func (q *NormalQuery) findFromDynamicSort() Result { found := 0 limit := q.limit conditionCount := q.conditionCount result := <-q.db.sortedResults for _, id := range q.dynamicSort { keyd := key.Type(id) for j := 0; j < conditionCount; j++ { if q.conditions[j].Contains(keyd) == false { goto nomatchdesc } } result.total++ if result.total > q.offset { if found < limit { result.add(keyd) found++ } else if result.total >= q.upto { break } } nomatchdesc: } result.hasMore = result.total > (q.offset + q.limit) if q.includeTotal == false { result.total = -1 } return result } // Walk the sort index and filter out results func (q *NormalQuery) findBySort() Result { found := 0 limit := q.limit conditionCount := q.conditionCount var iterator indexes.Iterator result := <-q.db.sortedResults if q.desc { iterator = q.sort.Backwards() } else { iterator = q.sort.Forwards() } if q.sortCondition != nil { iterator.Range(q.sortCondition.Range()).Offset(0) } for id := iterator.Current(); id != key.NULL; id = iterator.Next() { for j := 0; j < conditionCount; j++ { if q.conditions[j].Contains(id) == false { goto nomatchdesc } } result.total++ if result.total > q.offset { if found < limit { result.add(id) found++ } else if result.total >= q.upto { break } } nomatchdesc: } iterator.Close() result.hasMore = result.total > (q.offset + q.limit) if q.includeTotal == false { result.total = -1 } return result } // Filter by indexes, then sort. Ideal when the smallest index is quite a bit // smaller than the sort index func (q *NormalQuery) findByIndex() Result { conditionCount := q.conditionCount result := <-q.db.unsortedResults var sort RankedContainer if q.sortCondition != nil { q.sortCondition.On(q.sort) sort = q.sortCondition } else { sort = q.sort } iterator := q.conditions[0].Iterator() defer iterator.Close() for id := iterator.Current(); id != key.NULL; id = iterator.Next() { for j := 1; j < conditionCount; j++ { if q.conditions[j].Contains(id) == false { goto nomatch } } if score, exists := sort.Score(id); exists { result.add(id, score) } nomatch: } return result.finalize(q) } // Reset the query and release it back into the pool func (q *NormalQuery) reset() { q.sort = nil q.offset = 0 q.cache = true q.desc = false q.ranged = false q.dynamicSort = nil q.conditionCount = 0 q.sortCondition = nil q.includeTotal = false q.limit = q.db.defaultLimit q.upto = q.db.defaultLimit + 1 q.db.queryPool <- q }
// An optimized code path for when no index is provided (just walking through // a sort index) func (q *NormalQuery) findWithNoIndexes() Result { limit := q.limit result := <-q.db.sortedResults result.total = -1 var iterator indexes.Iterator if q.desc { iterator = q.sort.Backwards() } else { iterator = q.sort.Forwards() } if q.sortCondition != nil { iterator.Range(q.sortCondition.Range()) } iterator.Offset(q.offset) id := iterator.Current() for ; id != key.NULL; id = iterator.Next() { if result.add(id) == limit { break } } result.hasMore = id != key.NULL && iterator.Next() != key.NULL iterator.Close() if q.includeTotal { result.total = q.sortLength if result.total > q.upto { result.total = q.upto } } return result }