From 183c687c06b780ea9372c8c8c173f38cdefce338 Mon Sep 17 00:00:00 2001 From: Alex Goodman Date: Sun, 21 Oct 2018 13:59:08 -0400 Subject: [PATCH] efficiency now takes into account removed dirs --- filetree/efficiency.go | 36 ++++++++++++++++++++++++++++++++---- ui/detailsview.go | 5 +---- 2 files changed, 33 insertions(+), 8 deletions(-) diff --git a/filetree/efficiency.go b/filetree/efficiency.go index caf2bcb..3789b89 100644 --- a/filetree/efficiency.go +++ b/filetree/efficiency.go @@ -1,6 +1,7 @@ package filetree import ( + "github.com/sirupsen/logrus" "sort" ) @@ -36,6 +37,7 @@ func (efs EfficiencySlice) Less(i, j int) bool { func Efficiency(trees []*FileTree) (float64, EfficiencySlice) { efficiencyMap := make(map[string]*EfficiencyData) inefficientMatches := make(EfficiencySlice, 0) + currentTree := 0 visitor := func(node *FileNode) error { path := node.Path() @@ -47,9 +49,34 @@ func Efficiency(trees []*FileTree) (float64, EfficiencySlice) { } } data := efficiencyMap[path] - data.CumulativeSize += node.Data.FileInfo.TarHeader.Size - if data.minDiscoveredSize < 0 || node.Data.FileInfo.TarHeader.Size < data.minDiscoveredSize { - data.minDiscoveredSize = node.Data.FileInfo.TarHeader.Size + + // this node may have had children that were deleted, however, we won't explicitly list out every child, only + // the top-most parent with the cumulative size. These operations will need to be done on the full (stacked) + // tree. + // Note: whiteout files may also represent directories, so we need to find out if this was previously a file or dir. + var sizeBytes int64 + + if node.IsWhiteout() { + sizer := func(curNode *FileNode) error { + sizeBytes += curNode.Data.FileInfo.TarHeader.FileInfo().Size() + return nil + } + stackedTree := StackRange(trees, 0, currentTree-1) + previousTreeNode, err := stackedTree.GetNode(node.Path()) + if err != nil { + logrus.Fatal(err) + } + if previousTreeNode.Data.FileInfo.TarHeader.FileInfo().IsDir() { + previousTreeNode.VisitDepthChildFirst(sizer, nil) + } + + } else { + sizeBytes = node.Data.FileInfo.TarHeader.FileInfo().Size() + } + + data.CumulativeSize += sizeBytes + if data.minDiscoveredSize < 0 || sizeBytes < data.minDiscoveredSize { + data.minDiscoveredSize = sizeBytes } data.Nodes = append(data.Nodes, node) @@ -62,7 +89,8 @@ func Efficiency(trees []*FileTree) (float64, EfficiencySlice) { visitEvaluator := func(node *FileNode) bool { return node.IsLeaf() } - for _, tree := range trees { + for idx, tree := range trees { + currentTree = idx tree.VisitDepthChildFirst(visitor, visitEvaluator) } diff --git a/ui/detailsview.go b/ui/detailsview.go index 3753a7d..663859d 100644 --- a/ui/detailsview.go +++ b/ui/detailsview.go @@ -79,7 +79,7 @@ func (view *DetailsView) CursorUp() error { // Update refreshes the state objects for future rendering. Note: we only need to update this view upon the initial tree load func (view *DetailsView) Update() error { layerTrees := Views.Tree.RefTrees - view.efficiency, view.inefficiencies = filetree.Efficiency(layerTrees[:len(layerTrees)-1]) + view.efficiency, view.inefficiencies = filetree.Efficiency(layerTrees) return nil } @@ -98,9 +98,6 @@ func (view *DetailsView) Render() error { inefficiencyReport := fmt.Sprintf(Formatting.Header(template), "Count", "Total Space", "Path") for idx := len(view.inefficiencies) - 1; idx >= 0; idx-- { data := view.inefficiencies[idx] - if data.CumulativeSize == 0 { - continue - } trueInefficiencies++ wastedSpace += data.CumulativeSize inefficiencyReport += fmt.Sprintf(template, strconv.Itoa(len(data.Nodes)), humanize.Bytes(uint64(data.CumulativeSize)), data.Path)