mirror of
				https://source.quilibrium.com/quilibrium/ceremonyclient.git
				synced 2025-11-04 03:07:28 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			134 lines
		
	
	
		
			5.5 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			134 lines
		
	
	
		
			5.5 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
// Copyright 2018 The LevelDB-Go and Pebble Authors. All rights reserved. Use
 | 
						|
// of this source code is governed by a BSD-style license that can be found in
 | 
						|
// the LICENSE file.
 | 
						|
 | 
						|
package base
 | 
						|
 | 
						|
import "io"
 | 
						|
 | 
						|
// Merge creates a ValueMerger for the specified key initialized with the value
 | 
						|
// of one merge operand.
 | 
						|
type Merge func(key, value []byte) (ValueMerger, error)
 | 
						|
 | 
						|
// ValueMerger receives merge operands one by one. The operand received is either
 | 
						|
// newer or older than all operands received so far as indicated by the function
 | 
						|
// names, `MergeNewer()` and `MergeOlder()`. Once all operands have been received,
 | 
						|
// the client will invoke `Finish()` to obtain the final result. The order of
 | 
						|
// a merge is not changed after the first call to `MergeNewer()` or
 | 
						|
// `MergeOlder()`, i.e. the same method is used to submit all operands.
 | 
						|
//
 | 
						|
// The implementation may choose to merge values into the result immediately upon
 | 
						|
// receiving each operand, or buffer operands until Finish() is called. For example,
 | 
						|
// buffering may be useful to avoid (de)serializing partial merge results.
 | 
						|
//
 | 
						|
// The merge operation must be associative. That is, for the values A, B, C:
 | 
						|
//
 | 
						|
//	Merge(A).MergeOlder(B).MergeOlder(C) == Merge(C).MergeNewer(B).MergeNewer(A)
 | 
						|
//
 | 
						|
// Examples of merge operators are integer addition, list append, and string
 | 
						|
// concatenation.
 | 
						|
type ValueMerger interface {
 | 
						|
	// MergeNewer adds an operand that is newer than all existing operands.
 | 
						|
	// The caller retains ownership of value.
 | 
						|
	//
 | 
						|
	// If an error is returned the merge is aborted and no other methods must
 | 
						|
	// be called.
 | 
						|
	MergeNewer(value []byte) error
 | 
						|
 | 
						|
	// MergeOlder adds an operand that is older than all existing operands.
 | 
						|
	// The caller retains ownership of value.
 | 
						|
	//
 | 
						|
	// If an error is returned the merge is aborted and no other methods must
 | 
						|
	// be called.
 | 
						|
	MergeOlder(value []byte) error
 | 
						|
 | 
						|
	// Finish does any final processing of the added operands and returns a
 | 
						|
	// result. The caller can assume the returned byte slice will not be mutated.
 | 
						|
	//
 | 
						|
	// Finish must be the last function called on the ValueMerger. The caller
 | 
						|
	// must not call any other ValueMerger functions after calling Finish.
 | 
						|
	//
 | 
						|
	// If `includesBase` is true, the oldest merge operand was part of the
 | 
						|
	// merge. This will always be the true during normal iteration, but may be
 | 
						|
	// false during compaction when only a subset of operands may be
 | 
						|
	// available. Note that `includesBase` is set to true conservatively: a false
 | 
						|
	// value means that we could not definitely determine that the base merge
 | 
						|
	// operand was included.
 | 
						|
	//
 | 
						|
	// If a Closer is returned, the returned slice will remain valid until it is
 | 
						|
	// closed. The caller must arrange for the closer to be eventually closed.
 | 
						|
	Finish(includesBase bool) ([]byte, io.Closer, error)
 | 
						|
}
 | 
						|
 | 
						|
// DeletableValueMerger is an extension to ValueMerger which allows indicating that the
 | 
						|
// result of a merge operation is non-existent. Such non-existent entries will eventually
 | 
						|
// be deleted during compaction. Note that during compaction, non-existence of the result
 | 
						|
// of a merge means that the merge operands will not result in any record being output.
 | 
						|
// This is not the same as transforming the merge operands into a deletion tombstone, as
 | 
						|
// older merge operands will still be visible during iteration. Deletion of the merge operands
 | 
						|
// in this way is akin to the way a SingleDelete+Set combine into non-existence while leaving
 | 
						|
// older records for the same key unaffected.
 | 
						|
type DeletableValueMerger interface {
 | 
						|
	ValueMerger
 | 
						|
 | 
						|
	// DeletableFinish enables a value merger to indicate that the result of a merge operation
 | 
						|
	// is non-existent. See Finish for a description of includesBase.
 | 
						|
	DeletableFinish(includesBase bool) (value []byte, delete bool, closer io.Closer, err error)
 | 
						|
}
 | 
						|
 | 
						|
// Merger defines an associative merge operation. The merge operation merges
 | 
						|
// two or more values for a single key. A merge operation is requested by
 | 
						|
// writing a value using {Batch,DB}.Merge(). The value at that key is merged
 | 
						|
// with any existing value. It is valid to Set a value at a key and then Merge
 | 
						|
// a new value. Similar to non-merged values, a merged value can be deleted by
 | 
						|
// either Delete or DeleteRange.
 | 
						|
//
 | 
						|
// The merge operation is invoked when a merge value is encountered during a
 | 
						|
// read, either during a compaction or during iteration.
 | 
						|
type Merger struct {
 | 
						|
	Merge Merge
 | 
						|
 | 
						|
	// Name is the name of the merger.
 | 
						|
	//
 | 
						|
	// Pebble stores the merger name on disk, and opening a database with a
 | 
						|
	// different merger from the one it was created with will result in an error.
 | 
						|
	Name string
 | 
						|
}
 | 
						|
 | 
						|
// AppendValueMerger concatenates merge operands in order from oldest to newest.
 | 
						|
type AppendValueMerger struct {
 | 
						|
	buf []byte
 | 
						|
}
 | 
						|
 | 
						|
// MergeNewer appends value to the result.
 | 
						|
func (a *AppendValueMerger) MergeNewer(value []byte) error {
 | 
						|
	a.buf = append(a.buf, value...)
 | 
						|
	return nil
 | 
						|
}
 | 
						|
 | 
						|
// MergeOlder prepends value to the result, which involves allocating a new buffer.
 | 
						|
func (a *AppendValueMerger) MergeOlder(value []byte) error {
 | 
						|
	buf := make([]byte, len(a.buf)+len(value))
 | 
						|
	copy(buf, value)
 | 
						|
	copy(buf[len(value):], a.buf)
 | 
						|
	a.buf = buf
 | 
						|
	return nil
 | 
						|
}
 | 
						|
 | 
						|
// Finish returns the buffer that was constructed on-demand in `Merge{OlderNewer}()` calls.
 | 
						|
func (a *AppendValueMerger) Finish(includesBase bool) ([]byte, io.Closer, error) {
 | 
						|
	return a.buf, nil, nil
 | 
						|
}
 | 
						|
 | 
						|
// DefaultMerger is the default implementation of the Merger interface. It
 | 
						|
// concatenates the two values to merge.
 | 
						|
var DefaultMerger = &Merger{
 | 
						|
	Merge: func(key, value []byte) (ValueMerger, error) {
 | 
						|
		res := &AppendValueMerger{}
 | 
						|
		res.buf = append(res.buf, value...)
 | 
						|
		return res, nil
 | 
						|
	},
 | 
						|
 | 
						|
	Name: "pebble.concatenate",
 | 
						|
}
 |