From b9f05bed7d2f7669044b6b2c234a3ea294588ff3 Mon Sep 17 00:00:00 2001 From: Arpad Ryszka Date: Mon, 17 Jul 2017 23:59:26 +0200 Subject: [PATCH] simplify storage --- parse.go | 2 +- store.go | 120 +++++++++++++++++++------------------------------------ 2 files changed, 42 insertions(+), 80 deletions(-) diff --git a/parse.go b/parse.go index e4bbc5c..91bb52d 100644 --- a/parse.go +++ b/parse.go @@ -15,7 +15,7 @@ type parser interface { nodeName() string nodeID() int setIncludedBy(parser, *idSet) - storeIncluded(*context, int, int) + storeIncluded(*context, int, int) // can be just an id set, taking what's excluded from the context parse(Trace, *context) } diff --git a/store.go b/store.go index 557e377..36a7458 100644 --- a/store.go +++ b/store.go @@ -1,120 +1,82 @@ package treerack -type storeEntry struct { - match *idSet - noMatch *idSet - matches []int - all []int -} - type store struct { - entries []*storeEntry -} - -func (s *store) getEntry(offset int) *storeEntry { - if len(s.entries) <= offset { - return nil - } - - return s.entries[offset] + noMatch []*idSet + match [][]int } func (s *store) hasNoMatch(offset, id int) bool { - e := s.getEntry(offset) - if e == nil { + if len(s.noMatch) <= offset || s.noMatch[offset] == nil { return false } - return e.noMatch.has(id) + return s.noMatch[offset].has(id) } func (s *store) getMatch(offset, id int) (int, bool, bool) { - e := s.getEntry(offset) - if e == nil { - return 0, false, false - } - - if e.noMatch.has(id) { + if s.hasNoMatch(offset, id) { return 0, false, true } - if !e.match.has(id) { + if len(s.match) <= offset { return 0, false, false } - for i := 0; i < len(e.matches); i += 2 { - if e.matches[i] == id { - return e.matches[i + 1], true, true + var ( + found bool + length int + ) + + for i := 0; i < len(s.match[offset]); i++ { + if s.match[offset][i] != id { + continue + } + + found = true + if s.match[offset][i + 1] > length { + length = s.match[offset][i + 1] } } - return 0, false, false + return length, found, found } func (s *store) ensureOffset(offset int) { - if len(s.entries) > offset { + if len(s.match) > offset { return } - if cap(s.entries) > offset { - s.entries = s.entries[:offset+1] + if cap(s.match) > offset { + s.match = s.match[:offset+1] return } - s.entries = s.entries[:cap(s.entries)] - for len(s.entries) <= offset { - s.entries = append(s.entries, nil) + s.match = s.match[:cap(s.match)] + for i := len(s.match); i <= offset; i++ { + s.match = append(s.match, nil) } } -func (s *store) ensureEntry(offset int) *storeEntry { - s.ensureOffset(offset) - e := s.entries[offset] - if e != nil { - return e - } - - e = &storeEntry{ - match: &idSet{}, - noMatch: &idSet{}, - } - - s.entries[offset] = e - return e -} - func (s *store) setMatch(offset, id, to int) { - e := s.ensureEntry(offset) - - 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 - } - - if to != e.matches[i + 1] { - e.all = append(e.all, id, to) - } - - return - } - } - - e.matches = append(e.matches, id, to) + s.ensureOffset(offset) + s.match[offset] = append(s.match[offset], id, to) } func (s *store) setNoMatch(offset, id int) { - e := s.ensureEntry(offset) - - if e.match.has(id) { - return + if len(s.noMatch) <= offset { + if cap(s.noMatch) > offset { + s.noMatch = s.noMatch[:offset + 1] + } else { + s.noMatch = s.noMatch[:cap(s.noMatch)] + for i := len(s.noMatch); i <= offset; i++ { + s.noMatch = append(s.noMatch, nil) + } + } } - e.noMatch.set(id) -} + if s.noMatch[offset] == nil { + s.noMatch[offset] = &idSet{} + } -func (s *store) add(offset, id, to int) { - e := s.ensureEntry(offset) - e.all = append(e.all, id, to) + s.noMatch[offset].set(id) }