Files
upstream-bleve/util/file_callbacks.go
upstream-mirror f8d3d9f0cf
Some checks failed
Coverage / coverage (push) Failing after 6s
Tests / test (1.24.x, ubuntu-latest) (push) Failing after 42s
Tests / test (1.26.x, ubuntu-latest) (push) Failing after 38s
Tests / test (1.25.x, ubuntu-latest) (push) Failing after 35s
Tests / test (1.25.x, windows-latest) (push) Has been cancelled
Tests / test (1.26.x, macos-latest) (push) Has been cancelled
Tests / test (1.26.x, windows-latest) (push) Has been cancelled
Tests / test (1.24.x, macos-latest) (push) Has been cancelled
Tests / test (1.24.x, windows-latest) (push) Has been cancelled
Tests / test (1.25.x, macos-latest) (push) Has been cancelled
snapshot of https://github.com/blevesearch/bleve.git (master, 2026-09-15; blobs > 131072B omitted)
2026-09-15 22:27:16 +05:00

130 lines
3.7 KiB
Go

// Copyright (c) 2026 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 util
import (
"fmt"
index "github.com/blevesearch/bleve_index_api"
)
// This file provides a mechanism for users of bleve to provide callbacks
// that can process data before it is written to disk, and after it is read
// from disk. This can be used for things like encryption, compression, etc.
// The user is responsible for ensuring that the writer and reader callbacks
// are compatible with each other, and that any state needed by the callbacks
// is managed appropriately. For example, if the writer callback uses a
// unique key or nonce per write, the reader callback must be able to
// determine the correct key or nonce to use for each read.
// The callbacks are identified by an id string, which is returned by the
// WriterHook. The same id string is passed to the ReaderHook when creating a reader.
// This allows the reader to determine which callback to use for a given file.
// Support for identifying all callbacks used by a given index and to remove
// selected callbacks associated with ids is provided via index.WriterIdsInUse()
// and index.DropWriterIds().
const DefaultFileCallbackId = ""
// FileWriter and FileReader interfaces are wrappers around the callback functions
// provided by the user. They provide a convenient way to apply the callbacks to data
// being written to or read from a file. They also store the id the callbacks,
// which can be useful for managing state across multiple reads and writes.
type FileWriter interface {
Process(data []byte) []byte
Id() string
}
type fileWriterImpl struct {
id string
processor func(data []byte) []byte
}
func NewFileWriter(context []byte) (FileWriter, error) {
rv := &fileWriterImpl{}
if index.WriterHook != nil {
var err error
rv.id, rv.processor, err = index.WriterHook(context)
if err != nil {
return nil, err
}
}
return rv, nil
}
func (w *fileWriterImpl) Process(data []byte) []byte {
if w.processor != nil {
return w.processor(data)
}
return data
}
func (w *fileWriterImpl) Id() string {
return w.id
}
type FileReader interface {
Process(data []byte) ([]byte, error)
Id() string
}
type fileReaderImpl struct {
id string
processor func(data []byte) ([]byte, error)
}
func NewFileReader(id string, context []byte) (FileReader, error) {
rv := &fileReaderImpl{
id: id,
}
if index.ReaderHook != nil {
var err error
rv.processor, err = index.ReaderHook(id, context)
if err != nil {
return nil, err
}
} else if id != "" {
return nil, fmt.Errorf("reader callback id %s provided but no ReaderHook is set", id)
}
return rv, nil
}
func (r *fileReaderImpl) Process(data []byte) ([]byte, error) {
if r.processor != nil {
return r.processor(data)
}
return data, nil
}
func (r *fileReaderImpl) Id() string {
return r.id
}
// -----------------------------------------------------------------------
// set of bolt keys and bucket names that require processing by the reader
// and writer callbacks.
var boltKeysProcessed = map[string]struct{}{
string(BoltDeletedKey): {},
string(BoltInternalKey): {},
string(BoltStatsKey): {},
string(BoltUpdatedFieldsKey): {},
}