diff --git a/index/brand.go b/index/brand.go index 4474f7489..0a488904d 100644 --- a/index/brand.go +++ b/index/brand.go @@ -191,8 +191,7 @@ func (self *Brand) Store(bitmap_id uint64, bm IBitmap, filter uint64) { self.storage.Store(int64(bitmap_id), self.db, self.frame, self.slice, filter, bm.(*Bitmap)) self.cache_it(bm, bitmap_id, filter) } - -func (self *Brand) TopN(src_bitmap IBitmap, n int, categories []uint64) []Pair { +func (self *Brand) checkRank() { if len(self.rankings) < 50 { self.Rank() } else if self.rank_count > 0 { @@ -201,7 +200,9 @@ func (self *Brand) TopN(src_bitmap IBitmap, n int, categories []uint64) []Pair { self.Rank() } } - +} +func (self *Brand) TopN(src_bitmap IBitmap, n int, categories []uint64) []Pair { + self.checkRank() is := NewIntSet() for _, v := range categories { is.Add(v) @@ -219,6 +220,36 @@ func dump(r RankList, n int) { } } } + +func (self *Brand) TopNAll(n int, categories []uint64) []Pair { + + self.checkRank() + results := make([]Pair, n) + + category := NewIntSet() + needCat := false + for _, v := range categories { + category.Add(v) + needCat = true + + } + count := 0 + for _, pair := range self.rankings { + if needCat { + if !category.Contains(pair.category) { + continue + } + } + + if count > n { + break + } + results[count] = Pair{pair.Key, pair.Count} + count++ + } + return results[:count] +} + func (self *Brand) TopNCat(src_bitmap IBitmap, n int, category *IntSet) []Pair { breakout := 500 var ( diff --git a/index/commands.go b/index/commands.go index a999c3ff8..e6c953c14 100644 --- a/index/commands.go +++ b/index/commands.go @@ -316,3 +316,17 @@ func (self *CmdTopFill) Execute(f *Fragment) Calculation { } return result } + +type CmdTopNAll struct { + *Responder + n int + categories []uint64 +} + +func NewTopNAll(n int, categories []uint64) *CmdTopNAll { + return &CmdTopNAll{NewResponder("TopNAll"), n, categories} +} + +func (self *CmdTopNAll) Execute(f *Fragment) Calculation { + return f.TopNAll(self.n, self.categories) +} diff --git a/index/fragment_container.go b/index/fragment_container.go index 6acb5e9e9..702414e5d 100644 --- a/index/fragment_container.go +++ b/index/fragment_container.go @@ -173,6 +173,18 @@ func (self *FragmentContainer) TopN(frag_id util.SUUID, bh BitmapHandle, n int, } return nil, errors.New(fmt.Sprintf("Fragment not found:%s", util.SUUID_to_Hex(frag_id))) } + +func (self *FragmentContainer) TopNAll(frag_id util.SUUID, n int, categories []uint64) ([]Pair, error) { + if fragment, found := self.GetFragment(frag_id); found { + request := NewTopNAll(n, categories) + fragment.requestChan <- request + result := request.Response() + util.SendTimer("fragmant_container_TopNAll", result.exec_time.Nanoseconds()) + return result.answer.([]Pair), nil + } + return nil, errors.New(fmt.Sprintf("Fragment not found:%s", util.SUUID_to_Hex(frag_id))) +} + func (self *FragmentContainer) TopFillBatch(args []FillArgs) ([]Pair, error) { //should probaly make this concurrent but then all hell breaks lose results := make(map[uint64]uint64) @@ -285,6 +297,7 @@ type Pilosa interface { Get(id uint64) IBitmap SetBit(id uint64, bit_pos uint64, filter uint64) bool TopN(b IBitmap, n int, categories []uint64) []Pair + TopNAll(n int, categories []uint64) []Pair Clear() bool Store(bitmap_id uint64, bm IBitmap, filter uint64) Stats() interface{} @@ -347,6 +360,9 @@ func (self *Fragment) getBitmap(bitmap BitmapHandle) (IBitmap, bool) { func (self *Fragment) exists(bitmap_id uint64) bool { return self.impl.Exists(bitmap_id) } +func (self *Fragment) TopNAll(n int, categories []uint64) []Pair { + return self.impl.TopNAll(n, categories) +} func (self *Fragment) TopN(bitmap BitmapHandle, n int, categories []uint64) []Pair { diff --git a/index/general.go b/index/general.go index 65b1dd1cb..96485db3b 100644 --- a/index/general.go +++ b/index/general.go @@ -138,3 +138,20 @@ func (self *General) Load(requestChan chan Command, f *Fragment) { request.Response() } } + +func (self *General) TopNAll(n int, categories []uint64) []Pair { + + results := make([]Pair, n) + + count := 0 + for k, _ := range self.keys { + + if count > n { + break + } + bm := self.Get(k) + results[count] = Pair{k, bm.Count()} + count++ + } + return results[:count] +}