@ -33,7 +33,7 @@ func (p *memPostings) get(t term) Postings {
if l == nil {
return emptyPostings
}
return & listPostings { list : l , idx : - 1 }
return newListPostings ( l )
}
// add adds a document to the index. The caller has to ensure that no
@ -70,18 +70,13 @@ func (e errPostings) Seek(uint32) bool { return false }
func ( e errPostings ) At ( ) uint32 { return 0 }
func ( e errPostings ) Err ( ) error { return e . err }
func expandPostings ( p Postings ) ( res [ ] uint32 , err error ) {
for p . Next ( ) {
res = append ( res , p . At ( ) )
}
return res , p . Err ( )
}
var emptyPostings = errPostings { }
// Intersect returns a new postings list over the intersection of the
// input postings.
func Intersect ( its ... Postings ) Postings {
if len ( its ) == 0 {
return e rrPostings{ err : nil }
return e mptyPostings
}
a := its [ 0 ]
@ -91,8 +86,6 @@ func Intersect(its ...Postings) Postings {
return a
}
var emptyPostings = errPostings { }
type intersectPostings struct {
a , b Postings
aok , bok bool
@ -100,41 +93,44 @@ type intersectPostings struct {
}
func newIntersectPostings ( a , b Postings ) * intersectPostings {
it := & intersectPostings { a : a , b : b }
it . aok = it . a . Next ( )
it . bok = it . b . Next ( )
return it
return & intersectPostings { a : a , b : b }
}
func ( it * intersectPostings ) At ( ) uint32 {
return it . cur
}
func ( it * intersectPostings ) Next( ) bool {
func ( it * intersectPostings ) do Next( id uint32 ) bool {
for {
if ! it . aok || ! it . bok {
if ! it . b. Seek ( id ) {
return false
}
av , bv := it . a . At ( ) , it . b . At ( )
if av < bv {
it . aok = it . a . Seek ( bv )
} else if bv < av {
it . bok = it . b . Seek ( av )
} else {
it . cur = av
it . aok = it . a . Next ( )
it . bok = it . b . Next ( )
return true
if vb := it . b . At ( ) ; vb != id {
if ! it . a . Seek ( vb ) {
return false
}
id = it . a . At ( )
if vb != id {
continue
}
}
it . cur = id
return true
}
}
func ( it * intersectPostings ) Next ( ) bool {
if ! it . a . Next ( ) {
return false
}
return it . doNext ( it . a . At ( ) )
}
func ( it * intersectPostings ) Seek ( id uint32 ) bool {
it . aok = it . a . Seek ( id )
it . bok = it . b . Seek ( id )
return it . Next ( )
if ! it . a . Seek ( id ) {
return false
}
return it . doNext ( it . a . At ( ) )
}
func ( it * intersectPostings ) Err ( ) error {
@ -158,17 +154,14 @@ func Merge(its ...Postings) Postings {
}
type mergedPostings struct {
a , b Postings
aok , bok bool
cur uint32
a , b Postings
initialized bool
aok , bok bool
cur uint32
}
func newMergedPostings ( a , b Postings ) * mergedPostings {
it := & mergedPostings { a : a , b : b }
it . aok = it . a . Next ( )
it . bok = it . b . Next ( )
return it
return & mergedPostings { a : a , b : b }
}
func ( it * mergedPostings ) At ( ) uint32 {
@ -176,6 +169,12 @@ func (it *mergedPostings) At() uint32 {
}
func ( it * mergedPostings ) Next ( ) bool {
if ! it . initialized {
it . aok = it . a . Next ( )
it . bok = it . b . Next ( )
it . initialized = true
}
if ! it . aok && ! it . bok {
return false
}
@ -196,25 +195,31 @@ func (it *mergedPostings) Next() bool {
if acur < bcur {
it . cur = acur
it . aok = it . a . Next ( )
return true
}
if bcur < acur {
} else if acur > bcur {
it . cur = bcur
it . bok = it . b . Next ( )
return true
} else {
it . cur = acur
it . aok = it . a . Next ( )
it . bok = it . b . Next ( )
}
it . cur = acur
it . aok = it . a . Next ( )
it . bok = it . b . Next ( )
return true
}
func ( it * mergedPostings ) Seek ( id uint32 ) bool {
it . aok = it . a . Seek ( id )
it . bok = it . b . Seek ( id )
return it . Next ( )
it . initialized = true
acur , bcur := it . a . At ( ) , it . b . At ( )
if acur < bcur {
it . cur = acur
} else if acur > bcur {
it . cur = bcur
} else {
it . cur = acur
it . bok = it . b . Next ( )
}
return it . aok && it . bok
}
func ( it * mergedPostings ) Err ( ) error {
@ -227,28 +232,38 @@ func (it *mergedPostings) Err() error {
// listPostings implements the Postings interface over a plain list.
type listPostings struct {
list [ ] uint32
idx int
cur uint32
}
func newListPostings ( list [ ] uint32 ) * listPostings {
return & listPostings { list : list , idx : - 1 }
return & listPostings { list : list }
}
func ( it * listPostings ) At ( ) uint32 {
return it . list[ it . idx ]
return it . cur
}
func ( it * listPostings ) Next ( ) bool {
it . idx ++
return it . idx < len ( it . list )
if len ( it . list ) > 0 {
it . cur = it . list [ 0 ]
it . list = it . list [ 1 : ]
return true
}
return false
}
func ( it * listPostings ) Seek ( x uint32 ) bool {
// Do binary search between current position and end.
i t. idx + = sort . Search ( len ( it . list ) - it . idx , func ( i int ) bool {
return it . list [ i + it . idx ] >= x
i : = sort . Search ( len ( it . list ) , func ( i int ) bool {
return it . list [ i ] >= x
} )
return it . idx < len ( it . list )
if i < len ( it . list ) {
it . cur = it . list [ i ]
it . list = it . list [ i + 1 : ]
return true
}
it . list = nil
return false
}
func ( it * listPostings ) Err ( ) error {
@ -259,32 +274,40 @@ func (it *listPostings) Err() error {
// big endian numbers.
type bigEndianPostings struct {
list [ ] byte
idx int
cur uint32
}
func newBigEndianPostings ( list [ ] byte ) * bigEndianPostings {
return & bigEndianPostings { list : list , idx : - 1 }
return & bigEndianPostings { list : list }
}
func ( it * bigEndianPostings ) At ( ) uint32 {
idx := 4 * it . idx
return binary . BigEndian . Uint32 ( it . list [ idx : idx + 4 ] )
return it . cur
}
func ( it * bigEndianPostings ) Next ( ) bool {
it . idx ++
return it . idx * 4 < len ( it . list )
if len ( it . list ) >= 4 {
it . cur = binary . BigEndian . Uint32 ( it . list )
it . list = it . list [ 4 : ]
return true
}
return false
}
func ( it * bigEndianPostings ) Seek ( x uint32 ) bool {
num := len ( it . list ) / 4
// Do binary search between current position and end.
it . idx += sort . Search ( num - it . idx , func ( i int ) bool {
idx := 4 * ( it . idx + i )
val := binary . BigEndian . Uint32 ( it . list [ idx : idx + 4 ] )
return val >= x
i := sort . Search ( num , func ( i int ) bool {
return binary . BigEndian . Uint32 ( it . list [ i * 4 : ] ) >= x
} )
return it . idx * 4 < len ( it . list )
if i < num {
j := i * 4
it . cur = binary . BigEndian . Uint32 ( it . list [ j : ] )
it . list = it . list [ j + 4 : ]
return true
}
it . list = nil
return false
}
func ( it * bigEndianPostings ) Err ( ) error {