ncdu: refactor accumulated attributes into a struct
This commit is contained in:
parent
a15885dd74
commit
97606bbdef
2 changed files with 68 additions and 47 deletions
|
@ -299,9 +299,9 @@ func (u *UI) biggestEntry() (biggest int64) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
for i := range u.entries {
|
for i := range u.entries {
|
||||||
size, _, _, _, _, _, _ := u.d.AttrI(u.sortPerm[i])
|
attrs, _ := u.d.AttrI(u.sortPerm[i])
|
||||||
if size > biggest {
|
if attrs.Size > biggest {
|
||||||
biggest = size
|
biggest = attrs.Size
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
|
@ -313,8 +313,8 @@ func (u *UI) hasEmptyDir() bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
for i := range u.entries {
|
for i := range u.entries {
|
||||||
_, count, _, isDir, _, _, _ := u.d.AttrI(u.sortPerm[i])
|
attrs, _ := u.d.AttrI(u.sortPerm[i])
|
||||||
if isDir && count == 0 {
|
if attrs.IsDir && attrs.Count == 0 {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -359,9 +359,9 @@ func (u *UI) Draw() error {
|
||||||
if y >= h-1 {
|
if y >= h-1 {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
size, count, countUnknownSize, isDir, readable, entriesHaveErrors, err := u.d.AttrI(u.sortPerm[n])
|
attrs, err := u.d.AttrI(u.sortPerm[n])
|
||||||
fg := termbox.ColorWhite
|
fg := termbox.ColorWhite
|
||||||
if entriesHaveErrors {
|
if attrs.EntriesHaveErrors {
|
||||||
fg = termbox.ColorYellow
|
fg = termbox.ColorYellow
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -372,19 +372,19 @@ func (u *UI) Draw() error {
|
||||||
fg, bg = bg, fg
|
fg, bg = bg, fg
|
||||||
}
|
}
|
||||||
mark := ' '
|
mark := ' '
|
||||||
if isDir {
|
if attrs.IsDir {
|
||||||
mark = '/'
|
mark = '/'
|
||||||
}
|
}
|
||||||
fileFlag := ' '
|
fileFlag := ' '
|
||||||
message := ""
|
message := ""
|
||||||
if !readable {
|
if !attrs.Readable {
|
||||||
message = " [not read yet]"
|
message = " [not read yet]"
|
||||||
}
|
}
|
||||||
if countUnknownSize > 0 {
|
if attrs.CountUnknownSize > 0 {
|
||||||
message = fmt.Sprintf(" [%d of %d files have unknown size, size may be underestimated]", countUnknownSize, count)
|
message = fmt.Sprintf(" [%d of %d files have unknown size, size may be underestimated]", attrs.CountUnknownSize, attrs.Count)
|
||||||
fileFlag = '~'
|
fileFlag = '~'
|
||||||
}
|
}
|
||||||
if entriesHaveErrors {
|
if attrs.EntriesHaveErrors {
|
||||||
message = " [some subdirectories could not be read, size may be underestimated]"
|
message = " [some subdirectories could not be read, size may be underestimated]"
|
||||||
fileFlag = '.'
|
fileFlag = '.'
|
||||||
}
|
}
|
||||||
|
@ -394,35 +394,29 @@ func (u *UI) Draw() error {
|
||||||
}
|
}
|
||||||
extras := ""
|
extras := ""
|
||||||
if u.showCounts {
|
if u.showCounts {
|
||||||
ss := operations.CountStringField(count, u.humanReadable, 9) + " "
|
ss := operations.CountStringField(attrs.Count, u.humanReadable, 9) + " "
|
||||||
if count > 0 {
|
if attrs.Count > 0 {
|
||||||
extras += ss
|
extras += ss
|
||||||
} else {
|
} else {
|
||||||
extras += strings.Repeat(" ", len(ss))
|
extras += strings.Repeat(" ", len(ss))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var averageSize float64
|
|
||||||
if count > 0 {
|
|
||||||
countForAverage := count - countUnknownSize
|
|
||||||
if countForAverage > 0 {
|
|
||||||
averageSize = float64(size) / float64(countForAverage)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if u.showDirAverageSize {
|
if u.showDirAverageSize {
|
||||||
ss := operations.SizeStringField(int64(averageSize), u.humanReadable, 9) + " "
|
avg := attrs.AverageSize()
|
||||||
if averageSize > 0 {
|
ss := operations.SizeStringField(int64(avg), u.humanReadable, 9) + " "
|
||||||
|
if avg > 0 {
|
||||||
extras += ss
|
extras += ss
|
||||||
} else {
|
} else {
|
||||||
extras += strings.Repeat(" ", len(ss))
|
extras += strings.Repeat(" ", len(ss))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if showEmptyDir {
|
if showEmptyDir {
|
||||||
if isDir && count == 0 && fileFlag == ' ' {
|
if attrs.IsDir && attrs.Count == 0 && fileFlag == ' ' {
|
||||||
fileFlag = 'e'
|
fileFlag = 'e'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if u.showGraph {
|
if u.showGraph {
|
||||||
bars := (size + perBar/2 - 1) / perBar
|
bars := (attrs.Size + perBar/2 - 1) / perBar
|
||||||
// clip if necessary - only happens during startup
|
// clip if necessary - only happens during startup
|
||||||
if bars > 10 {
|
if bars > 10 {
|
||||||
bars = 10
|
bars = 10
|
||||||
|
@ -431,7 +425,7 @@ func (u *UI) Draw() error {
|
||||||
}
|
}
|
||||||
extras += "[" + graph[graphBars-bars:2*graphBars-bars] + "] "
|
extras += "[" + graph[graphBars-bars:2*graphBars-bars] + "] "
|
||||||
}
|
}
|
||||||
Linef(0, y, w, fg, bg, ' ', "%c %s %s%c%s%s", fileFlag, operations.SizeStringField(size, u.humanReadable, 12), extras, mark, path.Base(entry.Remote()), message)
|
Linef(0, y, w, fg, bg, ' ', "%c %s %s%c%s%s", fileFlag, operations.SizeStringField(attrs.Size, u.humanReadable, 12), extras, mark, path.Base(entry.Remote()), message)
|
||||||
y++
|
y++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -582,14 +576,14 @@ type ncduSort struct {
|
||||||
// Less is part of sort.Interface.
|
// Less is part of sort.Interface.
|
||||||
func (ds *ncduSort) Less(i, j int) bool {
|
func (ds *ncduSort) Less(i, j int) bool {
|
||||||
var iAvgSize, jAvgSize float64
|
var iAvgSize, jAvgSize float64
|
||||||
isize, icount, _, _, _, _, _ := ds.d.AttrI(ds.sortPerm[i])
|
iattrs, _ := ds.d.AttrI(ds.sortPerm[i])
|
||||||
jsize, jcount, _, _, _, _, _ := ds.d.AttrI(ds.sortPerm[j])
|
jattrs, _ := ds.d.AttrI(ds.sortPerm[j])
|
||||||
iname, jname := ds.entries[ds.sortPerm[i]].Remote(), ds.entries[ds.sortPerm[j]].Remote()
|
iname, jname := ds.entries[ds.sortPerm[i]].Remote(), ds.entries[ds.sortPerm[j]].Remote()
|
||||||
if icount > 0 {
|
if iattrs.Count > 0 {
|
||||||
iAvgSize = float64(isize / icount)
|
iAvgSize = iattrs.AverageSize()
|
||||||
}
|
}
|
||||||
if jcount > 0 {
|
if jattrs.Count > 0 {
|
||||||
jAvgSize = float64(jsize / jcount)
|
jAvgSize = jattrs.AverageSize()
|
||||||
}
|
}
|
||||||
|
|
||||||
switch {
|
switch {
|
||||||
|
@ -598,33 +592,33 @@ func (ds *ncduSort) Less(i, j int) bool {
|
||||||
case ds.u.sortByName > 0:
|
case ds.u.sortByName > 0:
|
||||||
break
|
break
|
||||||
case ds.u.sortBySize < 0:
|
case ds.u.sortBySize < 0:
|
||||||
if isize != jsize {
|
if iattrs.Size != jattrs.Size {
|
||||||
return isize < jsize
|
return iattrs.Size < jattrs.Size
|
||||||
}
|
}
|
||||||
case ds.u.sortBySize > 0:
|
case ds.u.sortBySize > 0:
|
||||||
if isize != jsize {
|
if iattrs.Size != jattrs.Size {
|
||||||
return isize > jsize
|
return iattrs.Size > jattrs.Size
|
||||||
}
|
}
|
||||||
case ds.u.sortByCount < 0:
|
case ds.u.sortByCount < 0:
|
||||||
if icount != jcount {
|
if iattrs.Count != jattrs.Count {
|
||||||
return icount < jcount
|
return iattrs.Count < jattrs.Count
|
||||||
}
|
}
|
||||||
case ds.u.sortByCount > 0:
|
case ds.u.sortByCount > 0:
|
||||||
if icount != jcount {
|
if iattrs.Count != jattrs.Count {
|
||||||
return icount > jcount
|
return iattrs.Count > jattrs.Count
|
||||||
}
|
}
|
||||||
case ds.u.sortByAverageSize < 0:
|
case ds.u.sortByAverageSize < 0:
|
||||||
if iAvgSize != jAvgSize {
|
if iAvgSize != jAvgSize {
|
||||||
return iAvgSize < jAvgSize
|
return iAvgSize < jAvgSize
|
||||||
}
|
}
|
||||||
// if avgSize is equal, sort by size
|
// if avgSize is equal, sort by size
|
||||||
return isize < jsize
|
return iattrs.Size < jattrs.Size
|
||||||
case ds.u.sortByAverageSize > 0:
|
case ds.u.sortByAverageSize > 0:
|
||||||
if iAvgSize != jAvgSize {
|
if iAvgSize != jAvgSize {
|
||||||
return iAvgSize > jAvgSize
|
return iAvgSize > jAvgSize
|
||||||
}
|
}
|
||||||
// if avgSize is equal, sort by size
|
// if avgSize is equal, sort by size
|
||||||
return isize > jsize
|
return iattrs.Size > jattrs.Size
|
||||||
}
|
}
|
||||||
// if everything equal, sort by name
|
// if everything equal, sort by name
|
||||||
return iname < jname
|
return iname < jname
|
||||||
|
|
|
@ -25,6 +25,33 @@ type Dir struct {
|
||||||
entriesHaveErrors bool
|
entriesHaveErrors bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Attrs contains accumulated properties for a directory entry
|
||||||
|
//
|
||||||
|
// Files with unknown size are counted separately but also included
|
||||||
|
// in the total count. They are not included in the size, i.e. treated
|
||||||
|
// as empty files, which means the size may be underestimated.
|
||||||
|
type Attrs struct {
|
||||||
|
Size int64
|
||||||
|
Count int64
|
||||||
|
CountUnknownSize int64
|
||||||
|
IsDir bool
|
||||||
|
Readable bool
|
||||||
|
EntriesHaveErrors bool
|
||||||
|
}
|
||||||
|
|
||||||
|
// AverageSize calculates average size of files in directory
|
||||||
|
//
|
||||||
|
// If there are files with unknown size, this returns the average over
|
||||||
|
// files with known sizes, which means it may be under- or
|
||||||
|
// overestimated.
|
||||||
|
func (a *Attrs) AverageSize() float64 {
|
||||||
|
countKnownSize := a.Count - a.CountUnknownSize
|
||||||
|
if countKnownSize > 0 {
|
||||||
|
return float64(a.Size) / float64(countKnownSize)
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
// Parent returns the directory above this one
|
// Parent returns the directory above this one
|
||||||
func (d *Dir) Parent() *Dir {
|
func (d *Dir) Parent() *Dir {
|
||||||
// no locking needed since these are write once in newDir()
|
// no locking needed since these are write once in newDir()
|
||||||
|
@ -167,19 +194,19 @@ func (d *Dir) Attr() (size int64, count int64) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// AttrI returns the size, count and flags for the i-th directory entry
|
// AttrI returns the size, count and flags for the i-th directory entry
|
||||||
func (d *Dir) AttrI(i int) (size int64, count int64, countUnknownSize int64, isDir bool, readable bool, entriesHaveErrors bool, err error) {
|
func (d *Dir) AttrI(i int) (attrs Attrs, err error) {
|
||||||
d.mu.Lock()
|
d.mu.Lock()
|
||||||
defer d.mu.Unlock()
|
defer d.mu.Unlock()
|
||||||
subDir, isDir := d.getDir(i)
|
subDir, isDir := d.getDir(i)
|
||||||
|
|
||||||
if !isDir {
|
if !isDir {
|
||||||
return d.entries[i].Size(), 0, 0, false, true, d.entriesHaveErrors, d.readError
|
return Attrs{d.entries[i].Size(), 0, 0, false, true, d.entriesHaveErrors}, d.readError
|
||||||
}
|
}
|
||||||
if subDir == nil {
|
if subDir == nil {
|
||||||
return 0, 0, 0, true, false, false, nil
|
return Attrs{0, 0, 0, true, false, false}, nil
|
||||||
}
|
}
|
||||||
size, count = subDir.Attr()
|
size, count := subDir.Attr()
|
||||||
return size, count, subDir.countUnknownSize, true, true, subDir.entriesHaveErrors, subDir.readError
|
return Attrs{size, count, subDir.countUnknownSize, true, true, subDir.entriesHaveErrors}, subDir.readError
|
||||||
}
|
}
|
||||||
|
|
||||||
// Scan the Fs passed in, returning a root directory channel and an
|
// Scan the Fs passed in, returning a root directory channel and an
|
||||||
|
|
Loading…
Reference in a new issue