コード例 #1
0
ファイル: KeyValueDBTransaction.cs プロジェクト: quyenbc/BTDB
 void ErasePartiallyChild(ref Sector sector, long firstKeyIndex, long lastKeyIndex)
 {
     var iter = new BTreeChildIterator(sector.Data);
     iter.MoveTo((int)firstKeyIndex);
     var eraseFromOfs = iter.EntryOffset;
     while (true)
     {
         if (iter.HasKeySectorPtr)
             DeleteContentSector(iter.KeySectorPtr, iter.KeyLen - iter.KeyLenInline, sector);
         if (iter.HasValueSectorPtr)
             DeleteContentSector(iter.ValueSectorPtr, iter.ValueLen - iter.ValueLenInline, sector);
         if (iter.Index == (int)lastKeyIndex) break;
         iter.MoveNext();
     }
     var eraseToOfs = iter.EntryOffset + iter.CurrentEntrySize;
     var originalLength = iter.TotalLength;
     var newCount = iter.Count - 1 - (int)(lastKeyIndex - firstKeyIndex);
     sector = _owner.ResizeSectorNoUpdatePosition(sector,
                                                  originalLength - eraseToOfs + eraseFromOfs - BTreeChildIterator.HeaderForEntry * (iter.Count - newCount),
                                                  sector.Parent,
                                                  null);
     BTreeChildIterator.SetCountToSectorData(sector.Data, newCount);
     var ofs = BTreeChildIterator.HeaderSize + BTreeChildIterator.HeaderForEntry * newCount;
     Array.Copy(iter.Data, iter.FirstOffset, sector.Data, ofs, eraseFromOfs - iter.FirstOffset);
     ofs += eraseFromOfs - iter.FirstOffset;
     Array.Copy(iter.Data, eraseToOfs, sector.Data, ofs, originalLength - eraseToOfs);
     BTreeChildIterator.RecalculateHeader(sector.Data, newCount);
 }
コード例 #2
0
ファイル: KeyValueDBTransaction.cs プロジェクト: quyenbc/BTDB
 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;
 }
コード例 #3
0
ファイル: KeyValueDBTransaction.cs プロジェクト: quyenbc/BTDB
 void SplitBTreeChild(byte[] keyBuf, int keyOfs, int keyLen, byte[] valueBuf, int valueOfs, int valueLen, Sector sector, BTreeChildIterator iter, int additionalLengthNeeded)
 {
     int middleoffset = (iter.TotalLength + iter.FirstOffset + additionalLengthNeeded) / 2;
     iter.MoveFirst();
     bool beforeNew = true;
     int splitIndex = 0;
     int currentPos = iter.FirstOffset;
     while (currentPos < middleoffset)
     {
         if (beforeNew && splitIndex == _currentKeyIndexInLeaf)
         {
             beforeNew = false;
             currentPos += additionalLengthNeeded - BTreeChildIterator.HeaderForEntry;
         }
         else
         {
             currentPos += iter.CurrentEntrySize;
             splitIndex++;
             iter.MoveNext();
         }
     }
     var rightSector = _owner.NewSector();
     rightSector.Type = SectorType.BTreeChild;
     int rightCount = iter.Count - splitIndex + (beforeNew ? 1 : 0);
     rightSector.SetLengthWithRound(BTreeChildIterator.HeaderSize + rightCount * BTreeChildIterator.HeaderForEntry + iter.TotalLength + additionalLengthNeeded - BTreeChildIterator.HeaderForEntry - currentPos);
     BTreeChildIterator.SetCountToSectorData(rightSector.Data, rightCount);
     rightSector.Parent = sector.Parent;
     int leftCount = splitIndex + (beforeNew ? 0 : 1);
     var leftSector = _owner.ResizeSectorWithUpdatePosition(sector, BTreeChildIterator.HeaderSize + leftCount * BTreeChildIterator.HeaderForEntry + currentPos - iter.FirstOffset, sector.Parent,
                                                               _currentKeySectorParents);
     _currentKeySector = leftSector;
     Sector newKeySector;
     BTreeChildIterator.SetCountToSectorData(leftSector.Data, leftCount);
     int newItemPos = iter.OffsetOfIndex(_currentKeyIndexInLeaf);
     int setActualDataPos;
     if (beforeNew)
     {
         Array.Copy(iter.Data, iter.FirstOffset, leftSector.Data, BTreeChildIterator.HeaderSize + BTreeChildIterator.HeaderForEntry * leftCount, currentPos - iter.FirstOffset);
         Array.Copy(iter.Data, currentPos, rightSector.Data, BTreeChildIterator.HeaderSize + BTreeChildIterator.HeaderForEntry * rightCount, newItemPos - currentPos);
         int rightPos = BTreeChildIterator.HeaderSize + BTreeChildIterator.HeaderForEntry * rightCount + newItemPos - currentPos;
         setActualDataPos = rightPos;
         SetBTreeChildKeyDataJustLengths(rightSector, keyLen, valueLen, rightPos);
         rightPos += additionalLengthNeeded - BTreeChildIterator.HeaderForEntry;
         Array.Copy(iter.Data, newItemPos, rightSector.Data, rightPos, iter.TotalLength - newItemPos);
         newKeySector = rightSector;
         _currentKeyIndexInLeaf -= splitIndex;
     }
     else
     {
         Array.Copy(iter.Data, iter.FirstOffset, leftSector.Data, BTreeChildIterator.HeaderSize + BTreeChildIterator.HeaderForEntry * leftCount, newItemPos - iter.FirstOffset);
         int leftPosInsert = BTreeChildIterator.HeaderSize + BTreeChildIterator.HeaderForEntry * leftCount + newItemPos - iter.FirstOffset;
         int leftPos = leftPosInsert;
         leftPos += additionalLengthNeeded - BTreeChildIterator.HeaderForEntry;
         Array.Copy(iter.Data, currentPos - additionalLengthNeeded + BTreeChildIterator.HeaderForEntry, rightSector.Data, BTreeChildIterator.HeaderSize + BTreeChildIterator.HeaderForEntry * rightCount,
                    iter.TotalLength + additionalLengthNeeded - BTreeChildIterator.HeaderForEntry - currentPos);
         Array.Copy(iter.Data, newItemPos, leftSector.Data, leftPos, currentPos - newItemPos - additionalLengthNeeded + BTreeChildIterator.HeaderForEntry);
         setActualDataPos = leftPosInsert;
         SetBTreeChildKeyDataJustLengths(leftSector, keyLen, valueLen, leftPosInsert);
         newKeySector = leftSector;
     }
     BTreeChildIterator.RecalculateHeader(leftSector.Data, leftCount);
     BTreeChildIterator.RecalculateHeader(rightSector.Data, rightCount);
     _owner.FixChildrenParentPointers(leftSector);
     _owner.PublishSector(rightSector, true);
     Interlocked.Increment(ref leftSector.ChildrenInCache);
     Interlocked.Increment(ref rightSector.ChildrenInCache);
     try
     {
         _owner.TruncateSectorCache(true, 0);
         SetBTreeChildKeyData(newKeySector, keyBuf, keyOfs, keyLen, valueBuf, valueOfs, valueLen, setActualDataPos);
         if (leftSector.Parent == null)
         {
             CreateBTreeParentFromTwoLeafs(leftSector, rightSector);
         }
         else
         {
             iter = new BTreeChildIterator(rightSector.Data);
             iter.MoveFirst();
             if (iter.HasKeySectorPtr) ForceKeyFlush(iter.KeySectorPtr, iter.KeyLen - iter.KeyLenInline, rightSector);
             int keyLenInSector = iter.KeyLenInline + (iter.HasKeySectorPtr ? KeyValueDB.PtrDownSize : 0);
             AddToBTreeParent(leftSector, rightSector, iter.Data, iter.KeyLen, iter.KeyOffset,
                              keyLenInSector);
         }
     }
     finally
     {
         Interlocked.Decrement(ref leftSector.ChildrenInCache);
         Interlocked.Decrement(ref rightSector.ChildrenInCache);
     }
     UnlockUselessAndFixKeySectorParents(newKeySector, leftSector, rightSector);
     _currentKeySector = newKeySector;
 }
コード例 #4
0
ファイル: KeyValueDB.cs プロジェクト: quyenbc/BTDB
 static int FindOfsInParent(Sector sector, Sector where)
 {
     switch (where.Type)
     {
         case SectorType.BTreeParent:
             {
                 var iter = new BTreeParentIterator(where.Data);
                 if ((iter.FirstChildSectorPos & MaskOfPosition) == sector.Position)
                     return BTreeParentIterator.FirstChildSectorPtrOffset;
                 if (iter.Count != 0)
                 {
                     iter.MoveFirst();
                     do
                     {
                         if ((iter.KeySectorPos & MaskOfPosition) == sector.Position)
                             return iter.KeySectorPtrOffset;
                         if ((iter.ChildSectorPos & MaskOfPosition) == sector.Position)
                             return iter.ChildSectorPtrOffset;
                     }
                     while (iter.MoveNext());
                 }
                 throw new BTDBException("Cannot FindOfsInParent");
             }
         case SectorType.BTreeChild:
             {
                 var iter = new BTreeChildIterator(where.Data);
                 iter.MoveFirst();
                 do
                 {
                     if ((iter.KeySectorPos & MaskOfPosition) == sector.Position)
                         return iter.KeySectorPtrOffset;
                     if ((iter.ValueSectorPos & MaskOfPosition) == sector.Position)
                         return iter.ValueSectorPtrOffset;
                 }
                 while (iter.MoveNext());
                 throw new BTDBException("Cannot FindOfsInParent");
             }
         case SectorType.AllocParent:
         case SectorType.DataParent:
             for (int i = 0; i < where.Length / PtrDownSize; i++)
             {
                 if ((PackUnpack.UnpackInt64LE(where.Data, i * PtrDownSize) & MaskOfPosition) == sector.Position)
                     return i * PtrDownSize;
             }
             throw new BTDBException("Cannot FindOfsInParent");
         case SectorType.DataChild:
             throw new BTDBException("DataChild cannot be parent");
         case SectorType.AllocChild:
             throw new BTDBException("AllocChild cannot be parent");
         default:
             throw new ArgumentOutOfRangeException();
     }
 }
コード例 #5
0
ファイル: KeyValueDB.cs プロジェクト: quyenbc/BTDB
 internal void FixChildrenParentPointers(Sector parent)
 {
     switch (parent.Type)
     {
         case SectorType.BTreeParent:
             {
                 var iter = new BTreeParentIterator(parent.Data);
                 for (int i = 0; i <= iter.Count; i++)
                 {
                     var childSectorPos = iter.GetChildSectorPos(i);
                     FixChildParentPointer(childSectorPos, parent);
                 }
                 break;
             }
         case SectorType.BTreeChild:
             {
                 var iter = new BTreeChildIterator(parent.Data);
                 iter.MoveFirst();
                 do
                 {
                     if (iter.HasKeySectorPtr)
                         FixChildParentPointer(iter.KeySectorPos, parent);
                     if (iter.HasValueSectorPtr)
                         FixChildParentPointer(iter.ValueSectorPos, parent);
                 } while (iter.MoveNext());
                 break;
             }
         case SectorType.DataChild:
         case SectorType.AllocChild:
             break;
         case SectorType.AllocParent:
         case SectorType.DataParent:
             {
                 var ptrCount = parent.Length / PtrDownSize;
                 for (int i = 0; i < ptrCount; i++)
                 {
                     var sectorPos = PackUnpack.UnpackInt64LE(parent.Data, i * PtrDownSize);
                     if (sectorPos == 0) break;
                     FixChildParentPointer(sectorPos, parent);
                 }
             }
             break;
         default:
             throw new InvalidOperationException();
     }
 }
コード例 #6
0
ファイル: KeyValueDB.cs プロジェクト: quyenbc/BTDB
 bool CheckBTree(SectorPtr sectorPtr)
 {
     byte[] sector = CheckSector(sectorPtr);
     if (sector == null) return false;
     if (BTreeChildIterator.IsChildFromSectorData(sector))
     {
         var iter = new BTreeChildIterator(sector);
         iter.MoveFirst();
         do
         {
             if (iter.HasKeySectorPtr)
             {
                 if (!CheckDataPages(iter.KeySectorPtr, iter.KeyLen - iter.KeyLenInline)) return false;
             }
             if (iter.HasValueSectorPtr)
             {
                 if (!CheckDataPages(iter.ValueSectorPtr, iter.ValueLen - iter.ValueLenInline)) return false;
             }
         } while (iter.MoveNext());
     }
     else
     {
         var iter = new BTreeParentIterator(sector);
         if (!CheckBTree(iter.FirstChildSectorPtr)) return false;
         iter.MoveFirst();
         do
         {
             if (iter.HasKeySectorPtr)
             {
                 if (!CheckDataPages(iter.KeySectorPtr, iter.KeyLen - iter.KeyLenInline)) return false;
             }
             if (!CheckBTree(iter.ChildSectorPtr)) return false;
         } while (iter.MoveNext());
     }
     return true;
 }