Exemplo n.º 1
0
 void AddToBTreeParent(Sector leftSector, Sector rightSector, byte[] middleKeyData, int middleKeyLen, int middleKeyOfs, int middleKeyLenInSector)
 {
     var parentSector = leftSector.Parent;
     var iter = new BTreeParentIterator(parentSector.Data);
     int additionalLengthNeeded = BTreeParentIterator.HeaderForEntry + BTreeParentIterator.CalcEntrySize(middleKeyLen);
     int leftIndexInParent = iter.FindChildByPos(leftSector.Position);
     bool splitting = true;
     if (!KeyValueDB.ShouldSplitBTreeParent(iter.TotalLength, additionalLengthNeeded, iter.Count + 1))
     {
         parentSector = _owner.ResizeSectorWithUpdatePositionNoWriteTruncate(
             parentSector,
             iter.TotalLength + additionalLengthNeeded,
             parentSector.Parent,
             _currentKeySectorParents);
         splitting = false;
     }
     var mergedData = new byte[iter.TotalLength + additionalLengthNeeded];
     BTreeParentIterator.SetCountToSectorData(mergedData, iter.Count + 1);
     int ofs;
     int splitOfs = iter.OffsetOfIndex(leftIndexInParent);
     if (leftIndexInParent == 0)
     {
         SectorPtr.Pack(mergedData, BTreeParentIterator.FirstChildSectorPtrOffset, leftSector.ToSectorPtr());
         PackUnpack.PackUInt64LE(mergedData, BTreeParentIterator.FirstChildSectorPtrOffset + KeyValueDB.PtrDownSize, CalcKeysInSector(leftSector));
         ofs = BTreeParentIterator.HeaderSize + BTreeParentIterator.HeaderForEntry * (iter.Count + 1);
     }
     else
     {
         Array.Copy(iter.Data, BTreeParentIterator.FirstChildSectorPtrOffset, mergedData, BTreeParentIterator.FirstChildSectorPtrOffset, KeyValueDB.PtrDownSize + 8);
         ofs = BTreeParentIterator.HeaderSize + BTreeParentIterator.HeaderForEntry * (iter.Count + 1);
         int splitOfsPrev = iter.OffsetOfIndex(leftIndexInParent - 1);
         Array.Copy(iter.Data, iter.FirstOffset, mergedData, ofs, splitOfsPrev - iter.FirstOffset);
         ofs += splitOfsPrev - iter.FirstOffset;
         Array.Copy(iter.Data, splitOfsPrev, mergedData, ofs, 4 + KeyValueDB.PtrDownSize);
         ofs += 4 + KeyValueDB.PtrDownSize;
         PackUnpack.PackUInt64LE(mergedData, ofs, CalcKeysInSector(leftSector));
         ofs += 8;
         splitOfsPrev += 4 + KeyValueDB.PtrDownSize + 8;
         Array.Copy(iter.Data, splitOfsPrev, mergedData, ofs, splitOfs - splitOfsPrev);
         ofs += splitOfs - splitOfsPrev;
     }
     PackUnpack.PackInt32LE(mergedData, ofs, middleKeyLen);
     ofs += 4;
     SectorPtr.Pack(mergedData, ofs, rightSector.ToSectorPtr());
     ofs += KeyValueDB.PtrDownSize;
     PackUnpack.PackUInt64LE(mergedData, ofs, CalcKeysInSector(rightSector));
     ofs += 8;
     Array.Copy(middleKeyData, middleKeyOfs, mergedData, ofs, middleKeyLenInSector);
     ofs += middleKeyLenInSector;
     Array.Copy(iter.Data, splitOfs, mergedData, ofs, iter.TotalLength - splitOfs);
     BTreeParentIterator.RecalculateHeader(mergedData, iter.Count + 1);
     if (!splitting)
     {
         Array.Copy(mergedData, parentSector.Data, mergedData.Length);
         leftSector.Parent = parentSector;
         rightSector.Parent = parentSector;
         IncrementChildCountInBTreeParents(parentSector);
         _owner.FixChildrenParentPointers(parentSector);
     }
     else
     {
         iter = new BTreeParentIterator(mergedData);
         int middleoffset = mergedData.Length / 2;
         iter.MoveFirst();
         int splitIndex = 0;
         int currentPos = iter.FirstOffset;
         while (currentPos < middleoffset)
         {
             currentPos += iter.CurrentEntrySize;
             splitIndex++;
             iter.MoveNext();
         }
         Sector leftParentSector = null;
         Sector rightParentSector = null;
         try
         {
             rightParentSector = _owner.NewSector();
             rightParentSector.Type = SectorType.BTreeParent;
             var rightCount = iter.Count - splitIndex - 1;
             var rightFirstOffset = BTreeParentIterator.HeaderSize + rightCount * BTreeParentIterator.HeaderForEntry;
             rightParentSector.SetLengthWithRound(rightFirstOffset + mergedData.Length - iter.NextEntryOffset);
             BTreeParentIterator.SetCountToSectorData(rightParentSector.Data, rightCount);
             rightParentSector.Parent = parentSector.Parent;
             var leftFirstOffset = BTreeParentIterator.HeaderSize + splitIndex * BTreeParentIterator.HeaderForEntry;
             leftParentSector = _owner.ResizeSectorWithUpdatePosition(parentSector,
                                                                      leftFirstOffset + currentPos -
                                                                      iter.FirstOffset, parentSector.Parent,
                                                                      _currentKeySectorParents);
             BTreeParentIterator.SetCountToSectorData(leftParentSector.Data, splitIndex);
             leftSector.Parent = leftParentSector;
             rightSector.Parent = leftParentSector;
             Array.Copy(mergedData, BTreeParentIterator.FirstChildSectorPtrOffset, leftParentSector.Data,
                        BTreeParentIterator.FirstChildSectorPtrOffset,
                        KeyValueDB.PtrDownSize + 8 + BTreeParentIterator.HeaderForEntry * splitIndex);
             Array.Copy(mergedData, iter.FirstOffset, leftParentSector.Data, leftFirstOffset,
                        currentPos - iter.FirstOffset);
             Array.Copy(mergedData, iter.ChildSectorPtrOffset, rightParentSector.Data, BTreeParentIterator.FirstChildSectorPtrOffset, KeyValueDB.PtrDownSize + 8);
             Array.Copy(mergedData, iter.NextEntryOffset, rightParentSector.Data, rightFirstOffset, iter.TotalLength - iter.NextEntryOffset);
             BTreeParentIterator.RecalculateHeader(rightParentSector.Data, rightCount);
             _owner.FixChildrenParentPointers(leftParentSector);
             _owner.PublishSector(rightParentSector, true);
             Interlocked.Increment(ref leftParentSector.ChildrenInCache);
             Interlocked.Increment(ref rightParentSector.ChildrenInCache);
             try
             {
                 _owner.TruncateSectorCache(true, 0);
                 int keyLenInSector = iter.KeyLenInline + (iter.HasKeySectorPtr ? KeyValueDB.PtrDownSize : 0);
                 if (leftParentSector.Parent == null)
                 {
                     CreateBTreeParentFromTwoChildren(leftParentSector, rightParentSector, iter.Data, iter.KeyLen, iter.KeyOffset, keyLenInSector);
                 }
                 else
                 {
                     AddToBTreeParent(leftParentSector, rightParentSector, iter.Data, iter.KeyLen, iter.KeyOffset, keyLenInSector);
                 }
             }
             finally
             {
                 Interlocked.Decrement(ref leftParentSector.ChildrenInCache);
                 Interlocked.Decrement(ref rightParentSector.ChildrenInCache);
             }
         }
         finally
         {
             if (leftSector.Parent == rightParentSector)
             {
                 for (int i = 0; i < _currentKeySectorParents.Count; i++)
                 {
                     if (_currentKeySectorParents[i] == leftParentSector)
                     {
                         _currentKeySectorParents[i] = rightParentSector;
                         break;
                     }
                 }
             }
         }
     }
 }
Exemplo n.º 2
0
 void InternalBTreeParentEraseRange(ref Sector sector, ref BTreeParentIterator iter, int firstIndexToErase, int lastIndexToErase)
 {
     var originalLength = iter.TotalLength;
     Debug.Assert(iter.Count >= lastIndexToErase - firstIndexToErase);
     var eraseFromOfs = iter.OffsetOfIndex(firstIndexToErase);
     var eraseToOfs = lastIndexToErase - 1 == iter.Count
                          ? originalLength + KeyValueDB.PtrDownSize + 8
                          : iter.OffsetOfIndex(lastIndexToErase);
     sector = _owner.ResizeSectorNoUpdatePosition(sector,
                                                  originalLength - eraseToOfs + eraseFromOfs,
                                                  sector.Parent,
                                                  null);
     var newCount = iter.Count - (lastIndexToErase - firstIndexToErase);
     BTreeParentIterator.SetCountToSectorData(sector.Data, newCount);
     var ofs = BTreeParentIterator.HeaderSize + newCount * BTreeParentIterator.HeaderForEntry;
     if (firstIndexToErase == 0)
     {
         iter.MoveTo(lastIndexToErase - 1);
         Array.Copy(iter.Data, iter.ChildSectorPtrOffset, sector.Data, BTreeParentIterator.FirstChildSectorPtrOffset, KeyValueDB.PtrDownSize + 8);
         Array.Copy(iter.Data, eraseToOfs, sector.Data, ofs, originalLength - eraseToOfs);
     }
     else
     {
         Array.Copy(iter.Data, BTreeParentIterator.FirstChildSectorPtrOffset, sector.Data, BTreeParentIterator.FirstChildSectorPtrOffset, KeyValueDB.PtrDownSize + 8);
         iter.MoveTo(firstIndexToErase - 1);
         if (lastIndexToErase - 1 == iter.Count)
         {
             Array.Copy(iter.Data, iter.FirstOffset, sector.Data, ofs, iter.EntryOffset - iter.FirstOffset);
         }
         else
         {
             var ofs2 = ofs + iter.ChildSectorPtrOffset - iter.FirstOffset;
             iter.MoveTo(lastIndexToErase - 1);
             Array.Copy(iter.Data, iter.FirstOffset, sector.Data, ofs, eraseFromOfs - iter.FirstOffset);
             ofs += eraseFromOfs - iter.FirstOffset;
             Array.Copy(iter.Data, iter.ChildSectorPtrOffset, sector.Data, ofs2, KeyValueDB.PtrDownSize + 8);
             Array.Copy(iter.Data, eraseToOfs, sector.Data, ofs, originalLength - eraseToOfs);
         }
     }
     BTreeParentIterator.RecalculateHeader(sector.Data, newCount);
 }