Skip to content

Commit 925464a

Browse files
committed
implement file transfer APIs
1 parent 4b6a6d3 commit 925464a

4 files changed

Lines changed: 128 additions & 0 deletions

File tree

index.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -353,6 +353,13 @@ type IndexCopyable interface {
353353
CopyTo(d index.Directory) error
354354
}
355355

356+
// IndexFileCopyable is an index supporting the transfer of a single file between
357+
// two indexes
358+
type IndexFileCopyable interface {
359+
UpdateFileInBolt(key []byte, value []byte) error
360+
CopyFile(file string, d index.IndexDirectory) error
361+
}
362+
356363
// FileSystemDirectory is the default implementation for the
357364
// index.Directory interface.
358365
type FileSystemDirectory string

index/scorch/scorch.go

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,13 @@
1515
package scorch
1616

1717
import (
18+
"bytes"
1819
"encoding/json"
1920
"fmt"
21+
"io"
2022
"os"
2123
"path/filepath"
24+
"strings"
2225
"sync"
2326
"sync/atomic"
2427
"time"
@@ -1016,6 +1019,88 @@ func (s *Scorch) CopyReader() index.CopyReader {
10161019
return rv
10171020
}
10181021

1022+
func (s *Scorch) UpdateFileInBolt(key []byte, value []byte) error {
1023+
tx, err := s.rootBolt.Begin(true)
1024+
if err != nil {
1025+
return err
1026+
}
1027+
defer func() {
1028+
if err != nil {
1029+
_ = tx.Rollback()
1030+
}
1031+
}()
1032+
1033+
snapshotsBucket, err := tx.CreateBucketIfNotExists(util.BoltSnapshotsBucket)
1034+
if err != nil {
1035+
return err
1036+
}
1037+
1038+
// currently this is specific to centroid index file update
1039+
if bytes.Equal(key, util.BoltTrainerKey) {
1040+
// todo: guard against duplicate updates
1041+
trainerBucket, err := snapshotsBucket.CreateBucketIfNotExists(util.BoltTrainerKey)
1042+
if err != nil {
1043+
return err
1044+
}
1045+
if trainerBucket == nil {
1046+
return fmt.Errorf("trainer bucket not found")
1047+
}
1048+
existingValue := trainerBucket.Get(util.BoltPathKey)
1049+
if existingValue != nil {
1050+
return fmt.Errorf("key already exists %v %v", s.path, string(existingValue))
1051+
}
1052+
1053+
err = trainerBucket.Put(util.BoltPathKey, value)
1054+
if err != nil {
1055+
return err
1056+
}
1057+
}
1058+
1059+
err = tx.Commit()
1060+
if err != nil {
1061+
return err
1062+
}
1063+
1064+
err = s.rootBolt.Sync()
1065+
if err != nil {
1066+
return err
1067+
}
1068+
1069+
return nil
1070+
}
1071+
1072+
// CopyFile copies a specific file to a destination directory which has an access to a bleve index
1073+
// doing a io.Copy() isn't enough because the file needs to be tracked in bolt file as well
1074+
func (s *Scorch) CopyFile(file string, d index.IndexDirectory) error {
1075+
s.rootLock.Lock()
1076+
defer s.rootLock.Unlock()
1077+
1078+
// this code is currently specific to centroid index file but is future proofed for other files
1079+
// to be updated in the dest's bolt
1080+
if strings.HasSuffix(file, index.CentroidIndexFileName) {
1081+
// centroid index file - this is outside the snapshots domain so the bolt update is different
1082+
err := d.UpdateFileInBolt(util.BoltTrainerKey, []byte(file))
1083+
if err != nil {
1084+
return fmt.Errorf("error updating dest index bolt: %w", err)
1085+
}
1086+
}
1087+
1088+
dest, err := d.GetWriter(filepath.Join("store", file))
1089+
if err != nil {
1090+
return err
1091+
}
1092+
1093+
source, err := os.Open(filepath.Join(s.path, file))
1094+
if err != nil {
1095+
return err
1096+
}
1097+
1098+
defer source.Close()
1099+
defer dest.Close()
1100+
_, err = io.Copy(dest, source)
1101+
return err
1102+
}
1103+
10191104
// external API to fire a scorch event (EventKindIndexStart) externally from bleve
10201105
func (s *Scorch) FireIndexEvent() {
10211106
s.fireEvent(EventKindIndexStart, 0)

index/scorch/train_noop.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,3 +23,7 @@ func (t *noopTrainer) loadTrainedData(bucket *bolt.Bucket) error {
2323
// noop
2424
return nil
2525
}
26+
27+
func (t *noopTrainer) getInternal(key []byte) ([]byte, error) {
28+
return nil, nil
29+
}

index_impl.go

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1463,6 +1463,38 @@ func (i *indexImpl) CopyTo(d index.Directory) (err error) {
14631463
return i.meta.CopyTo(d)
14641464
}
14651465

1466+
func (i *indexImpl) CopyFile(file string, d index.IndexDirectory) (err error) {
1467+
i.mutex.RLock()
1468+
defer i.mutex.RUnlock()
1469+
1470+
if !i.open {
1471+
return ErrorIndexClosed
1472+
}
1473+
1474+
copyIndex, ok := i.i.(index.IndexFileCopyable)
1475+
if !ok {
1476+
return fmt.Errorf("index implementation does not support copy reader")
1477+
}
1478+
1479+
return copyIndex.CopyFile(file, d)
1480+
}
1481+
1482+
func (i *indexImpl) UpdateFileInBolt(key []byte, value []byte) error {
1483+
i.mutex.RLock()
1484+
defer i.mutex.RUnlock()
1485+
1486+
if !i.open {
1487+
return ErrorIndexClosed
1488+
}
1489+
1490+
copyIndex, ok := i.i.(index.IndexFileCopyable)
1491+
if !ok {
1492+
return fmt.Errorf("index implementation does not support file copy")
1493+
}
1494+
1495+
return copyIndex.UpdateFileInBolt(key, value)
1496+
}
1497+
14661498
func (f FileSystemDirectory) GetWriter(filePath string) (io.WriteCloser,
14671499
error,
14681500
) {

0 commit comments

Comments
 (0)