Skip to content

Commit

Permalink
changed equality check of states
Browse files Browse the repository at this point in the history
  • Loading branch information
ikawaha committed Nov 25, 2014
1 parent 24035fe commit 9ff6132
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 18 deletions.
28 changes: 10 additions & 18 deletions ss/mast.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ func buildMast(input PairSlice) (m *mast) {

const initialMastSize = 1024
m = new(mast)
dic := make(map[uint][]*state)
m.states = make([]*state, 0, initialMastSize)
m.finalStates = make([]*state, 0, initialMastSize)

Expand All @@ -69,23 +70,17 @@ func buildMast(input PairSlice) (m *mast) {
for _, pair := range input {
in, out := pair.In, pair.Out
prefixLen := commonPrefixLen(in, prev)
candidate := m.finalStates
for i := len(prev); i > prefixLen; i-- {
var s *state
detected := false
if candidate != nil {
for _, c := range candidate {
if cs, ok := dic[buf[i].hcode]; ok {
for _, c := range cs {
if c.eq(buf[i]) {
buf[i].renew()
s = c
candidate = c.Prev
detected = true
break
}
}
}
if !detected {
candidate = nil
if s == nil {
s = &state{}
*s = *buf[i]
buf[i].renew()
Expand Down Expand Up @@ -129,23 +124,20 @@ func buildMast(input PairSlice) (m *mast) {
prev = in
}
// flush the buf
candidate := m.finalStates
for i := len(prev); i > 0; i-- {
var s *state
detected := false
if candidate != nil {
for _, c := range candidate {
if cs, ok := dic[buf[i].hcode]; ok {
for _, c := range cs {
if c.eq(buf[i]) {
s = c
candidate = c.Prev
detected = true
break
}
}
}
if !detected {
candidate = nil
s = buf[i]
if s == nil {
s = &state{}
*s = *buf[i]
buf[i].renew()
m.addState(s)
}
buf[i-1].setTransition(prev[i-1], s)
Expand Down
14 changes: 14 additions & 0 deletions ss/state.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package ss

import (
"fmt"
"hash/fnv"
)

type stringSet map[string]bool
Expand All @@ -13,6 +14,7 @@ type state struct {
Tail stringSet
IsFinal bool
Prev []*state
hcode uint
}

func newState() (n *state) {
Expand Down Expand Up @@ -45,10 +47,18 @@ func (n *state) tails() (t []string) {

func (n *state) setOutput(ch byte, out string) {
n.Output[ch] = out

const magic = 8191
h := fnv.New32a()
h.Write([]byte(out))
n.hcode += (uint(ch) + uint(h.Sum32())) * magic
}

func (n *state) setTransition(ch byte, next *state) {
n.Trans[ch] = next

const magic = 1001
n.hcode += (uint(ch) + uint(next.ID)) * magic
}

func (n *state) setInvTransition() {
Expand All @@ -63,6 +73,7 @@ func (n *state) renew() {
n.Tail = make(stringSet)
n.IsFinal = false
n.Prev = make([]*state, 0)
n.hcode = 0
}

func (n *state) eq(dst *state) bool {
Expand All @@ -72,6 +83,9 @@ func (n *state) eq(dst *state) bool {
if n == dst {
return true
}
if n.hcode != dst.hcode {
return false
}
if len(n.Trans) != len(dst.Trans) ||
len(n.Output) != len(dst.Output) ||
len(n.Tail) != len(dst.Tail) ||
Expand Down

0 comments on commit 9ff6132

Please sign in to comment.