treerack/store.go

121 lines
1.8 KiB
Go
Raw Normal View History

2017-07-15 21:49:08 +02:00
package treerack
2017-06-25 17:51:08 +02:00
2017-06-26 02:20:23 +02:00
type storeEntry struct {
2017-07-15 23:00:43 +02:00
match *idSet
noMatch *idSet
2017-07-17 21:58:03 +02:00
matches []int
all []int
2017-06-25 17:51:08 +02:00
}
2017-06-26 02:20:23 +02:00
type store struct {
2017-07-15 23:00:43 +02:00
entries []*storeEntry
2017-06-25 17:51:08 +02:00
}
2017-07-17 21:58:03 +02:00
func (s *store) getEntry(offset int) *storeEntry {
if len(s.entries) <= offset {
return nil
}
return s.entries[offset]
}
func (s *store) hasNoMatch(offset, id int) bool {
e := s.getEntry(offset)
if e == nil {
return false
2017-06-25 17:51:08 +02:00
}
2017-07-17 21:58:03 +02:00
return e.noMatch.has(id)
}
func (s *store) getMatch(offset, id int) (int, bool, bool) {
e := s.getEntry(offset)
if e == nil {
2017-07-17 04:23:29 +02:00
return 0, false, false
2017-06-25 17:51:08 +02:00
}
2017-07-17 21:58:03 +02:00
if e.noMatch.has(id) {
2017-07-17 04:23:29 +02:00
return 0, false, true
2017-06-25 17:51:08 +02:00
}
2017-07-17 21:58:03 +02:00
if !e.match.has(id) {
2017-07-17 04:23:29 +02:00
return 0, false, false
2017-07-15 23:00:43 +02:00
}
2017-07-17 21:58:03 +02:00
for i := 0; i < len(e.matches); i += 2 {
if e.matches[i] == id {
return e.matches[i + 1], true, true
2017-06-25 17:51:08 +02:00
}
}
2017-07-17 04:23:29 +02:00
return 0, false, false
2017-06-25 17:51:08 +02:00
}
2017-07-17 21:58:03 +02:00
func (s *store) ensureOffset(offset int) {
if len(s.entries) > offset {
2017-06-25 17:51:08 +02:00
return
}
2017-07-17 21:58:03 +02:00
if cap(s.entries) > offset {
s.entries = s.entries[:offset+1]
return
2017-07-16 23:15:42 +02:00
}
2017-07-17 21:58:03 +02:00
s.entries = s.entries[:cap(s.entries)]
for len(s.entries) <= offset {
s.entries = append(s.entries, nil)
2017-07-16 23:15:42 +02:00
}
}
2017-07-17 21:58:03 +02:00
func (s *store) ensureEntry(offset int) *storeEntry {
s.ensureOffset(offset)
e := s.entries[offset]
if e != nil {
return e
2017-07-16 23:15:42 +02:00
}
2017-07-17 21:58:03 +02:00
e = &storeEntry{
2017-07-16 23:15:42 +02:00
match: &idSet{},
noMatch: &idSet{},
}
2017-07-17 21:58:03 +02:00
s.entries[offset] = e
return e
2017-07-16 23:15:42 +02:00
}
2017-07-17 21:58:03 +02:00
func (s *store) setMatch(offset, id, to int) {
e := s.ensureEntry(offset)
2017-07-16 23:15:42 +02:00
2017-07-17 21:58:03 +02:00
e.match.set(id)
for i := 0; i < len(e.matches); i += 2 {
if e.matches[i] == id {
if to > e.matches[i + 1] {
e.matches[i + 1] = to
}
2017-07-16 23:15:42 +02:00
2017-07-17 21:58:03 +02:00
if to != e.matches[i + 1] {
e.all = append(e.all, id, to)
}
2017-07-16 23:15:42 +02:00
2017-07-17 21:58:03 +02:00
return
2017-07-16 23:15:42 +02:00
}
}
2017-07-17 21:58:03 +02:00
e.matches = append(e.matches, id, to)
2017-07-16 23:15:42 +02:00
}
2017-07-17 21:58:03 +02:00
func (s *store) setNoMatch(offset, id int) {
e := s.ensureEntry(offset)
2017-07-16 23:15:42 +02:00
2017-07-17 21:58:03 +02:00
if e.match.has(id) {
2017-07-16 23:15:42 +02:00
return
}
2017-07-17 21:58:03 +02:00
e.noMatch.set(id)
}
2017-07-16 23:15:42 +02:00
2017-07-17 21:58:03 +02:00
func (s *store) add(offset, id, to int) {
e := s.ensureEntry(offset)
e.all = append(e.all, id, to)
2017-07-16 23:15:42 +02:00
}