| 1075 | } |
| 1076 | |
| 1077 | void BTreeDatabase::doCommit() { |
| 1078 | if (m_availableBlocks.empty() && m_uncommitted.empty()) |
| 1079 | return; |
| 1080 | |
| 1081 | if (!m_availableBlocks.empty()) { |
| 1082 | // First, read the existing head FreeIndexBlock, if it exists |
| 1083 | FreeIndexBlock indexBlock = FreeIndexBlock{InvalidBlockIndex, {}}; |
| 1084 | |
| 1085 | auto newBlock = [&]() -> BlockIndex { |
| 1086 | if (!m_availableBlocks.empty()) |
| 1087 | return m_availableBlocks.takeFirst(); |
| 1088 | else |
| 1089 | return makeEndBlock(); |
| 1090 | }; |
| 1091 | |
| 1092 | if (m_headFreeIndexBlock != InvalidBlockIndex) |
| 1093 | indexBlock = readFreeIndexBlock(m_headFreeIndexBlock); |
| 1094 | else |
| 1095 | m_headFreeIndexBlock = newBlock(); |
| 1096 | |
| 1097 | // Then, we need to write all the available blocks to the FreeIndexBlock chain. |
| 1098 | while (true) { |
| 1099 | // If we have room on our current FreeIndexBlock, just add a block to it. |
| 1100 | if (!m_availableBlocks.empty() && indexBlock.freeBlocks.size() < maxFreeIndexLength()) { |
| 1101 | BlockIndex toAdd = m_availableBlocks.takeFirst(); |
| 1102 | indexBlock.freeBlocks.append(toAdd); |
| 1103 | } else { |
| 1104 | // Update the current head free index block. |
| 1105 | writeFreeIndexBlock(m_headFreeIndexBlock, indexBlock); |
| 1106 | |
| 1107 | // If we're out of blocks to free, then we're done |
| 1108 | if (m_availableBlocks.empty()) |
| 1109 | break; |
| 1110 | |
| 1111 | // If our head free index block is full, then |
| 1112 | // need to write a new head free index block. |
| 1113 | if (indexBlock.freeBlocks.size() >= maxFreeIndexLength()) { |
| 1114 | indexBlock.nextFreeBlock = m_headFreeIndexBlock; |
| 1115 | indexBlock.freeBlocks.clear(); |
| 1116 | |
| 1117 | m_headFreeIndexBlock = newBlock(); |
| 1118 | writeFreeIndexBlock(m_headFreeIndexBlock, indexBlock); |
| 1119 | } |
| 1120 | } |
| 1121 | } |
| 1122 | } |
| 1123 | |
| 1124 | |
| 1125 | commitWrites(); |
| 1126 | writeRoot(); |
| 1127 | m_uncommitted.clear(); |
| 1128 | } |
| 1129 | |
| 1130 | void BTreeDatabase::commitWrites() { |
| 1131 | for (auto& write : m_uncommittedWrites) |