Skip to content

Commit 00a409b

Browse files
committed
Separate out a counts package
1 parent 8d1c961 commit 00a409b

6 files changed

Lines changed: 194 additions & 175 deletions

File tree

sizes/count.go renamed to counts/counts.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package sizes
1+
package counts
22

33
import (
44
"math"

counts/human.go

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
package counts
2+
3+
import (
4+
"fmt"
5+
"math"
6+
)
7+
8+
type Prefix struct {
9+
Name string
10+
Multiplier uint64
11+
}
12+
13+
type Humaner interface {
14+
Human([]Prefix, string) (string, string)
15+
ToUint64() uint64
16+
}
17+
18+
var MetricPrefixes []Prefix
19+
20+
func init() {
21+
MetricPrefixes = []Prefix{
22+
{"", 1},
23+
{"k", 1e3},
24+
{"M", 1e6},
25+
{"G", 1e9},
26+
{"T", 1e12},
27+
{"P", 1e15},
28+
}
29+
}
30+
31+
var BinaryPrefixes []Prefix
32+
33+
func init() {
34+
BinaryPrefixes = []Prefix{
35+
{"", 1 << (10 * 0)},
36+
{"Ki", 1 << (10 * 1)},
37+
{"Mi", 1 << (10 * 2)},
38+
{"Gi", 1 << (10 * 3)},
39+
{"Ti", 1 << (10 * 4)},
40+
{"Pi", 1 << (10 * 5)},
41+
}
42+
}
43+
44+
// Format values, aligned, in `len(unit) + 10` or fewer characters
45+
// (except for extremely large numbers).
46+
func Human(n uint64, prefixes []Prefix, unit string) (string, string) {
47+
prefix := prefixes[0]
48+
wholePart := n
49+
for _, p := range prefixes {
50+
w := n / p.Multiplier
51+
if w >= 1 {
52+
wholePart = w
53+
prefix = p
54+
}
55+
}
56+
57+
if prefix.Multiplier == 1 {
58+
return fmt.Sprintf("%d", n), unit
59+
} else {
60+
mantissa := float64(n) / float64(prefix.Multiplier)
61+
var format string
62+
63+
if wholePart >= 100 {
64+
// `mantissa` can actually be up to 1023.999.
65+
format = "%.0f"
66+
} else if wholePart >= 10 {
67+
format = "%.1f"
68+
} else {
69+
format = "%.2f"
70+
}
71+
return fmt.Sprintf(format, mantissa), prefix.Name + unit
72+
}
73+
}
74+
75+
func (n Count32) Human(prefixes []Prefix, unit string) (string, string) {
76+
if n == math.MaxUint32 {
77+
return "∞", ""
78+
} else {
79+
return Human(uint64(n), prefixes, unit)
80+
}
81+
}
82+
83+
func (n Count64) Human(prefixes []Prefix, unit string) (string, string) {
84+
if n == math.MaxUint64 {
85+
return "∞", unit
86+
} else {
87+
return Human(uint64(n), prefixes, unit)
88+
}
89+
}

sizes/git.go

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ import (
1212
"path/filepath"
1313
"strconv"
1414
"strings"
15+
16+
"github.com/github/git-sizer/counts"
1517
)
1618

1719
// The type of an object ("blob", "tree", "commit", "tag", "missing").
@@ -97,7 +99,7 @@ func (repo *Repository) Close() error {
9799
type Reference struct {
98100
Refname string
99101
ObjectType ObjectType
100-
ObjectSize Count32
102+
ObjectSize counts.Count32
101103
Oid Oid
102104
}
103105

@@ -162,7 +164,7 @@ func (iter *ReferenceIter) Next() (Reference, bool, error) {
162164
return Reference{
163165
Refname: refname,
164166
ObjectType: objectType,
165-
ObjectSize: Count32(objectSize),
167+
ObjectSize: counts.Count32(objectSize),
166168
Oid: oid,
167169
}, true, nil
168170
}
@@ -215,7 +217,7 @@ func (repo *Repository) NewBatchObjectIter() (*BatchObjectIter, io.WriteCloser,
215217
}, in, nil
216218
}
217219

218-
func (iter *BatchObjectIter) Next() (Oid, ObjectType, Count32, []byte, error) {
220+
func (iter *BatchObjectIter) Next() (Oid, ObjectType, counts.Count32, []byte, error) {
219221
header, err := iter.f.ReadString('\n')
220222
if err != nil {
221223
return Oid{}, "", 0, nil, err
@@ -321,7 +323,7 @@ func NotFilter(filter ReferenceFilter) ReferenceFilter {
321323

322324
// Parse a `cat-file --batch[-check]` output header line (including
323325
// the trailing LF). `spec`, if not "", is used in error messages.
324-
func parseBatchHeader(spec string, header string) (Oid, ObjectType, Count32, error) {
326+
func parseBatchHeader(spec string, header string) (Oid, ObjectType, counts.Count32, error) {
325327
header = header[:len(header)-1]
326328
words := strings.Split(header, " ")
327329
if words[len(words)-1] == "missing" {
@@ -340,7 +342,7 @@ func parseBatchHeader(spec string, header string) (Oid, ObjectType, Count32, err
340342
if err != nil {
341343
return Oid{}, "missing", 0, err
342344
}
343-
return oid, ObjectType(words[1]), NewCount32(size), nil
345+
return oid, ObjectType(words[1]), counts.NewCount32(size), nil
344346
}
345347

346348
type ObjectIter struct {
@@ -443,7 +445,7 @@ func (repo *Repository) NewObjectIter(args ...string) (
443445
}
444446

445447
// Next returns the next object, or EOF when done.
446-
func (l *ObjectIter) Next() (Oid, ObjectType, Count32, error) {
448+
func (l *ObjectIter) Next() (Oid, ObjectType, counts.Count32, error) {
447449
line, err := l.f.ReadString('\n')
448450
if err != nil {
449451
return Oid{}, "", 0, err
@@ -508,7 +510,7 @@ func (iter *ObjectHeaderIter) Next() (string, string, error) {
508510
}
509511

510512
type Commit struct {
511-
Size Count32
513+
Size counts.Count32
512514
Parents []Oid
513515
Tree Oid
514516
}
@@ -548,7 +550,7 @@ func ParseCommit(oid Oid, data []byte) (*Commit, error) {
548550
return nil, fmt.Errorf("no tree found in commit %s", oid)
549551
}
550552
return &Commit{
551-
Size: NewCount32(uint64(len(data))),
553+
Size: counts.NewCount32(uint64(len(data))),
552554
Parents: parents,
553555
Tree: tree,
554556
}, nil
@@ -619,7 +621,7 @@ func (iter *TreeIter) NextEntry() (TreeEntry, bool, error) {
619621
}
620622

621623
type Tag struct {
622-
Size Count32
624+
Size counts.Count32
623625
Referent Oid
624626
ReferentType ObjectType
625627
}
@@ -663,7 +665,7 @@ func ParseTag(oid Oid, data []byte) (*Tag, error) {
663665
return nil, fmt.Errorf("no type found in tag %s", oid)
664666
}
665667
return &Tag{
666-
Size: NewCount32(uint64(len(data))),
668+
Size: counts.NewCount32(uint64(len(data))),
667669
Referent: referent,
668670
ReferentType: referentType,
669671
}, nil

sizes/graph.go

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"sync"
99
"time"
1010

11+
"github.com/github/git-sizer/counts"
1112
"github.com/github/git-sizer/meter"
1213
)
1314

@@ -82,7 +83,7 @@ func ScanRepositoryUsingGraph(
8283

8384
type ObjectHeader struct {
8485
oid Oid
85-
objectSize Count32
86+
objectSize counts.Count32
8687
}
8788

8889
type CommitHeader struct {
@@ -399,7 +400,7 @@ func (g *Graph) HistorySize() HistorySize {
399400
}
400401

401402
// Record that the specified `oid` is a blob with the specified size.
402-
func (g *Graph) RegisterBlob(oid Oid, objectSize Count32) {
403+
func (g *Graph) RegisterBlob(oid Oid, objectSize counts.Count32) {
403404
size := BlobSize{Size: objectSize}
404405
// There are no listeners. Since this is a blob, we know all that
405406
// we need to know about it. So skip the record and just fill in
@@ -485,7 +486,9 @@ func (g *Graph) RegisterTree(oid Oid, tree *Tree) error {
485486
return record.initialize(g, oid, tree)
486487
}
487488

488-
func (g *Graph) finalizeTreeSize(oid Oid, size TreeSize, objectSize Count32, treeEntries Count32) {
489+
func (g *Graph) finalizeTreeSize(
490+
oid Oid, size TreeSize, objectSize counts.Count32, treeEntries counts.Count32,
491+
) {
489492
g.treeLock.Lock()
490493
g.treeSizes[oid] = size
491494
delete(g.treeRecords, oid)
@@ -504,11 +507,11 @@ type treeRecord struct {
504507

505508
// The size of this object, in bytes. Initialized iff pending !=
506509
// -1.
507-
objectSize Count32
510+
objectSize counts.Count32
508511

509512
// The number of entries directly in this tree. Initialized iff
510513
// pending != -1.
511-
entryCount Count32
514+
entryCount counts.Count32
512515

513516
// The size of the items we know so far:
514517
size TreeSize
@@ -537,7 +540,7 @@ func (r *treeRecord) initialize(g *Graph, oid Oid, tree *Tree) error {
537540
r.lock.Lock()
538541
defer r.lock.Unlock()
539542

540-
r.objectSize = NewCount32(uint64(len(tree.data)))
543+
r.objectSize = counts.NewCount32(uint64(len(tree.data)))
541544
r.pending = 0
542545

543546
iter := tree.Iter()
@@ -642,7 +645,7 @@ func (g *Graph) RegisterCommit(oid Oid, commit *Commit) {
642645
g.commitLock.Unlock()
643646

644647
// The number of direct parents of this commit.
645-
parentCount := NewCount32(uint64(len(commit.Parents)))
648+
parentCount := counts.NewCount32(uint64(len(commit.Parents)))
646649

647650
// The size of the items we know so far:
648651
size := CommitSize{}
@@ -711,7 +714,7 @@ func (g *Graph) RegisterTag(oid Oid, tag *Tag) {
711714
record.initialize(g, oid, tag)
712715
}
713716

714-
func (g *Graph) finalizeTagSize(oid Oid, size TagSize, objectSize Count32) {
717+
func (g *Graph) finalizeTagSize(oid Oid, size TagSize, objectSize counts.Count32) {
715718
g.tagLock.Lock()
716719
g.tagSizes[oid] = size
717720
delete(g.tagRecords, oid)
@@ -729,7 +732,7 @@ type tagRecord struct {
729732
lock sync.Mutex
730733

731734
// The size of this commit object in bytes.
732-
objectSize Count32
735+
objectSize counts.Count32
733736

734737
// The size of the items we know so far:
735738
size TagSize

0 commit comments

Comments
 (0)