Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
103 changes: 103 additions & 0 deletions format.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
package tree

import (
"fmt"
"strings"
)

// KB = 1000 bytes
const (
KB = 1 * 1000
MB = KB * 1000
GB = MB * 1000
TB = GB * 1000
PB = TB * 1000
EB = PB * 1000
)

// Do it using KiB format, so KB = 1024 ...
const (
_ = iota // ignore first value by assigning to blank identifier
KiB int64 = 1 << (10 * iota)
MiB
GiB
TiB
PiB
EiB
)

// round use like so: "%.1f", round(f, 0.1) or "%.0f", round(f, 1)
// Otherwise 9.9999 is < 10 but "%.1f" will give "10.0"
func round(x, unit float64) float64 {
return float64(int64(x/unit+0.5)) * unit
}

// Convert bytes to human readable string. Like a 2 MB, 64.2 KB, 52 B
func formatBytes(i int64) (result string) {
var n float64
sFmt, eFmt := "%.01f", ""
switch {
case i >= EB:
eFmt = "E"
n = float64(i) / float64(EB)
case i >= PB:
eFmt = "P"
n = float64(i) / float64(PB)
case i >= TB:
eFmt = "T"
n = float64(i) / float64(TB)
case i >= GB:
eFmt = "G"
n = float64(i) / float64(GB)
case i >= MB:
eFmt = "M"
n = float64(i) / float64(MB)
case i >= KB:
eFmt = "K"
n = float64(i) / float64(KB)
default:
sFmt = "%.0f"
n = float64(i)
}
if eFmt != "" && round(n, 0.1) >= 10 {
sFmt = "%.0f"
}
result = fmt.Sprintf(sFmt+eFmt, n)
result = strings.Trim(result, " ")
return
}

// Convert bytes to human readable string. Like a 2 MB, 64.2 KB, 52 B
func formatBytesKiB(i int64) (result string) {
var n float64
sFmt, eFmt := "%.01f", ""
switch {
case i >= EiB:
eFmt = "E"
n = float64(i) / float64(EiB)
case i >= PiB:
eFmt = "P"
n = float64(i) / float64(PiB)
case i >= TiB:
eFmt = "T"
n = float64(i) / float64(TiB)
case i >= GiB:
eFmt = "G"
n = float64(i) / float64(GiB)
case i >= MiB:
eFmt = "M"
n = float64(i) / float64(MiB)
case i >= KiB:
eFmt = "K"
n = float64(i) / float64(KiB)
default:
sFmt = "%.0f"
n = float64(i)
}
if eFmt != "" && round(n, 0.1) >= 10 {
sFmt = "%.0f"
}
result = fmt.Sprintf(sFmt+eFmt, n)
result = strings.Trim(result, " ")
return
}
105 changes: 105 additions & 0 deletions format_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
package tree

import (
"testing"
)

func TestFormatBytes(t *testing.T) {
data := []struct {
val int64
res string
}{
{0, "0"}, // 0
{1, "1"},
{2, "2"},
{9, "9"},
{10, "10"},
{11, "11"},
{99, "99"},
{100, "100"},
{101, "101"},
{999, "999"},

{1000, "1.0K"}, // 10
{1001, "1.0K"},
{1002, "1.0K"},
{1202, "1.2K"},
{9202, "9.2K"},
{9849, "9.8K"},
{9900, "9.9K"},
{9900, "9.9K"},
{9999, "10K"},
{10000, "10K"},
{10001, "10K"}, // 20
{10022, "10K"},
{10333, "10K"},
{14444, "14K"},
{19999, "20K"},

{1000 * 1024, "1.0M"},
{1000 * 1001, "1.0M"},
{1000 * 1002, "1.0M"},
{1000 * 1202, "1.2M"},
{1000 * 9202, "9.2M"},
{1000 * 9202, "9.2M"}, // 30
{1000 * 9849, "9.8M"},
{1000 * 9900, "9.9M"},
{1000 * 9900, "9.9M"},
{1000 * 9999, "10M"},
{1000 * 10000, "10M"},
{1000 * 10001, "10M"},
{1000 * 10022, "10M"},
{1000 * 10333, "10M"},
{1000 * 14444, "14M"},
{1000 * 19999, "20M"}, // 40
}

for i := range data {
val := data[i].val
res := data[i].res

if tst := formatBytes(val); tst != res {
t.Errorf("data not equal: %v: %v\n tst=<%s>\n got <%s>\n",
i, val, res, tst)
}
}
}

func TestFormatBytesKiB(t *testing.T) {
data := []struct {
val int64
res string
}{
{0, "0"}, // 0
{1, "1"},
{2, "2"},
{9, "9"},
{10, "10"},
{11, "11"},
{99, "99"},
{100, "100"},
{101, "101"},
{999, "999"},

{1024 + 0, "1.0K"}, // 10
{1024 + 1, "1.0K"},
{1024 + 2, "1.0K"},
{1024 + 202, "1.2K"},

{1024*1024 - 2, "1024K"},
{1024*1024 - 1, "1024K"}, // 15
{1024 * 1024, "1.0M"},
{1024*1024 + 1, "1.0M"},
{1024*1024 + 2, "1.0M"},
}

for i := range data {
val := data[i].val
res := data[i].res

if tst := formatBytesKiB(val); tst != res {
t.Errorf("data not equal: %v: %v\n tst=<%s>\n got <%s>\n",
i, val, res, tst)
}
}
}
45 changes: 0 additions & 45 deletions node.go
Original file line number Diff line number Diff line change
Expand Up @@ -352,48 +352,3 @@ func (node *Node) print(indent string, opts *Options) {
nnode.print(indent+add, opts)
}
}

const (
_ = iota // ignore first value by assigning to blank identifier
KB int64 = 1 << (10 * iota)
MB
GB
TB
PB
EB
)

// Convert bytes to human readable string. Like a 2 MB, 64.2 KB, 52 B
func formatBytes(i int64) (result string) {
var n float64
sFmt, eFmt := "%.01f", ""
switch {
case i > EB:
eFmt = "E"
n = float64(i) / float64(EB)
case i > PB:
eFmt = "P"
n = float64(i) / float64(PB)
case i > TB:
eFmt = "T"
n = float64(i) / float64(TB)
case i > GB:
eFmt = "G"
n = float64(i) / float64(GB)
case i > MB:
eFmt = "M"
n = float64(i) / float64(MB)
case i > KB:
eFmt = "K"
n = float64(i) / float64(KB)
default:
sFmt = "%.0f"
n = float64(i)
}
if eFmt != "" && n >= 10 {
sFmt = "%.0f"
}
result = fmt.Sprintf(sFmt+eFmt, n)
result = strings.Trim(result, " ")
return
}
4 changes: 2 additions & 2 deletions node_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -275,8 +275,8 @@ c
`, 0, 3},
{"unit-size", &Options{Fs: fs, OutFile: out, UnitSize: true}, `[ 12K] root
├── [1.5K] a
├── [9.8K] b
└── [1000] c
├── [ 10K] b
└── [1.0K] c
`, 0, 3},
{"show-gid", &Options{Fs: fs, OutFile: out, ShowGid: true}, `root
├── [1 ] a
Expand Down