test(fileindex): fix issues and add tests
This commit is contained in:
parent
dbb1ce65ef
commit
f68a21792c
2 changed files with 103 additions and 15 deletions
|
@ -5,7 +5,6 @@ import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"os"
|
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/ihexxa/fsearch"
|
"github.com/ihexxa/fsearch"
|
||||||
|
@ -21,6 +20,7 @@ type IFileIndex interface {
|
||||||
WriteTo(pathname string) error
|
WriteTo(pathname string) error
|
||||||
ReadFrom(pathname string) error
|
ReadFrom(pathname string) error
|
||||||
Reset() error
|
Reset() error
|
||||||
|
String() string
|
||||||
}
|
}
|
||||||
|
|
||||||
type FileTreeIndex struct {
|
type FileTreeIndex struct {
|
||||||
|
@ -66,8 +66,12 @@ func (idx *FileTreeIndex) MovePath(pathname, dstParentPath string) error {
|
||||||
|
|
||||||
func (idx *FileTreeIndex) WriteTo(pathname string) error {
|
func (idx *FileTreeIndex) WriteTo(pathname string) error {
|
||||||
rowsChan := idx.index.Marshal()
|
rowsChan := idx.index.Marshal()
|
||||||
err := idx.fs.Create(pathname)
|
err := idx.fs.Remove(pathname)
|
||||||
if err != nil && !errors.Is(err, os.ErrExist) {
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
err = idx.fs.Create(pathname)
|
||||||
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -78,17 +82,20 @@ func (idx *FileTreeIndex) WriteTo(pathname string) error {
|
||||||
batch := []string{}
|
batch := []string{}
|
||||||
for {
|
for {
|
||||||
row, ok = <-rowsChan
|
row, ok = <-rowsChan
|
||||||
|
if ok {
|
||||||
|
batch = append(batch, row+"\n")
|
||||||
|
}
|
||||||
if !ok || len(batch) > 1024 {
|
if !ok || len(batch) > 1024 {
|
||||||
wrote, err = idx.fs.WriteAt(pathname, []byte(strings.Join(batch, "\n")), offset)
|
wrote, err = idx.fs.WriteAt(pathname, []byte(strings.Join(batch, "")), offset)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
offset += int64(wrote)
|
offset += int64(wrote)
|
||||||
|
batch = batch[:0]
|
||||||
}
|
}
|
||||||
if !ok {
|
if !ok {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
batch = append(batch, row)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return idx.index.Error()
|
return idx.index.Error()
|
||||||
|
@ -105,19 +112,37 @@ func (idx *FileTreeIndex) ReadFrom(pathname string) error {
|
||||||
rowSeparator := byte('\n')
|
rowSeparator := byte('\n')
|
||||||
reader := bufio.NewReader(f)
|
reader := bufio.NewReader(f)
|
||||||
rowsChan := make(chan string, 1024)
|
rowsChan := make(chan string, 1024)
|
||||||
|
|
||||||
|
var workerErr error
|
||||||
|
readWorker := func() {
|
||||||
defer close(rowsChan)
|
defer close(rowsChan)
|
||||||
for {
|
for {
|
||||||
row, err = reader.ReadString(rowSeparator)
|
row, err = reader.ReadString(rowSeparator)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if errors.Is(err, io.EOF) {
|
if errors.Is(err, io.EOF) {
|
||||||
rowsChan <- row // some content may still read
|
if row != "" {
|
||||||
break
|
|
||||||
} else {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
rowsChan <- row
|
rowsChan <- row
|
||||||
}
|
}
|
||||||
|
break
|
||||||
|
} else {
|
||||||
|
workerErr = err
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if row != "" {
|
||||||
|
rowsChan <- row
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
go readWorker()
|
||||||
|
|
||||||
|
idx.index.Unmarshal(rowsChan)
|
||||||
|
if workerErr != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
return idx.index.Error()
|
return idx.index.Error()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (idx *FileTreeIndex) String() string {
|
||||||
|
return idx.index.String()
|
||||||
|
}
|
||||||
|
|
63
src/search/fileindex/fsearch_test.go
Normal file
63
src/search/fileindex/fsearch_test.go
Normal file
|
@ -0,0 +1,63 @@
|
||||||
|
package fileindex
|
||||||
|
|
||||||
|
import (
|
||||||
|
"math/rand"
|
||||||
|
"os"
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/ihexxa/quickshare/src/fs/local"
|
||||||
|
"github.com/ihexxa/quickshare/src/idgen/simpleidgen"
|
||||||
|
"github.com/ihexxa/randstr"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestFileSearch(t *testing.T) {
|
||||||
|
dirPath := "tmp"
|
||||||
|
err := os.MkdirAll(dirPath, 0700)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
defer os.RemoveAll(dirPath)
|
||||||
|
|
||||||
|
makePaths := func(maxPathLen, count int) map[string]bool {
|
||||||
|
rand.Seed(time.Now().UnixNano())
|
||||||
|
randStr := randstr.New([]string{})
|
||||||
|
|
||||||
|
paths := map[string]bool{}
|
||||||
|
for i := 0; i < count; i++ {
|
||||||
|
pathLen := rand.Intn(maxPathLen) + 1
|
||||||
|
pathParts := []string{}
|
||||||
|
for j := 0; j < pathLen; j++ {
|
||||||
|
pathParts = append(pathParts, randStr.Alnums())
|
||||||
|
}
|
||||||
|
paths[strings.Join(pathParts, "/")] = true
|
||||||
|
}
|
||||||
|
|
||||||
|
return paths
|
||||||
|
}
|
||||||
|
|
||||||
|
ider := simpleidgen.New()
|
||||||
|
fs := local.NewLocalFS(dirPath, 0660, 1024, 60, 60, ider)
|
||||||
|
fileIndex := NewFileTreeIndex(fs, "/", 0)
|
||||||
|
|
||||||
|
paths := makePaths(8, 256)
|
||||||
|
for pathname := range paths {
|
||||||
|
err := fileIndex.AddPath(pathname)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
indexPath := "/fileindex"
|
||||||
|
err = fileIndex.WriteTo(indexPath)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
fileIndex2 := NewFileTreeIndex(fs, "/", 0)
|
||||||
|
err = fileIndex2.ReadFrom(indexPath)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue