Beispiel #1
0
        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
                });
            }
        }
Beispiel #3
0
        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());
                }
        }