Example #1
0
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
}
Example #2
0
// 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
}