| 740 | } |
| 741 | |
| 742 | auto BTreeDatabase::BTreeImpl::storeLeaf(Leaf leaf) -> Pointer { |
| 743 | if (leaf->self != InvalidBlockIndex) { |
| 744 | List<BlockIndex> tailBlocks = parent->leafTailBlocks(leaf->self); |
| 745 | for (uint32_t i = 0; i < tailBlocks.size(); ++i) |
| 746 | parent->freeBlock(tailBlocks[i]); |
| 747 | |
| 748 | if (!parent->m_uncommitted.contains(leaf->self)) { |
| 749 | parent->freeBlock(leaf->self); |
| 750 | leaf->self = InvalidBlockIndex; |
| 751 | } |
| 752 | } |
| 753 | |
| 754 | if (leaf->self == InvalidBlockIndex) |
| 755 | leaf->self = parent->reserveBlock(); |
| 756 | |
| 757 | BlockIndex currentLeafBlock = leaf->self; |
| 758 | DataStreamBuffer leafBuffer; |
| 759 | leafBuffer.reset(parent->m_blockSize); |
| 760 | leafBuffer.writeData(LeafMagic, 2); |
| 761 | |
| 762 | DataStreamFunctions leafOutput({}, [&](char const* data, size_t len) -> size_t { |
| 763 | size_t pos = 0; |
| 764 | size_t left = len; |
| 765 | |
| 766 | while (true) { |
| 767 | size_t toWrite = left; |
| 768 | if (toWrite > parent->m_blockSize - leafBuffer.pos() - sizeof(BlockIndex)) |
| 769 | toWrite = parent->m_blockSize - leafBuffer.pos() - sizeof(BlockIndex); |
| 770 | |
| 771 | if (toWrite != 0) { |
| 772 | leafBuffer.writeData(data + pos, toWrite); |
| 773 | left -= toWrite; |
| 774 | pos += toWrite; |
| 775 | } |
| 776 | |
| 777 | if (left == 0) |
| 778 | break; |
| 779 | |
| 780 | if (leafBuffer.pos() == (parent->m_blockSize - sizeof(BlockIndex))) { |
| 781 | BlockIndex nextBlock = parent->reserveBlock(); |
| 782 | leafBuffer.write<BlockIndex>(nextBlock); |
| 783 | parent->updateBlock(currentLeafBlock, leafBuffer.data()); |
| 784 | currentLeafBlock = nextBlock; |
| 785 | leafBuffer.reset(parent->m_blockSize); |
| 786 | leafBuffer.writeData(LeafMagic, 2); |
| 787 | } |
| 788 | } |
| 789 | |
| 790 | return len; |
| 791 | }); |
| 792 | |
| 793 | leafOutput.write<uint32_t>(leaf->elements.size()); |
| 794 | |
| 795 | for (LeafNode::ElementList::iterator i = leaf->elements.begin(); i != leaf->elements.end(); ++i) { |
| 796 | starAssert(i->key.size() == parent->m_keySize); |
| 797 | leafOutput.writeBytes(i->key); |
| 798 | leafOutput.write(i->data); |
| 799 | } |
no test coverage detected