コード例 #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
 public void SetValue(byte[] buf, int bufOfs, int len)
 {
     if (len < 0) throw new ArgumentOutOfRangeException("len");
     if (_currentKeyIndexInLeaf < 0) throw new BTDBException("Current Key is invalid");
     var iter = new BTreeChildIterator(_currentKeySector.Data);
     iter.MoveTo(_currentKeyIndexInLeaf);
     long oldSize = iter.ValueLen;
     if (oldSize == len)
     {
         WriteValue(0, len, buf, bufOfs);
         return;
     }
     UpgradeToWriteTransaction();
     int oldInlineSize = BTreeChildIterator.CalcValueLenInline(oldSize);
     int newInlineSize = BTreeChildIterator.CalcValueLenInline(len);
     long oldDeepSize = oldSize - oldInlineSize;
     int newDeepSize = len - newInlineSize;
     if (oldDeepSize > 0 && newDeepSize == 0)
         DeleteContentSector(iter.ValueSectorPtr, oldDeepSize, _currentKeySector);
     _currentKeySector = _owner.ResizeSectorWithUpdatePosition(_currentKeySector, iter.TotalLength - iter.CurrentEntrySize + BTreeChildIterator.CalcEntrySize(iter.KeyLen, len), _currentKeySector.Parent, _currentKeySectorParents);
     iter.ResizeValue(_currentKeySector.Data, len);
     _owner.FixChildrenParentPointers(_currentKeySector);
     Array.Copy(buf, bufOfs + len - newInlineSize, _currentKeySector.Data, iter.ValueOffset, newInlineSize);
     if (oldDeepSize == 0)
     {
         if (newDeepSize != 0)
         {
             CreateContentSector(buf, bufOfs, newDeepSize, _currentKeySector, iter.ValueSectorPtrOffset);
         }
     }
     else if (newDeepSize != 0)
     {
         ResizeContentSector(iter.ValueSectorPtr, oldDeepSize, _currentKeySector, iter.ValueSectorPtrOffset, newDeepSize, buf, bufOfs);
     }
 }
コード例 #3
0
ファイル: KeyValueDBTransaction.cs プロジェクト: quyenbc/BTDB
 public void SetValueSize(long newSize)
 {
     if (newSize < 0) throw new ArgumentOutOfRangeException("newSize");
     if (_currentKeyIndexInLeaf < 0) throw new BTDBException("Current Key is invalid");
     var iter = new BTreeChildIterator(_currentKeySector.Data);
     iter.MoveTo(_currentKeyIndexInLeaf);
     long oldSize = iter.ValueLen;
     if (oldSize == newSize) return;
     UpgradeToWriteTransaction();
     int oldInlineSize = BTreeChildIterator.CalcValueLenInline(oldSize);
     int newInlineSize = BTreeChildIterator.CalcValueLenInline(newSize);
     var newEndContent = new byte[newInlineSize];
     byte[] oldEndContent = null;
     long newEndContentOfs = newSize - newEndContent.Length;
     if (oldSize < newSize)
     {
         oldEndContent = new byte[oldInlineSize];
         ReadValue(oldSize - oldInlineSize, oldInlineSize, oldEndContent, 0);
     }
     else
     {
         ReadValue(newEndContentOfs, (int)Math.Min(newEndContent.Length, oldSize - newEndContentOfs), newEndContent, 0);
     }
     long oldDeepSize = oldSize - oldInlineSize;
     long newDeepSize = newSize - newInlineSize;
     if (oldDeepSize > 0 && newDeepSize == 0)
         DeleteContentSector(iter.ValueSectorPtr, oldDeepSize, _currentKeySector);
     _currentKeySector = _owner.ResizeSectorWithUpdatePosition(_currentKeySector, iter.TotalLength - iter.CurrentEntrySize + BTreeChildIterator.CalcEntrySize(iter.KeyLen, newSize), _currentKeySector.Parent, _currentKeySectorParents);
     iter.ResizeValue(_currentKeySector.Data, newSize);
     _owner.FixChildrenParentPointers(_currentKeySector);
     if (oldDeepSize != newDeepSize)
     {
         if (oldDeepSize == 0)
         {
             CreateContentSector(newDeepSize, _currentKeySector, iter.ValueSectorPtrOffset);
         }
         else if (newDeepSize != 0)
         {
             ResizeContentSector(iter.ValueSectorPtr, oldDeepSize, _currentKeySector, iter.ValueSectorPtrOffset, newDeepSize, null, 0);
         }
     }
     if (newEndContent.Length > 0) InternalWriteValue(newEndContentOfs, newEndContent.Length, newEndContent, 0);
     if (oldEndContent != null && oldEndContent.Length > 0) InternalWriteValue(oldSize - oldInlineSize, oldInlineSize, oldEndContent, 0);
 }
コード例 #4
0
ファイル: KeyValueDBTransaction.cs プロジェクト: quyenbc/BTDB
 public void ReadKey(int ofs, int len, byte[] buf, int bufOfs)
 {
     ThrowIfCurrentKeyIsInvalid();
     ofs += _prefix.Length;
     var iter = new BTreeChildIterator(_currentKeySector.Data);
     iter.MoveTo(_currentKeyIndexInLeaf);
     var keyLen = iter.KeyLen;
     if (ofs < 0 || ofs > keyLen) throw new ArgumentOutOfRangeException("ofs");
     if (len < 0 || ofs + len > keyLen) throw new ArgumentOutOfRangeException("len");
     if (len == 0) return;
     var keyLenInline = iter.KeyLenInline;
     if (ofs < keyLenInline)
     {
         var copyLen = Math.Min(len, keyLenInline - ofs);
         Array.Copy(_currentKeySector.Data, iter.KeyOffset + ofs, buf, bufOfs, copyLen);
         len -= copyLen;
         bufOfs += copyLen;
         ofs += copyLen;
     }
     if (len > 0)
     {
         ofs -= keyLenInline;
         int dataLen = keyLen - keyLenInline;
         RecursiveReadOverflown(ofs, iter.KeySectorPtr, _currentKeySector, dataLen, buf, ref bufOfs, ref len);
     }
 }
コード例 #5
0
ファイル: KeyValueDBTransaction.cs プロジェクト: quyenbc/BTDB
 public void ReadValue(long ofs, int len, byte[] buf, int bufOfs)
 {
     ThrowIfCurrentKeyIsInvalid();
     var iter = new BTreeChildIterator(_currentKeySector.Data);
     iter.MoveTo(_currentKeyIndexInLeaf);
     var valueLen = iter.ValueLen;
     if (ofs < 0 || ofs > valueLen) throw new ArgumentOutOfRangeException("ofs");
     if (len < 0 || ofs + len > valueLen) throw new ArgumentOutOfRangeException("len");
     if (len == 0) return;
     var valueLenInline = iter.ValueLenInline;
     long dataLen = valueLen - valueLenInline;
     if (ofs < dataLen)
     {
         RecursiveReadOverflown(ofs, iter.ValueSectorPtr, _currentKeySector, dataLen, buf, ref bufOfs, ref len);
         ofs = dataLen;
     }
     if (len > 0)
     {
         Debug.Assert(ofs >= dataLen);
         Array.Copy(_currentKeySector.Data, iter.ValueOffset + (int)(ofs - dataLen), buf, bufOfs, len);
     }
 }
コード例 #6
0
ファイル: KeyValueDBTransaction.cs プロジェクト: quyenbc/BTDB
 public void PeekValue(long ofs, out int len, out byte[] buf, out int bufOfs)
 {
     ThrowIfCurrentKeyIsInvalid();
     var iter = new BTreeChildIterator(_currentKeySector.Data);
     iter.MoveTo(_currentKeyIndexInLeaf);
     if (ofs < 0 || ofs >= iter.ValueLen)
     {
         len = 0;
         buf = null;
         bufOfs = 0;
         return;
     }
     if (ofs >= iter.ValueLen - iter.ValueLenInline)
     {
         len = (int)(iter.ValueLen - ofs);
         buf = _currentKeySector.Data;
         bufOfs = iter.ValueOffset + iter.ValueLenInline - len;
         return;
     }
     SectorPtr dataSectorPtr = iter.ValueSectorPtr;
     long dataLen = iter.ValueLen - iter.ValueLenInline;
     Sector parentOfSector = _currentKeySector;
     Debug.Assert(ofs < dataLen);
     while (true)
     {
         Sector dataSector = GetOrReadDataSector(dataSectorPtr, dataLen, parentOfSector);
         if (dataSector.Type == SectorType.DataChild)
         {
             buf = dataSector.Data;
             bufOfs = (int)ofs;
             len = (int)(dataSector.Length - ofs);
             return;
         }
         parentOfSector = dataSector;
         int downPtrCount;
         long bytesInDownLevel = KeyValueDB.GetBytesInDownLevel(dataLen, out downPtrCount);
         var i = (int)(ofs / bytesInDownLevel);
         ofs = ofs % bytesInDownLevel;
         dataSectorPtr = SectorPtr.Unpack(dataSector.Data, i * KeyValueDB.PtrDownSize);
         if (i < downPtrCount - 1)
         {
             dataLen = bytesInDownLevel;
         }
         else
         {
             dataLen = dataLen % bytesInDownLevel;
             if (dataLen == 0) dataLen = bytesInDownLevel;
         }
     }
 }
コード例 #7
0
ファイル: KeyValueDBTransaction.cs プロジェクト: quyenbc/BTDB
 public void PeekKey(int ofs, out int len, out byte[] buf, out int bufOfs)
 {
     ThrowIfCurrentKeyIsInvalid();
     ofs += _prefix.Length;
     var iter = new BTreeChildIterator(_currentKeySector.Data);
     iter.MoveTo(_currentKeyIndexInLeaf);
     if (ofs >= iter.KeyLen)
     {
         len = 0;
         buf = null;
         bufOfs = 0;
         return;
     }
     if (ofs < iter.KeyLenInline)
     {
         len = iter.KeyLenInline - ofs;
         buf = _currentKeySector.Data;
         bufOfs = iter.KeyOffset + ofs;
         return;
     }
     ofs -= iter.KeyLenInline;
     SectorPtr dataSectorPtr = iter.KeySectorPtr;
     int dataLen = iter.KeyLen - iter.KeyLenInline;
     Sector parentOfSector = _currentKeySector;
     while (true)
     {
         Sector dataSector = GetOrReadDataSector(dataSectorPtr, dataLen, parentOfSector);
         if (dataSector.Type == SectorType.DataChild)
         {
             buf = dataSector.Data;
             bufOfs = ofs;
             len = dataSector.Length - ofs;
             return;
         }
         parentOfSector = dataSector;
         int downPtrCount;
         var bytesInDownLevel = (int)KeyValueDB.GetBytesInDownLevel(dataLen, out downPtrCount);
         int i = ofs / bytesInDownLevel;
         ofs = ofs % bytesInDownLevel;
         dataSectorPtr = SectorPtr.Unpack(dataSector.Data, i * KeyValueDB.PtrDownSize);
         if (i < downPtrCount - 1)
         {
             dataLen = bytesInDownLevel;
         }
         else
         {
             dataLen = dataLen % bytesInDownLevel;
             if (dataLen == 0) dataLen = bytesInDownLevel;
         }
     }
 }
コード例 #8
0
ファイル: KeyValueDBTransaction.cs プロジェクト: quyenbc/BTDB
 public long GetValueSize()
 {
     if (_currentKeyIndexInLeaf < 0) return -1;
     var iter = new BTreeChildIterator(_currentKeySector.Data);
     iter.MoveTo(_currentKeyIndexInLeaf);
     return iter.ValueLen;
 }
コード例 #9
0
ファイル: KeyValueDBTransaction.cs プロジェクト: quyenbc/BTDB
 public int GetKeySize()
 {
     if (_currentKeyIndexInLeaf < 0) return -1;
     var iter = new BTreeChildIterator(_currentKeySector.Data);
     iter.MoveTo(_currentKeyIndexInLeaf);
     return iter.KeyLen - _prefix.Length;
 }
コード例 #10
0
ファイル: KeyValueDBTransaction.cs プロジェクト: quyenbc/BTDB
 void InternalWriteValue(long ofs, int len, byte[] buf, int bufOfs)
 {
     _currentKeySector = _owner.DirtizeSector(_currentKeySector, _currentKeySector.Parent, _currentKeySectorParents);
     var iter = new BTreeChildIterator(_currentKeySector.Data);
     iter.MoveTo(_currentKeyIndexInLeaf);
     var valueLen = iter.ValueLen;
     var valueLenInline = iter.ValueLenInline;
     if (ofs + len > valueLen - valueLenInline)
     {
         var inlineEnd = (int)(ofs + len - (valueLen - valueLenInline));
         var inlineStart = 0;
         if (ofs > valueLen - valueLenInline)
         {
             inlineStart = (int)(ofs - (valueLen - valueLenInline));
         }
         if (buf != null)
         {
             var inlineBufOfs = bufOfs + (int)(valueLen - valueLenInline + inlineStart - ofs);
             Array.Copy(buf, inlineBufOfs, iter.Data, iter.ValueOffset + inlineStart, inlineEnd - inlineStart);
         }
         else
         {
             Array.Clear(iter.Data, iter.ValueOffset + inlineStart, inlineEnd - inlineStart);
         }
         len -= inlineEnd - inlineStart;
         if (len == 0) return;
     }
     RecursiveWriteValue(iter.ValueSectorPtr, valueLen - valueLenInline, ofs, len, buf, bufOfs, _currentKeySector, iter.ValueSectorPtrOffset);
 }