Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,7 @@ _testmain.go

# tmp
*#
.#*
.#*

# test files
/testfiles/Test*
9 changes: 0 additions & 9 deletions .travis.yml

This file was deleted.

17 changes: 7 additions & 10 deletions branch.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,12 @@ func (b *Branch) add(entry []byte) (addedBranch *Branch) {
if b.LeafValue == nil && len(b.Branches) == 0 {
if len(entry) > 0 {
b.LeafValue = entry
} else {
// something came in but we already have branches for it
// so the tail was the current branches index but no value
// to push. just mark the current idx position as End
}
// else {
// something came in but we already have branches for it
// so the tail was the current branches index but no value
// to push. just mark the current idx position as End
// }
b.setEnd(true)
addedBranch = b
return
Expand Down Expand Up @@ -215,7 +216,7 @@ func (b *Branch) delete(entry []byte) (deleted bool) {
if len(b.Branches) == 0 && b.Count == 0 {
b.LeafValue = nil
} else if len(b.Branches) == 1 && b.Count == 0 {
b = b.pullUp()
b.pullUp()
}
return true
}
Expand Down Expand Up @@ -248,10 +249,7 @@ func (b *Branch) delete(entry []byte) (deleted bool) {
/*
*/
func (b *Branch) has(entry []byte) bool {
if b.getBranch(entry) != nil {
return true
}
return false
return b.getBranch(entry) != nil
}

func (b *Branch) hasCount(entry []byte) (bool, int64) {
Expand Down Expand Up @@ -443,7 +441,6 @@ func (b *Branch) setEnd(flag bool) {
}
}
b.End = flag
return
}

func (b *Branch) String() string {
Expand Down
5 changes: 5 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module github.com/glaslos/trie

go 1.21.2

require github.com/fvbock/uds-go v0.0.0-20150825055119-e378dd1356b9
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
github.com/fvbock/uds-go v0.0.0-20150825055119-e378dd1356b9 h1:PI8D0UwtC04m+FUaqB8RPOeuicjr896/afA5jlvpojA=
github.com/fvbock/uds-go v0.0.0-20150825055119-e378dd1356b9/go.mod h1:J+KQJ2ZNVvd2gibb4nuUJbXVCSdKCFGn0ch/FI9xPlw=
76 changes: 25 additions & 51 deletions trie.go
Original file line number Diff line number Diff line change
@@ -1,15 +1,10 @@
package trie

import (
"bufio"
"bytes"
"encoding/gob"
"errors"
"fmt"
"io"
"log"
"os"
"time"
)

type Trie struct {
Expand Down Expand Up @@ -149,47 +144,34 @@ using encoding/gob.
The Trie itself can currently not be encoded directly because gob does not
directly support structs with a sync.Mutex on them.
*/
func (t *Trie) DumpToFile(fname string) (err error) {
func (t *Trie) DumpToFile(fname string) error {
t.Root.Lock()
entries := t.Members()
t.Root.Unlock()

buf := new(bytes.Buffer)
enc := gob.NewEncoder(buf)
if err = enc.Encode(entries); err != nil {
err = errors.New(fmt.Sprintf("Could encode Trie entries for dump file: %v", err))
return
}

f, err := os.Create(fname)
if err != nil {
err = errors.New(fmt.Sprintf("Could not save dump file: %v", err))
return
return fmt.Errorf("could not save dump file: %w", err)
}
defer f.Close()

w := bufio.NewWriter(f)
_, err = w.Write(buf.Bytes())
if err != nil {
err = errors.New(fmt.Sprintf("Error writing to dump file: %v", err))
return
enc := gob.NewEncoder(f)
if err := enc.Encode(entries); err != nil {
return fmt.Errorf("could encode Trie entries for dump file: %w", err)

}
// log.Printf("wrote %d bytes to dumpfile %s\n", bl, fname)
w.Flush()
return
return nil
}

/*
MergeFromFile loads a gib encoded wordlist from a file and Add() them to the `Trie`.
*/
// TODO: write tests for merge
func (t *Trie) MergeFromFile(fname string) (err error) {
func (t *Trie) MergeFromFile(fname string) error {
entries, err := loadTrieFile(fname)
if err != nil {
return
return err
}
log.Printf("Got %v entries\n", len(entries))
startTime := time.Now()
for _, mi := range entries {
b := t.GetBranch(mi.Value)
if b != nil {
Expand All @@ -203,51 +185,43 @@ func (t *Trie) MergeFromFile(fname string) (err error) {
b.Unlock()
}
}
log.Printf("merging words to index took: %v\n", time.Since(startTime))
return
return nil
}

/*
LoadFromFile loads a gib encoded wordlist from a file and creates a new Trie
by Add()ing all of them.
*/
func LoadFromFile(fname string) (tr *Trie, err error) {
tr = NewTrie()
func LoadFromFile(fname string) (*Trie, error) {
tr := NewTrie()
entries, err := loadTrieFile(fname)
if err != nil {
return
return tr, err
}
log.Printf("Got %v entries\n", len(entries))
startTime := time.Now()
for _, mi := range entries {
b := tr.Add(mi.Value)
b.Count = mi.Count
}
log.Printf("adding words to index took: %v\n", time.Since(startTime))

return
return tr, nil
}

func loadTrieFile(fname string) (entries []*MemberInfo, err error) {
log.Println("Load trie from", fname)
func loadTrieFile(fname string) ([]*MemberInfo, error) {
f, err := os.Open(fname)
if err != nil {
err = errors.New(fmt.Sprintf("Could not open Trie file: %v", err))
} else {
defer f.Close()
return nil, fmt.Errorf("could not open Trie file: %w", err)
}
defer f.Close()

buf := bufio.NewReader(f)
dec := gob.NewDecoder(buf)
if err = dec.Decode(&entries); err != nil {
var entries []*MemberInfo
dec := gob.NewDecoder(f)
if err = dec.Decode(&entries); err != nil {
if err != nil {
if err == io.EOF && entries == nil {
log.Println("Nothing to decode. Seems the file is empty.")
err = nil
} else {
err = errors.New(fmt.Sprintf("Decoding error: %v", err))
return
return entries, nil
}
return entries, fmt.Errorf("decoding error: %w", err)
}
}

return
return entries, nil
}
3 changes: 3 additions & 0 deletions trie_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -900,6 +900,9 @@ func TestTrieDumpToFileLoadFromFile(t *testing.T) {
n++
}
err := tr.DumpToFile("testfiles/TestDumpToFileLoadFromFile")
if err != nil {
t.Error(err)
}

loadedTrie, err := LoadFromFile("testfiles/TestDumpToFileLoadFromFile")
if err != nil {
Expand Down