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 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); } }