| 518 | } |
| 519 | |
| 520 | auto BTreeDatabase::BTreeImpl::loadIndex(Pointer pointer) -> Index { |
| 521 | SpinLocker lock(parent->m_indexCacheSpinLock); |
| 522 | if (auto index = parent->m_indexCache.ptr(pointer)) |
| 523 | return *index; |
| 524 | lock.unlock(); |
| 525 | |
| 526 | auto index = make_shared<IndexNode>(); |
| 527 | |
| 528 | DataStreamBuffer buffer(parent->readBlock(pointer)); |
| 529 | |
| 530 | if (buffer.readBytes(2) != ByteArray(IndexMagic, 2)) |
| 531 | throw DBException("Error, incorrect index block signature."); |
| 532 | |
| 533 | index->self = pointer; |
| 534 | |
| 535 | index->level = buffer.read<uint8_t>(); |
| 536 | uint32_t s = buffer.read<uint32_t>(); |
| 537 | index->beginPointer = buffer.read<BlockIndex>(); |
| 538 | index->pointers.resize(s); |
| 539 | for (uint32_t i = 0; i < s; ++i) { |
| 540 | auto& e = index->pointers[i]; |
| 541 | e.key = buffer.readBytes(parent->m_keySize); |
| 542 | e.pointer = buffer.read<BlockIndex>(); |
| 543 | } |
| 544 | |
| 545 | lock.lock(); |
| 546 | parent->m_indexCache.set(pointer, index); |
| 547 | return index; |
| 548 | } |
| 549 | |
| 550 | bool BTreeDatabase::BTreeImpl::indexNeedsShift(Index const& index) { |
| 551 | return index->pointerCount() < (parent->maxIndexPointers() + 1) / 2; |