1
0
Fork 0
golang-github-blevesearch-b.../analysis/lang/pl/stempel/trie.go
Daniel Baumann 982828099e
Adding upstream version 2.5.1.
Signed-off-by: Daniel Baumann <daniel@debian.org>
2025-05-19 00:20:02 +02:00

132 lines
2.9 KiB
Go

// Copyright (c) 2018 Couchbase, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package stempel
import (
"fmt"
"github.com/blevesearch/stempel/javadata"
)
// trie represents the internal trie structure
type trie struct {
rows []*row
cmds []string
root int32
forward bool
}
func newTrie(r *javadata.Reader) (rv *trie, err error) {
rv = &trie{}
rv.forward, err = r.ReadBool()
if err != nil {
return nil, fmt.Errorf("error reading trie forward: %v", err)
}
rv.root, err = r.ReadInt32()
if err != nil {
return nil, fmt.Errorf("error reading trie root: %v", err)
}
// commands
nCommands, err := r.ReadInt32()
if err != nil {
return nil, fmt.Errorf("error reading trie num commands: %v", err)
}
for nCommands > 0 {
utfCommand, nerr := r.ReadUTF()
if nerr != nil {
return nil, fmt.Errorf("error reading trie command utf: %v", nerr)
}
rv.cmds = append(rv.cmds, utfCommand)
nCommands--
}
// rows
nRows, err := r.ReadInt32()
if err != nil {
return nil, fmt.Errorf("error reading trie num rows: %v", err)
}
for nRows > 0 {
row, err := newRow(r)
if err != nil {
return nil, fmt.Errorf("error reading trie row: %v", err)
}
rv.rows = append(rv.rows, row)
nRows--
}
return rv, nil
}
func (t *trie) getRow(i int) *row {
if i < 0 || i >= len(t.rows) {
return nil
}
return t.rows[i]
}
func (t *trie) GetLastOnPath(key []rune) []rune {
now := t.getRow(int(t.root))
var last []rune
var w int32
e := newStrEnum(key, t.forward)
// walk over each rune
// if rune has row in the table, note the cmd (as last)
// if rune has row in table, see if it transitions to another row
// if it does, move to that row and next char on next loop itr
// if it does not, return the last cmd
// if you get to end of string and there is command in row use it
// or return last
for i := 0; i < len(key)-1; i++ {
r, err := e.next()
if err != nil {
return last
}
w = now.getCmd(r)
if w >= 0 {
last = []rune(t.cmds[w])
}
w = now.getRef(r)
if w >= 0 {
now = t.getRow(int(w))
} else {
return last
}
}
r, err := e.next()
if err != nil {
return last
}
w = now.getCmd(r)
if err != nil {
return last
}
if w >= 0 {
return []rune(t.cmds[w])
}
return last
}
func (t *trie) String() string {
rv := ""
for _, cmd := range t.cmds {
rv += fmt.Sprintf("cmd: %s\n", string(cmd))
}
for _, row := range t.rows {
rv += fmt.Sprintf("row: %v\n", row)
}
return rv
}