Exemplo n.º 1
0
 void EraseCompletely(ref Sector sector)
 {
     if (sector.Type == SectorType.BTreeChild)
     {
         var iter = new BTreeChildIterator(sector.Data);
         iter.MoveFirst();
         do
         {
             if (iter.HasKeySectorPtr)
                 DeleteContentSector(iter.KeySectorPtr, iter.KeyLen - iter.KeyLenInline, sector);
             if (iter.HasValueSectorPtr)
                 DeleteContentSector(iter.ValueSectorPtr, iter.ValueLen - iter.ValueLenInline, sector);
         } while (iter.MoveNext());
     }
     else
     {
         var iter = new BTreeParentIterator(sector.Data);
         for (int i = 0; i <= iter.Count; i++)
         {
             var childSectorPtr = iter.GetChildSectorPtr(i);
             var childSector = GetBTreeSector(childSectorPtr, sector);
             EraseCompletely(ref childSector);
         }
     }
     _owner.DeallocateSector(sector);
     sector = null;
 }
Exemplo n.º 2
0
 public bool FindPreviousKey()
 {
     if (_currentKeyIndexInLeaf < 0) throw new BTDBException("Current Key is invalid");
     if (_currentKeyIndex == _prefixKeyStart) return false;
     try
     {
         if (_currentKeyIndexInLeaf > 0)
         {
             _currentKeyIndexInLeaf--;
             _currentKeyIndex--;
             _owner.UpdateLastAccess(_currentKeySector);
             return true;
         }
         var sector = _currentKeySector;
         var parent = PopCurrentKeyParent();
         while (parent != null)
         {
             var iter = new BTreeParentIterator(parent.Data);
             var childByPos = iter.FindChildByPos(sector.Position);
             if (childByPos == 0)
             {
                 sector = parent;
                 parent = PopCurrentKeyParent();
                 continue;
             }
             var childSectorPtr = iter.GetChildSectorPtr(childByPos - 1);
             while (true)
             {
                 sector = LoadBTreeSector(childSectorPtr);
                 if (sector.Type == SectorType.BTreeChild)
                 {
                     _currentKeyIndexInLeaf = (int)(BTreeChildIterator.CountFromSectorData(sector.Data) - 1);
                     _currentKeyIndex--;
                     return true;
                 }
                 iter = new BTreeParentIterator(sector.Data);
                 childSectorPtr = iter.GetChildSectorPtr(iter.Count);
             }
         }
         throw new BTDBException("Internal error");
     }
     catch
     {
         InvalidateCurrentKey();
         throw;
     }
 }
Exemplo n.º 3
0
 public bool FindNextKey()
 {
     if (_currentKeyIndexInLeaf < 0) throw new BTDBException("Current Key is invalid");
     if (_prefixKeyCount != -1 && _currentKeyIndex + 1 >= _prefixKeyStart + _prefixKeyCount) return false;
     try
     {
         if (_currentKeyIndexInLeaf + 1 < BTreeChildIterator.CountFromSectorData(_currentKeySector.Data))
         {
             _owner.UpdateLastAccess(_currentKeySector);
             _currentKeyIndexInLeaf++;
             if (CheckPrefix())
             {
                 _currentKeyIndex++;
                 return true;
             }
             _prefixKeyCount = _currentKeyIndex - _prefixKeyStart + 1;
             _currentKeyIndexInLeaf--;
             return false;
         }
         var sector = _currentKeySector;
         var parent = PopCurrentKeyParent();
         if (parent == null)
         {
             _prefixKeyCount = _currentKeyIndex - _prefixKeyStart + 1;
             FindLastKey();
             return false;
         }
         while (true)
         {
             var iter = new BTreeParentIterator(parent.Data);
             var childByPos = iter.FindChildByPos(sector.Position);
             if (childByPos == iter.Count)
             {
                 sector = parent;
                 parent = PopCurrentKeyParent();
                 if (parent == null)
                 {
                     _prefixKeyCount = _currentKeyIndex - _prefixKeyStart + 1;
                     FindLastKey();
                     return false;
                 }
                 continue;
             }
             var childSectorPtr = iter.GetChildSectorPtr(childByPos + 1);
             while (true)
             {
                 sector = LoadBTreeSector(childSectorPtr);
                 if (sector.Type == SectorType.BTreeChild)
                 {
                     _currentKeyIndexInLeaf = 0;
                     _currentKeyIndex++;
                     if (CheckPrefix())
                     {
                         return true;
                     }
                     _prefixKeyCount = _currentKeyIndex - _prefixKeyStart;
                     FindPreviousKey();
                     return false;
                 }
                 iter = new BTreeParentIterator(sector.Data);
                 childSectorPtr = iter.GetChildSectorPtr(0);
             }
         }
     }
     catch
     {
         InvalidateCurrentKey();
         throw;
     }
 }
Exemplo n.º 4
0
 void SimplifyBTree(ref Sector sector, int mergeAroundIndex)
 {
     var iter = new BTreeParentIterator(sector.Data);
     if (iter.Count == 0 || mergeAroundIndex > iter.Count)
         return;
     var lenCurrent = ApproximateLengthOfBTreeChild(iter.GetChildSectorPtr(mergeAroundIndex));
     var lenPrevious = -1;
     if (mergeAroundIndex > 0)
         lenPrevious = ApproximateLengthOfBTreeChild(iter.GetChildSectorPtr(mergeAroundIndex - 1));
     var lenNext = -1;
     if (mergeAroundIndex < iter.Count)
         lenNext = ApproximateLengthOfBTreeChild(iter.GetChildSectorPtr(mergeAroundIndex + 1));
     ShouldMergeResult result = KeyValueDB.ShouldMergeBTreeParent(lenPrevious, lenCurrent, lenNext);
     if (result == ShouldMergeResult.NoMerge)
         return;
     if (result == ShouldMergeResult.MergeWithPrevious)
         mergeAroundIndex--;
     long mergedPairs;
     var leftSectorPtr = iter.GetChildSectorPtrWithKeyCount(mergeAroundIndex, out mergedPairs);
     Sector mergedSector;
     var leftSector = GetBTreeSector(leftSectorPtr, sector);
     long tempPairs;
     var rightSectorPtr = iter.GetChildSectorPtrWithKeyCount(mergeAroundIndex + 1, out tempPairs);
     mergedPairs += tempPairs;
     var rightSector = GetBTreeSector(rightSectorPtr, sector);
     Debug.Assert(leftSector.Type == rightSector.Type);
     iter.MoveTo(mergeAroundIndex);
     if (leftSector.Type == SectorType.BTreeChild)
     {
         var leftIter = new BTreeChildIterator(leftSector.Data);
         var rightIter = new BTreeChildIterator(rightSector.Data);
         if (!KeyValueDB.ShouldMerge2BTreeChild(leftIter.Count, leftIter.TotalLength, rightIter.Count,
                                                   rightIter.TotalLength))
             return;
         mergedSector = _owner.NewSector();
         mergedSector.Type = SectorType.BTreeChild;
         mergedSector.Parent = sector;
         mergedSector.SetLengthWithRound(leftIter.TotalLength + rightIter.TotalLength - BTreeChildIterator.HeaderSize);
         var mergedCount = leftIter.Count + rightIter.Count;
         BTreeChildIterator.SetCountToSectorData(mergedSector.Data, mergedCount);
         var ofs = BTreeChildIterator.HeaderSize + BTreeChildIterator.HeaderForEntry * mergedCount;
         Array.Copy(leftIter.Data, leftIter.FirstOffset, mergedSector.Data, ofs, leftIter.TotalLength - leftIter.FirstOffset);
         ofs += leftIter.TotalLength - leftIter.FirstOffset;
         Array.Copy(rightIter.Data, rightIter.FirstOffset, mergedSector.Data, ofs, rightIter.TotalLength - rightIter.FirstOffset);
         BTreeChildIterator.RecalculateHeader(mergedSector.Data, mergedCount);
     }
     else
     {
         var keyStorageLen = 4 + iter.KeyLenInline + (iter.HasKeySectorPtr ? KeyValueDB.PtrDownSize : 0);
         var leftIter = new BTreeParentIterator(leftSector.Data);
         var rightIter = new BTreeParentIterator(rightSector.Data);
         if (!KeyValueDB.ShouldMerge2BTreeParent(leftIter.Count, leftIter.TotalLength, rightIter.Count,
                                                    rightIter.TotalLength, keyStorageLen))
             return;
         mergedSector = _owner.NewSector();
         mergedSector.Type = SectorType.BTreeParent;
         mergedSector.Parent = sector;
         mergedSector.SetLengthWithRound(leftIter.TotalLength + rightIter.TotalLength + keyStorageLen);
         var mergedCount = leftIter.Count + rightIter.Count + 1;
         BTreeParentIterator.SetCountToSectorData(mergedSector.Data, mergedCount);
         Array.Copy(leftIter.Data, BTreeParentIterator.FirstChildSectorPtrOffset, mergedSector.Data,
                    BTreeParentIterator.FirstChildSectorPtrOffset, KeyValueDB.PtrDownSize + 8);
         var ofs = BTreeParentIterator.HeaderSize + BTreeParentIterator.HeaderForEntry * mergedCount;
         Array.Copy(leftIter.Data, leftIter.FirstOffset, mergedSector.Data, ofs, leftIter.TotalLength - leftIter.FirstOffset);
         ofs += leftIter.TotalLength - leftIter.FirstOffset;
         PackUnpack.PackInt32LE(mergedSector.Data, ofs, iter.KeyLen);
         ofs += 4;
         Array.Copy(rightIter.Data, BTreeParentIterator.FirstChildSectorPtrOffset, mergedSector.Data, ofs, KeyValueDB.PtrDownSize + 8);
         ofs += KeyValueDB.PtrDownSize + 8;
         Array.Copy(iter.Data, iter.KeyOffset, mergedSector.Data, ofs, keyStorageLen - 4);
         ofs += keyStorageLen - 4;
         Array.Copy(rightIter.Data, rightIter.FirstOffset, mergedSector.Data, ofs, rightIter.TotalLength - rightIter.FirstOffset);
         BTreeParentIterator.RecalculateHeader(mergedSector.Data, mergedCount);
     }
     _owner.PublishSector(mergedSector, true);
     _owner.DeallocateSector(leftSector);
     _owner.DeallocateSector(rightSector);
     InternalBTreeParentEraseRange(ref sector, ref iter, mergeAroundIndex, mergeAroundIndex + 1);
     new BTreeParentIterator(sector.Data).SetChildSectorPtrWithKeyCount(mergeAroundIndex,
                                                                        mergedSector.ToSectorPtr(),
                                                                        mergedPairs);
     _owner.TruncateSectorCache(true, 0);
 }
Exemplo n.º 5
0
 private FindKeyResult FindKey(byte[] keyBuf, int keyOfs, int keyLen, FindKeyStrategy strategy, byte[] valueBuf, int valueOfs, int valueLen)
 {
     if (keyLen < 0) throw new ArgumentOutOfRangeException("keyLen");
     if (strategy == FindKeyStrategy.Create) UpgradeToWriteTransaction();
     InvalidateCurrentKey();
     var rootBTree = GetRootBTreeSectorPtr();
     if (rootBTree.Ptr == 0)
     {
         return FindKeyInEmptyBTree(keyBuf, keyOfs, keyLen, strategy, valueBuf, valueOfs, valueLen);
     }
     Sector sector;
     try
     {
         long keyIndex = 0;
         while (true)
         {
             sector = LoadBTreeSector(rootBTree);
             if (sector.Type == SectorType.BTreeChild) break;
             var iterParent = new BTreeParentIterator(sector.Data);
             int bindexParent = iterParent.BinarySearch(_prefix, keyBuf, keyOfs, keyLen, sector, SectorDataCompare);
             rootBTree = iterParent.GetChildSectorPtr((bindexParent + 1) / 2, ref keyIndex);
         }
         var iter = new BTreeChildIterator(sector.Data);
         int bindex = iter.BinarySearch(_prefix, keyBuf, keyOfs, keyLen, sector, SectorDataCompare);
         _currentKeyIndexInLeaf = bindex / 2;
         _currentKeyIndex = keyIndex + _currentKeyIndexInLeaf;
         if ((bindex & 1) != 0)
         {
             return FindKeyResult.FoundExact;
         }
         if (strategy != FindKeyStrategy.Create)
         {
             return FindKeyNoncreateStrategy(strategy, iter);
         }
         int additionalLengthNeeded = BTreeChildIterator.HeaderForEntry +
             (valueLen >= 0 ? BTreeChildIterator.CalcEntrySize(_prefix.Length + keyLen, valueLen) :
             BTreeChildIterator.CalcEntrySize(_prefix.Length + keyLen));
         if (KeyValueDB.ShouldSplitBTreeChild(iter.TotalLength, additionalLengthNeeded, iter.Count))
         {
             SplitBTreeChild(keyBuf, keyOfs, keyLen, valueBuf, valueOfs, valueLen, sector, iter, additionalLengthNeeded);
         }
         else
         {
             var origsector = sector;
             sector = _owner.ResizeSectorWithUpdatePosition(sector, iter.TotalLength + additionalLengthNeeded,
                                                            sector.Parent, _currentKeySectorParents);
             if (sector != origsector)
             {
                 Array.Copy(origsector.Data, sector.Data, origsector.Data.Length);
                 _owner.FixChildrenParentPointers(sector);
             }
             _currentKeySector = sector;
             int insertOfs = iter.AddEntry(additionalLengthNeeded, sector.Data, _currentKeyIndexInLeaf);
             IncrementChildCountInBTreeParents(sector);
             SetBTreeChildKeyData(sector, keyBuf, keyOfs, keyLen, valueBuf, valueOfs, valueLen, insertOfs);
         }
         _owner.NewState.KeyValuePairCount++;
         if (_prefixKeyCount != -1) _prefixKeyCount++;
         return FindKeyResult.Created;
     }
     catch
     {
         InvalidateCurrentKey();
         throw;
     }
 }