mirror of
https://github.com/featurebasedb/featurebase.git
synced 2026-09-07 09:05:55 +00:00
Merge branch 'umbel-perf-improvements' of https://github.com/pilosa/pilosa into umbel-perf-improvements
This commit is contained in:
commit
6cd29a129d
2 changed files with 39 additions and 26 deletions
18
cache.go
18
cache.go
|
|
@ -241,6 +241,24 @@ func (p Pairs) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
|
|||
func (p Pairs) Len() int { return len(p) }
|
||||
func (p Pairs) Less(i, j int) bool { return p[i].Count > p[j].Count }
|
||||
|
||||
type PairHeap struct {
|
||||
Pairs
|
||||
}
|
||||
|
||||
func (h *Pairs) Push(x interface{}) {
|
||||
// Push and Pop use pointer receivers because they modify the slice's length,
|
||||
// not just its contents.
|
||||
*h = append(*h, x.(Pair))
|
||||
}
|
||||
|
||||
func (h *Pairs) Pop() interface{} {
|
||||
old := *h
|
||||
n := len(old)
|
||||
x := old[n-1]
|
||||
*h = old[0 : n-1]
|
||||
return x
|
||||
}
|
||||
|
||||
// Add merges other into p and returns a new slice.
|
||||
func (p Pairs) Add(other []Pair) []Pair {
|
||||
// Create lookup of key/counts.
|
||||
|
|
|
|||
47
fragment.go
47
fragment.go
|
|
@ -4,6 +4,7 @@ import (
|
|||
"archive/tar"
|
||||
"bufio"
|
||||
"bytes"
|
||||
"container/heap"
|
||||
"context"
|
||||
"crypto/sha1"
|
||||
"encoding/binary"
|
||||
|
|
@ -28,7 +29,7 @@ import (
|
|||
|
||||
const (
|
||||
// SliceWidth is the number of profile IDs in a slice.
|
||||
//SliceWidth = 1048576
|
||||
// SliceWidth = 1048576
|
||||
SliceWidth = 262144
|
||||
|
||||
// SnapshotExt is the file extension used for an in-process snapshot.
|
||||
|
|
@ -173,7 +174,6 @@ func (f *Fragment) Open() error {
|
|||
|
||||
// openStorage opens the storage bitmap.
|
||||
func (f *Fragment) openStorage() error {
|
||||
//f.logger().Printf("Open Storage %s/%s/%d", f.db, f.frame, f.slice)
|
||||
// Create a roaring bitmap to serve as storage for the slice.
|
||||
f.storage = roaring.NewBitmap()
|
||||
|
||||
|
|
@ -494,7 +494,8 @@ func (f *Fragment) Top(opt TopOptions) ([]Pair, error) {
|
|||
}
|
||||
|
||||
// Iterate over rankings and add to results until we have enough.
|
||||
results := make([]Pair, 0, opt.N)
|
||||
//results := make(PairHeap, 0, opt.N)
|
||||
results := &PairHeap{}
|
||||
for _, pair := range pairs {
|
||||
bitmapID, n := pair.ID, pair.Count
|
||||
|
||||
|
|
@ -518,7 +519,7 @@ func (f *Fragment) Top(opt TopOptions) ([]Pair, error) {
|
|||
}
|
||||
|
||||
// The initial n pairs should simply be added to the results.
|
||||
if opt.N == 0 || len(results) < opt.N {
|
||||
if opt.N == 0 || results.Len() < opt.N {
|
||||
// Calculate count and append.
|
||||
count := n
|
||||
if opt.Src != nil {
|
||||
|
|
@ -527,23 +528,26 @@ func (f *Fragment) Top(opt TopOptions) ([]Pair, error) {
|
|||
if count == 0 {
|
||||
continue
|
||||
}
|
||||
results = append(results, Pair{Key: bitmapID, Count: count})
|
||||
//results = append(results, Pair{Key: bitmapID, Count: count})
|
||||
heap.Push(results, Pair{Key: bitmapID, Count: count})
|
||||
|
||||
// If we reach the requested number of pairs and we are not computing
|
||||
// intersections then simply exit. If we are intersecting then sort
|
||||
// and then only keep pairs that are higher than the lowest count.
|
||||
if opt.N > 0 && len(results) == opt.N {
|
||||
if opt.N > 0 && results.Len() == opt.N {
|
||||
if opt.Src == nil {
|
||||
break
|
||||
}
|
||||
sort.Sort(Pairs(results))
|
||||
// sort.Sort(Pairs(results))
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
// Retrieve the lowest count we have.
|
||||
// If it's too low then don't try finding anymore pairs.
|
||||
threshold := results[len(results)-1].Count
|
||||
//threshold := results[len(results)-1].Count
|
||||
|
||||
threshold := results.Pairs[0].Count
|
||||
if threshold < MinThreshold {
|
||||
break
|
||||
}
|
||||
|
|
@ -556,34 +560,25 @@ func (f *Fragment) Top(opt TopOptions) ([]Pair, error) {
|
|||
|
||||
// Calculate the intersecting bit count and skip if it's below our
|
||||
// last bitmap in our current result set.
|
||||
|
||||
count := opt.Src.IntersectionCount(f.Bitmap(bitmapID))
|
||||
if count < threshold {
|
||||
continue
|
||||
}
|
||||
|
||||
// Swap out the last pair for this new count.
|
||||
results[len(results)-1] = Pair{Key: bitmapID, Count: count}
|
||||
|
||||
// If it's count is also higher than the second to last item then resort.
|
||||
if len(results) >= 2 && count > results[len(results)-2].Count {
|
||||
sort.Sort(Pairs(results))
|
||||
}
|
||||
heap.Push(results, Pair{Key: bitmapID, Count: count})
|
||||
}
|
||||
|
||||
sort.Sort(Pairs(results))
|
||||
return results, nil
|
||||
}
|
||||
|
||||
func debugDumpPairs(pairs []BitmapPair) {
|
||||
fmt.Println("=====Start")
|
||||
for i, pair := range pairs {
|
||||
fmt.Println(i, pair.ID, pair.Count)
|
||||
r := make(Pairs, results.Len(), results.Len())
|
||||
x := results.Len()
|
||||
i := 1
|
||||
for results.Len() > 0 {
|
||||
r[x-i] = heap.Pop(results).(Pair)
|
||||
i++
|
||||
}
|
||||
fmt.Println("=====Stop")
|
||||
return r, nil
|
||||
}
|
||||
|
||||
func (f *Fragment) topBitmapPairs(bitmapIDs []uint64) []BitmapPair {
|
||||
//fmt.Println("DEBUG topBitmapPairs")
|
||||
// If no specific bitmaps are requested, retrieve top bitmaps.
|
||||
if len(bitmapIDs) == 0 {
|
||||
f.mu.Lock()
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue