public bool StartsWith(Slice other, SliceComparer cmp) { if (Size < other.Size) { return(false); } return(CompareData(other, cmp, other.Size) == 0); }
public int Compare(Slice other, SliceComparer cmp) { Debug.Assert(Options == SliceOptions.Key); var r = CompareData(other, cmp, Math.Min(Size, other.Size)); if (r != 0) { return(r); } return(Size - other.Size); }
public ushort FindPrefixSize(MemorySlice other) { _matchedBytes = 0; if (_matchPrefixInstance == null) { _matchPrefixInstance = MatchPrefix; } CompareData(other, _matchPrefixInstance, Math.Min(KeyLength, other.KeyLength)); return(_matchedBytes); }
protected override int CompareData(MemorySlice other, SliceComparer cmp, ushort size) { var prefixedSlice = other as PrefixedSlice; if (prefixedSlice != null) { return(SliceComparisonMethods.Compare(this, prefixedSlice, cmp, size)); } var slice = other as Slice; if (slice != null) { return(SliceComparisonMethods.Compare(slice, this, cmp, size) * -1); } throw new NotSupportedException("Cannot compare because of unknown slice type: " + other.GetType()); }
public StorageEnvironment(IVirtualPager pager, bool ownsPager = true) { try { _pager = pager; _ownsPager = ownsPager; _freeSpaceRepository = new FreeSpaceRepository(this); _sliceComparer = NativeMethods.memcmp; Setup(pager); FreeSpaceRoot.Name = "Free Space"; Root.Name = "Root"; } catch (Exception) { Dispose(); } }
protected override int CompareData(MemorySlice other, SliceComparer cmp, ushort size) { var otherSlice = other as Slice; if (otherSlice != null) { if (Array != null) { fixed(byte *a = Array) { if (otherSlice.Array != null) { fixed(byte *b = otherSlice.Array) { return(cmp(a, b, size)); } } return(cmp(a, otherSlice.Pointer, size)); } } if (otherSlice.Array != null) { fixed(byte *b = otherSlice.Array) { return(cmp(Pointer, b, size)); } } return(cmp(Pointer, otherSlice.Pointer, size)); } var prefixedSlice = other as PrefixedSlice; if (prefixedSlice != null) { return(SliceComparisonMethods.Compare(this, prefixedSlice, cmp, size)); } throw new NotSupportedException("Cannot compare because of unknown slice type: " + other.GetType()); }
public unsafe StorageEnvironment(StorageEnvironmentOptions options) { try { TemporaryPage = new TemporaryPage(); _options = options; _dataPager = options.DataPager; _freeSpaceHandling = new FreeSpaceHandling(this); _sliceComparer = NativeMethods.memcmp; _headerAccessor = new HeaderAccessor(this); var isNew = _headerAccessor.Initialize(); _scratchBufferPool = new ScratchBufferPool(this); _journal = new WriteAheadJournal(this); if (isNew) { CreateNewDatabase(); } else // existing db, let us load it { LoadExistingDatabase(); } State.FreeSpaceRoot.Name = Constants.FreeSpaceTreeName; State.Root.Name = Constants.RootTreeName; Writer = new TransactionMergingWriter(this); if (_options.ManualFlushing == false) { _flushingTask = FlushWritesToDataFileAsync(); } } catch (Exception) { Dispose(); throw; } }
public static int Compare(byte *prefix_x, ushort prefix_x_len, byte *prefix_y, ushort prefix_y_len, byte *x, ushort x_len, byte *y, ushort y_len, SliceComparer cmp, ushort size) { if (size == 0) // empty slice before all keys { return(0); } if (prefix_x_len == 0 && prefix_y_len == 0) { return(cmp(x, y, size)); } ushort toCompare; if (prefix_x_len == 0) { toCompare = Math.Min(prefix_y_len, size); var r = cmp(x, prefix_y, toCompare); if (r != 0) { return(r); } size -= toCompare; return(cmp(x + prefix_y_len, y, size)); } if (prefix_y_len == 0) { toCompare = Math.Min(prefix_x_len, size); var r = cmp(prefix_x, y, toCompare); if (r != 0) { return(r); } size -= toCompare; return(cmp(x, y + prefix_x_len, size)); } if (prefix_x_len > prefix_y_len) { var r = cmp(prefix_x, prefix_y, prefix_y_len); if (r != 0) { return(r); } size -= prefix_y_len; toCompare = Math.Min((ushort)(prefix_x_len - prefix_y_len), size); r = cmp(prefix_x + prefix_y_len, y, toCompare); if (r != 0) { return(r); } size -= toCompare; return(cmp(x, y + toCompare, size)); } else { var r = cmp(prefix_x, prefix_y, prefix_x_len); if (r != 0) { return(r); } size -= prefix_x_len; toCompare = Math.Min((ushort)(prefix_y_len - prefix_x_len), size); r = cmp(x, prefix_y + prefix_x_len, toCompare); if (r != 0) { return(r); } size -= toCompare; return(cmp(x + toCompare, y, size)); } }
public static int Compare(Slice x, PrefixedSlice y, SliceComparer cmp, ushort size) { fixed(byte *p1 = x.Array) fixed(byte *p2 = y.NonPrefixedData.Array) { var xPtr = p1 != null ? p1 : x.Pointer; var yPtr = p2 != null ? p2 : y.NonPrefixedData.Pointer; if (y.Header.PrefixId == PrefixedSlice.NonPrefixedId) { return(Compare(null, 0, null, 0, xPtr, x.KeyLength, yPtr, y.Header.NonPrefixedDataSize, cmp, size)); } if (x.PrefixComparisonCache == null) { if (y.Prefix == null) { return(Compare(null, 0, null, 0, xPtr, x.KeyLength, yPtr, y.Header.NonPrefixedDataSize, cmp, size)); } else if (y.Prefix.Value == null) { return(Compare(null, 0, y.Prefix.ValuePtr, y.Header.PrefixUsage, xPtr, x.KeyLength, yPtr, y.Header.NonPrefixedDataSize, cmp, size)); } else { fixed(byte *prefixVal = y.Prefix.Value) return(Compare(null, 0, prefixVal, y.Header.PrefixUsage, xPtr, x.KeyLength, yPtr, y.Header.NonPrefixedDataSize, cmp, size)); } } var prefixBytesToCompare = Math.Min(y.Header.PrefixUsage, x.KeyLength); int r; if (x.PrefixComparisonCache.TryGetCachedResult(y.Header.PrefixId, y.Prefix.PageNumber, prefixBytesToCompare, out r) == false) { if (y.Prefix == null) { r = Compare(null, 0, null, 0, xPtr, x.KeyLength, null, 0, cmp, prefixBytesToCompare); } else if (y.Prefix.Value == null) { r = Compare(null, 0, y.Prefix.ValuePtr, y.Header.PrefixUsage, xPtr, x.KeyLength, null, 0, cmp, prefixBytesToCompare); } else { fixed(byte *prefixVal = y.Prefix.Value) r = Compare(null, 0, prefixVal, y.Header.PrefixUsage, xPtr, x.KeyLength, null, 0, cmp, prefixBytesToCompare); } x.PrefixComparisonCache.SetPrefixComparisonResult(y.Header.PrefixId, y.Prefix.PageNumber, prefixBytesToCompare, r); } if (r != 0) { return(r); } size -= prefixBytesToCompare; return(Compare(null, 0, null, 0, xPtr + prefixBytesToCompare, (ushort)(x.KeyLength - prefixBytesToCompare), yPtr, y.Header.NonPrefixedDataSize, cmp, size)); } }
protected abstract int CompareData(MemorySlice other, SliceComparer cmp, ushort size);
public unsafe DetailedStorageReport GenerateDetailedReport(Transaction tx, bool calculateExactSizes = false) { var numberOfAllocatedPages = Math.Max(_dataPager.NumberOfAllocatedPages, NextPageNumber - 1); // async apply to data file task var numberOfFreePages = _freeSpaceHandling.AllPages(tx.LowLevelTransaction).Count; var trees = new List <Tree>(); var fixedSizeTrees = new List <FixedSizeTree>(); var tables = new List <Table>(); using (var rootIterator = tx.LowLevelTransaction.RootObjects.Iterate(false)) { if (rootIterator.Seek(Slices.BeforeAllKeys)) { do { var currentKey = rootIterator.CurrentKey.Clone(tx.Allocator); var type = tx.GetRootObjectType(currentKey); switch (type) { case RootObjectType.VariableSizeTree: var tree = tx.ReadTree(currentKey); trees.Add(tree); break; case RootObjectType.EmbeddedFixedSizeTree: break; case RootObjectType.FixedSizeTree: if (SliceComparer.AreEqual(currentKey, NewPageAllocator.AllocationStorage)) // will be counted inside pre allocated buffers report { continue; } fixedSizeTrees.Add(tx.FixedTreeFor(currentKey)); break; case RootObjectType.Table: var tableTree = tx.ReadTree(currentKey, RootObjectType.Table); var writtenSchemaData = tableTree.DirectRead(TableSchema.SchemasSlice); var writtenSchemaDataSize = tableTree.GetDataSize(TableSchema.SchemasSlice); var tableSchema = TableSchema.ReadFrom(tx.Allocator, writtenSchemaData, writtenSchemaDataSize); var table = tx.OpenTable(tableSchema, currentKey); tables.Add(table); break; default: throw new ArgumentOutOfRangeException(); } }while (rootIterator.MoveNext()); } } var generator = new StorageReportGenerator(tx.LowLevelTransaction); return(generator.Generate(new DetailedReportInput { NumberOfAllocatedPages = numberOfAllocatedPages, NumberOfFreePages = numberOfFreePages, NextPageNumber = NextPageNumber, Journals = Journal.Files.ToList(), Trees = trees, FixedSizeTrees = fixedSizeTrees, Tables = tables, CalculateExactSizes = calculateExactSizes, ScratchBufferPoolInfo = _scratchBufferPool.InfoForDebug(PossibleOldestReadTransaction(tx.LowLevelTransaction)) })); }