private static void CopyTrees(StorageEnvironment existingEnv, StorageEnvironment compactedEnv, Action <CompactionProgress> progressReport = null) { var context = new TransactionPersistentContext(true); using (var txr = existingEnv.ReadTransaction(context)) using (var rootIterator = txr.LowLevelTransaction.RootObjects.Iterate(false)) { if (rootIterator.Seek(Slices.BeforeAllKeys) == false) { return; } var totalTreesCount = txr.LowLevelTransaction.RootObjects.State.NumberOfEntries; var copiedTrees = 0L; do { var treeName = rootIterator.CurrentKey.ToString(); var currentKey = rootIterator.CurrentKey.Clone(txr.Allocator); var objectType = txr.GetRootObjectType(currentKey); switch (objectType) { case RootObjectType.None: break; case RootObjectType.VariableSizeTree: copiedTrees = CopyVariableSizeTree(compactedEnv, progressReport, txr, treeName, copiedTrees, totalTreesCount, context); break; case RootObjectType.EmbeddedFixedSizeTree: case RootObjectType.FixedSizeTree: if (FreeSpaceHandling.IsFreeSpaceTreeName(treeName)) { copiedTrees++;// we don't copy the fixed size tree continue; } copiedTrees = CopyFixedSizeTrees(compactedEnv, progressReport, txr, rootIterator, treeName, copiedTrees, totalTreesCount, objectType, context); break; case RootObjectType.Table: copiedTrees = CopyTableTree(compactedEnv, progressReport, txr, treeName, copiedTrees, totalTreesCount, context); break; default: throw new ArgumentOutOfRangeException("Unknown " + objectType); } } while (rootIterator.MoveNext()); } }
public EnvironmentStats Stats() { using (var tx = NewLowLevelTransaction(TransactionFlags.Read)) { var numberOfAllocatedPages = Math.Max(_dataPager.NumberOfAllocatedPages, State.NextPageNumber - 1); // async apply to data file task return(new EnvironmentStats { FreePagesOverhead = FreeSpaceHandling.GetFreePagesOverhead(tx), RootPages = tx.RootObjects.State.PageCount, UnallocatedPagesAtEndOfFile = _dataPager.NumberOfAllocatedPages - NextPageNumber, UsedDataFileSizeInBytes = (State.NextPageNumber - 1) * Options.PageSize, AllocatedDataFileSizeInBytes = numberOfAllocatedPages * Options.PageSize, NextWriteTransactionId = NextWriteTransactionId, ActiveTransactions = ActiveTransactions }); } }
private static void CopyTrees(StorageEnvironment existingEnv, StorageEnvironment compactedEnv, Action <StorageCompactionProgress> progressReport, CancellationToken token) { var context = new TransactionPersistentContext(true); using (var txr = existingEnv.ReadTransaction(context)) using (var rootIterator = txr.LowLevelTransaction.RootObjects.Iterate(false)) { if (rootIterator.Seek(Slices.BeforeAllKeys) == false) { return; } var globalTableIndexesToSkipCopying = new HashSet <string>(); do { var objectType = txr.GetRootObjectType(rootIterator.CurrentKey); if (objectType != RootObjectType.Table) { continue; } var treeName = rootIterator.CurrentKey.ToString(); var tableTree = txr.ReadTree(treeName, RootObjectType.Table); var schemaSize = tableTree.GetDataSize(TableSchema.SchemasSlice); var schemaPtr = tableTree.DirectRead(TableSchema.SchemasSlice); var schema = TableSchema.ReadFrom(txr.Allocator, schemaPtr, schemaSize); if (schema.Key != null && schema.Key.IsGlobal) { globalTableIndexesToSkipCopying.Add(schema.Key.Name.ToString()); } foreach (var index in schema.Indexes.Values) { if (index.IsGlobal) { globalTableIndexesToSkipCopying.Add(index.Name.ToString()); } } foreach (var index in schema.FixedSizeIndexes.Values) { if (index.IsGlobal) { globalTableIndexesToSkipCopying.Add(index.Name.ToString()); } } } while (rootIterator.MoveNext()); if (rootIterator.Seek(Slices.BeforeAllKeys) == false) { return; } // substract skipped items var totalTreesCount = txr.LowLevelTransaction.RootObjects.State.NumberOfEntries - globalTableIndexesToSkipCopying.Count; var copiedTrees = 0L; do { token.ThrowIfCancellationRequested(); var treeName = rootIterator.CurrentKey.ToString(); if (globalTableIndexesToSkipCopying.Contains(treeName)) { continue; } var currentKey = rootIterator.CurrentKey.Clone(txr.Allocator); var objectType = txr.GetRootObjectType(currentKey); switch (objectType) { case RootObjectType.None: break; case RootObjectType.VariableSizeTree: copiedTrees = CopyVariableSizeTree(compactedEnv, progressReport, txr, treeName, copiedTrees, totalTreesCount, context, token); break; case RootObjectType.EmbeddedFixedSizeTree: case RootObjectType.FixedSizeTree: if (FreeSpaceHandling.IsFreeSpaceTreeName(treeName)) { copiedTrees++;// we don't copy the fixed size tree continue; } if (NewPageAllocator.AllocationStorageName == treeName) { copiedTrees++; continue; // we don't copy the allocator storage } copiedTrees = CopyFixedSizeTrees(compactedEnv, progressReport, txr, rootIterator, treeName, copiedTrees, totalTreesCount, context, token); break; case RootObjectType.Table: copiedTrees = CopyTableTree(compactedEnv, progressReport, txr, treeName, copiedTrees, totalTreesCount, context, token); break; default: throw new ArgumentOutOfRangeException("Unknown " + objectType); } } while (rootIterator.MoveNext()); } }