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); }
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); } }
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); }
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); } }
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); } }
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; } } }
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; } } }
public long GetValueSize() { if (_currentKeyIndexInLeaf < 0) return -1; var iter = new BTreeChildIterator(_currentKeySector.Data); iter.MoveTo(_currentKeyIndexInLeaf); return iter.ValueLen; }
public int GetKeySize() { if (_currentKeyIndexInLeaf < 0) return -1; var iter = new BTreeChildIterator(_currentKeySector.Data); iter.MoveTo(_currentKeyIndexInLeaf); return iter.KeyLen - _prefix.Length; }
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); }