1//  Copyright (c) 2014 Couchbase, Inc.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// 		http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package collector
16
17import "github.com/blevesearch/bleve/search"
18
19type collectStoreSlice struct {
20	slice   search.DocumentMatchCollection
21	compare collectorCompare
22}
23
24func newStoreSlice(cap int, compare collectorCompare) *collectStoreSlice {
25	rv := &collectStoreSlice{
26		slice:   make(search.DocumentMatchCollection, 0, cap),
27		compare: compare,
28	}
29	return rv
30}
31
32func (c *collectStoreSlice) AddNotExceedingSize(doc *search.DocumentMatch,
33	size int) *search.DocumentMatch {
34	c.add(doc)
35	if c.len() > size {
36		return c.removeLast()
37	}
38	return nil
39}
40
41func (c *collectStoreSlice) add(doc *search.DocumentMatch) {
42	// find where to insert, starting at end (lowest)
43	i := len(c.slice)
44	for ; i > 0; i-- {
45		cmp := c.compare(doc, c.slice[i-1])
46		if cmp >= 0 {
47			break
48		}
49	}
50	// insert at i
51	c.slice = append(c.slice, nil)
52	copy(c.slice[i+1:], c.slice[i:])
53	c.slice[i] = doc
54}
55
56func (c *collectStoreSlice) removeLast() *search.DocumentMatch {
57	var rv *search.DocumentMatch
58	rv, c.slice = c.slice[len(c.slice)-1], c.slice[:len(c.slice)-1]
59	return rv
60}
61
62func (c *collectStoreSlice) Final(skip int, fixup collectorFixup) (search.DocumentMatchCollection, error) {
63	for i := skip; i < len(c.slice); i++ {
64		err := fixup(c.slice[i])
65		if err != nil {
66			return nil, err
67		}
68	}
69	if skip <= len(c.slice) {
70		return c.slice[skip:], nil
71	}
72	return search.DocumentMatchCollection{}, nil
73}
74
75func (c *collectStoreSlice) len() int {
76	return len(c.slice)
77}
78