add both filters into one func
This commit is contained in:
parent
1fe7a624c4
commit
35e9a37187
@ -383,6 +383,80 @@ func (d *Details) FilterEmptyContainers() *Details {
|
||||
}
|
||||
}
|
||||
|
||||
// FilterEmptyContainers returns a new Details struct all empty (ie: containing no
|
||||
// items) stripped out. If meta files have not been filtered out already, they
|
||||
// will continue to count as a "populated" container.
|
||||
func (d *Details) FilterBoth() *Details {
|
||||
type entCount struct {
|
||||
ent DetailsEntry
|
||||
itemCount int
|
||||
}
|
||||
|
||||
var (
|
||||
// shortRef: entCount
|
||||
srec = map[string]entCount{}
|
||||
items = []DetailsEntry{}
|
||||
)
|
||||
|
||||
// split the entries into items and folders.
|
||||
// folders are stored in a map by their shortRef for lookup.
|
||||
for _, ent := range d.Entries {
|
||||
if ent.isMetaFile() {
|
||||
continue
|
||||
}
|
||||
|
||||
if ent.Folder == nil {
|
||||
items = append(items, ent)
|
||||
} else {
|
||||
srec[ent.ShortRef] = entCount{ent, 0}
|
||||
}
|
||||
}
|
||||
|
||||
// for every item, add a count to the owning folder.
|
||||
// this assumes item parentRef == folder shortRef.
|
||||
for _, ent := range items {
|
||||
if len(ent.ParentRef) == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
ec := srec[ent.ParentRef]
|
||||
ec.itemCount++
|
||||
srec[ent.ParentRef] = ec
|
||||
|
||||
// to maintain a hierarchical count so that we don't
|
||||
// slice parent folders, this loop walks the tree upward
|
||||
// by parent ref, adding one count to each parent up
|
||||
// to the root.
|
||||
parentRef := ec.ent.ParentRef
|
||||
parentCount := 0
|
||||
|
||||
for len(parentRef) > 0 && parentCount == 0 {
|
||||
ec := srec[parentRef]
|
||||
|
||||
// minor optimization: if the parentCount is already
|
||||
// >zero, then all of its parents are guaranteed >zero.
|
||||
parentCount = ec.itemCount
|
||||
|
||||
ec.itemCount++
|
||||
srec[parentRef] = ec
|
||||
|
||||
parentRef = ec.ent.ParentRef
|
||||
}
|
||||
}
|
||||
|
||||
// walk the map of folder entries; every folder with one or more
|
||||
// items gets added back to the items slice to be returned.
|
||||
for _, ec := range srec {
|
||||
if ec.itemCount > 0 {
|
||||
items = append(items, ec.ent)
|
||||
}
|
||||
}
|
||||
|
||||
return &Details{
|
||||
DetailsModel: DetailsModel{items},
|
||||
}
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------
|
||||
// Entry
|
||||
// --------------------------------------------------------------------------------
|
||||
|
||||
@ -106,6 +106,9 @@ var result *Details
|
||||
func BenchmarkDetailsFiltering_512_both(b *testing.B) { benchmarkBoth(details512k, b) }
|
||||
func BenchmarkDetailsFiltering_256_both(b *testing.B) { benchmarkBoth(details256k, b) }
|
||||
func BenchmarkDetailsFiltering_102_both(b *testing.B) { benchmarkBoth(details102k, b) }
|
||||
func BenchmarkDetailsFiltering_512_each(b *testing.B) { benchmarkEach(details512k, b) }
|
||||
func BenchmarkDetailsFiltering_256_each(b *testing.B) { benchmarkEach(details256k, b) }
|
||||
func BenchmarkDetailsFiltering_102_each(b *testing.B) { benchmarkEach(details102k, b) }
|
||||
func BenchmarkDetailsFiltering_512_meta(b *testing.B) { benchmarkMeta(details512k, b) }
|
||||
func BenchmarkDetailsFiltering_256_meta(b *testing.B) { benchmarkMeta(details256k, b) }
|
||||
func BenchmarkDetailsFiltering_102_meta(b *testing.B) { benchmarkMeta(details102k, b) }
|
||||
@ -116,6 +119,16 @@ func BenchmarkDetailsFiltering_102_container(b *testing.B) { benchmarkContainer(
|
||||
func benchmarkBoth(d *Details, b *testing.B) {
|
||||
var d2 *Details
|
||||
|
||||
for n := 0; n < b.N; n++ {
|
||||
d2 = d.FilterBoth()
|
||||
}
|
||||
|
||||
result = d2
|
||||
}
|
||||
|
||||
func benchmarkEach(d *Details, b *testing.B) {
|
||||
var d2 *Details
|
||||
|
||||
for n := 0; n < b.N; n++ {
|
||||
d2 = d.FilterMetaFiles().FilterEmptyContainers()
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user