public StorageReport Generate(ReportInput input) { var unallocatedPagesAtEndOfFile = input.NumberOfAllocatedPages - input.NextPageNumber; var dataFile = new DataFileReport { AllocatedSpaceInBytes = PagesToBytes(input.NumberOfAllocatedPages), SpaceInUseInBytes = PagesToBytes(input.NextPageNumber - input.NumberOfFreePages), FreeSpaceInBytes = PagesToBytes(input.NumberOfFreePages + unallocatedPagesAtEndOfFile) }; var trees = new List <TreeReport>(); foreach (var tree in input.Trees) { List <double> densities = null; if (input.IsLightReport == false) { densities = GetPageDensities(tree); } MultiValuesReport multiValues = null; if (tree.State.Flags == TreeFlags.MultiValueTrees) { multiValues = CreateMultiValuesReport(tree); } var state = tree.State; var treeReport = new TreeReport { Name = tree.Name, BranchPages = state.BranchPages, Depth = state.Depth, EntriesCount = state.EntriesCount, LeafPages = state.LeafPages, OverflowPages = state.OverflowPages, PageCount = state.PageCount, Density = densities == null ? 0 : CalculateTreeDensity(densities), MultiValues = multiValues }; trees.Add(treeReport); } var journals = input.Journals.Select(journal => new JournalReport { Number = journal.Number, AllocatedSpaceInBytes = PagesToBytes(journal.JournalWriter.NumberOfAllocatedPages) }).ToList(); return(new StorageReport { DataFile = dataFile, Trees = trees, Journals = journals }); }
private MultiValuesReport CreateMultiValuesReport(Tree tree, CancellationToken token) { var multiValues = new MultiValuesReport(); using (var multiTreeIterator = tree.Iterate()) { if (multiTreeIterator.Seek(Slice.BeforeAllKeys)) { do { token.ThrowIfCancellationRequested(); var currentNode = multiTreeIterator.Current; switch (currentNode->Flags) { case NodeFlags.MultiValuePageRef: { var multiValueTreeHeader = (TreeRootHeader *)((byte *)currentNode + currentNode->KeySize + Constants.NodeHeaderSize); Debug.Assert(multiValueTreeHeader->Flags == TreeFlags.MultiValue); multiValues.EntriesCount += multiValueTreeHeader->EntriesCount; multiValues.BranchPages += multiValueTreeHeader->BranchPages; multiValues.LeafPages += multiValueTreeHeader->LeafPages; multiValues.PageCount += multiValueTreeHeader->PageCount; break; } case NodeFlags.Data: { var nestedPage = GetNestedMultiValuePage(NodeHeader.DirectAccess(_tx, currentNode), currentNode); multiValues.EntriesCount += nestedPage.NumberOfEntries; break; } case NodeFlags.PageRef: { var overFlowPage = _tx.GetReadOnlyPage(currentNode->PageNumber); var nestedPage = GetNestedMultiValuePage(overFlowPage.Base + Constants.PageHeaderSize, currentNode); multiValues.EntriesCount += nestedPage.NumberOfEntries; break; } default: throw new InvalidEnumArgumentException("currentNode->Flags", (int)currentNode->Flags, typeof(NodeFlags)); } } while (multiTreeIterator.MoveNext()); } } return(multiValues); }
private static MultiValuesReport CreateMultiValuesReport(Tree tree) { var multiValues = new MultiValuesReport(); using (var multiTreeIterator = tree.Iterate(false)) { if (multiTreeIterator.Seek(Slices.BeforeAllKeys)) { do { var currentNode = multiTreeIterator.Current; switch (currentNode->Flags) { case TreeNodeFlags.MultiValuePageRef: { var multiValueTreeHeader = (TreeRootHeader *)((byte *)currentNode + currentNode->KeySize + Constants.Tree.NodeHeaderSize); Debug.Assert(multiValueTreeHeader->Flags == TreeFlags.MultiValue); multiValues.NumberOfEntries += multiValueTreeHeader->NumberOfEntries; multiValues.BranchPages += multiValueTreeHeader->BranchPages; multiValues.LeafPages += multiValueTreeHeader->LeafPages; multiValues.PageCount += multiValueTreeHeader->PageCount; break; } case TreeNodeFlags.Data: { var nestedPage = GetNestedMultiValuePage(tree, tree.DirectAccessFromHeader(currentNode), currentNode); multiValues.NumberOfEntries += nestedPage.NumberOfEntries; break; } case TreeNodeFlags.PageRef: { var overFlowPage = tree.GetReadOnlyTreePage(currentNode->PageNumber); var nestedPage = GetNestedMultiValuePage(tree, overFlowPage.Base + Constants.Tree.PageHeaderSize, currentNode); multiValues.NumberOfEntries += nestedPage.NumberOfEntries; break; } default: VoronUnrecoverableErrorException.Raise(tree.Llt, "currentNode->FixedTreeFlags has value of " + currentNode->Flags); break; } } while (multiTreeIterator.MoveNext()); } } return(multiValues); }
public static TreeReport GetReport(Tree tree, bool includeDetails) { List <double> pageDensities = null; Dictionary <int, int> pageBalance = null; if (includeDetails) { pageDensities = GetPageDensities(tree); pageBalance = GatherBalanceDistribution(tree); } MultiValuesReport multiValues = null; StreamsReport streams = null; if (tree.State.Flags == TreeFlags.MultiValueTrees) { multiValues = CreateMultiValuesReport(tree); } else if (tree.State.Flags == (TreeFlags.FixedSizeTrees | TreeFlags.Streams)) { streams = CreateStreamsReport(tree); } var density = pageDensities?.Average() ?? -1; var treeReport = new TreeReport { Type = RootObjectType.VariableSizeTree, Name = tree.Name.ToString(), BranchPages = tree.State.BranchPages, Depth = tree.State.Depth, NumberOfEntries = tree.State.NumberOfEntries, LeafPages = tree.State.LeafPages, OverflowPages = tree.State.OverflowPages, PageCount = tree.State.PageCount, Density = density, AllocatedSpaceInBytes = tree.State.PageCount * Constants.Storage.PageSize + (streams?.AllocatedSpaceInBytes ?? 0), UsedSpaceInBytes = includeDetails ? (long)(tree.State.PageCount * Constants.Storage.PageSize * density) : -1, MultiValues = multiValues, Streams = streams, BalanceHistogram = pageBalance, }; return(treeReport); }
public static TreeReport GetReport(Tree tree, bool calculateExactSizes) { List <double> pageDensities = null; if (calculateExactSizes) { pageDensities = GetPageDensities(tree); } MultiValuesReport multiValues = null; if (tree.State.Flags == TreeFlags.MultiValueTrees) { multiValues = CreateMultiValuesReport(tree); } var density = pageDensities?.Average() ?? -1; var treeReport = new TreeReport { Type = RootObjectType.VariableSizeTree, Name = tree.Name.ToString(), BranchPages = tree.State.BranchPages, Depth = tree.State.Depth, NumberOfEntries = tree.State.NumberOfEntries, LeafPages = tree.State.LeafPages, OverflowPages = tree.State.OverflowPages, PageCount = tree.State.PageCount, Density = density, AllocatedSpaceInBytes = tree.State.PageCount * tree.Llt.PageSize, UsedSpaceInBytes = calculateExactSizes ? (long)(tree.State.PageCount * tree.Llt.PageSize * density) : -1, MultiValues = multiValues }; return(treeReport); }
private MultiValuesReport CreateMultiValuesReport(Tree tree) { var multiValues = new MultiValuesReport(); using (var multiTreeIterator = tree.Iterate()) { if (multiTreeIterator.Seek(Slice.BeforeAllKeys)) { do { var currentNode = multiTreeIterator.Current; switch (currentNode->Flags) { case NodeFlags.MultiValuePageRef: { var multiValueTreeHeader = (TreeRootHeader*) ((byte*) currentNode + currentNode->KeySize + Constants.NodeHeaderSize); Debug.Assert(multiValueTreeHeader->Flags == TreeFlags.MultiValue); multiValues.EntriesCount += multiValueTreeHeader->EntriesCount; multiValues.BranchPages += multiValueTreeHeader->BranchPages; multiValues.LeafPages += multiValueTreeHeader->LeafPages; multiValues.PageCount += multiValueTreeHeader->PageCount; break; } case NodeFlags.Data: { var nestedPage = GetNestedMultiValuePage(NodeHeader.DirectAccess(_tx, currentNode), currentNode); multiValues.EntriesCount += nestedPage.NumberOfEntries; break; } case NodeFlags.PageRef: { var overFlowPage = _tx.GetReadOnlyPage(currentNode->PageNumber); var nestedPage = GetNestedMultiValuePage(overFlowPage.Base + Constants.PageHeaderSize, currentNode); multiValues.EntriesCount += nestedPage.NumberOfEntries; break; } default: throw new InvalidEnumArgumentException("currentNode->Flags", (int) currentNode->Flags, typeof (NodeFlags)); } } while (multiTreeIterator.MoveNext()); } } return multiValues; }