add both filters into one func

This commit is contained in:
ryanfkeepers 2023-02-28 15:28:24 -07:00
parent 1fe7a624c4
commit 35e9a37187
2 changed files with 87 additions and 0 deletions

View File

@ -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
// --------------------------------------------------------------------------------

View File

@ -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()
}