File
Blob: spec/chord/kv.go
| 1 | package chord |
| 2 | |
| 3 | import ( |
| 4 | "context" |
| 5 | "time" |
| 6 | |
| 7 | "go.miragespace.co/specter/spec/protocol" |
| 8 | ) |
| 9 | |
| 10 | type HashFn func([]byte) uint64 |
| 11 | |
| 12 | type SimpleKV interface { |
| 13 | // Put will store the value to a node in the Chord network responsible for the given key. |
| 14 | // If the key did not exist, a new entry will be added. |
| 15 | // If the key already exist, the value will be overwrriten. |
| 16 | // If the key was concurrently modified by another request, ErrKVSimpleConflict error is returned. |
| 17 | Put(ctx context.Context, key, value []byte) error |
| 18 | // Get will fetch the value from a node in the Chord network. |
| 19 | Get(ctx context.Context, key []byte) (value []byte, err error) |
| 20 | // Delete will hard delete the key from the Chord network. |
| 21 | // If the key was concurrently modified by another request, ErrKVSimpleConflict error is returned. |
| 22 | // Note that Put/Get methods can share the same keyspace as Prefix methods, and |
| 23 | // Delete will not remove the Prefix children. |
| 24 | Delete(ctx context.Context, key []byte) error |
| 25 | } |
| 26 | |
| 27 | type PrefixKV interface { |
| 28 | // PrefixAppend appends the child under the prefix. This is useful for tracking |
| 29 | // hierarchical structure such as directories. |
| 30 | // If the child already exist, ErrKVPrefixConflict error is returned. |
| 31 | // Note that Prefix methods can share the same keyspace as Put/Get, and |
| 32 | // Delete will not remove the Prefix children. |
| 33 | PrefixAppend(ctx context.Context, prefix []byte, child []byte) error |
| 34 | // PrefixList returns the children under the prefix. |
| 35 | PrefixList(ctx context.Context, prefix []byte) (children [][]byte, err error) |
| 36 | // PrefixContains checks if the child is in the prefix children |
| 37 | PrefixContains(ctx context.Context, prefix []byte, child []byte) (bool, error) |
| 38 | // PrefixRemove removes the matching child under the prefix. |
| 39 | // If the child did not exist, this is an no-op |
| 40 | PrefixRemove(ctx context.Context, prefix []byte, child []byte) error |
| 41 | } |
| 42 | |
| 43 | type LeaseKV interface { |
| 44 | // Acquire obtains a lease with given time-to-live, and returns a token for |
| 45 | // later renewal and release. |
| 46 | // On conflicting lease acquisition, ErrKVLeaseConflict error is returned. |
| 47 | // If ttl is less than a second, ErrKVLeaseInvalidTTL error is returned. |
| 48 | // Not to be confused with memory ordering acquire/release semantics. |
| 49 | Acquire(ctx context.Context, lease []byte, ttl time.Duration) (token uint64, err error) |
| 50 | // Renew extends the lease with given time-to-live, given that prevToken |
| 51 | // is still valid. If the renewal occurs after a previous acquire |
| 52 | // has expired and a different lease was acquired, ErrKVLeaseExpired error is returned. |
| 53 | // If ttl is less than a second, ErrKVLeaseInvalidTTL error is returned. |
| 54 | Renew(ctx context.Context, lease []byte, ttl time.Duration, prevToken uint64) (newToken uint64, err error) |
| 55 | // Release relinquish the lease held previously by the given token. |
| 56 | // If the lease holder has changed, ErrKVLeaseExpired error is returned. |
| 57 | // Not to be confused with memory ordering acquire/release semantics. |
| 58 | Release(ctx context.Context, lease []byte, token uint64) error |
| 59 | } |
| 60 | |
| 61 | type KV interface { |
| 62 | SimpleKV |
| 63 | PrefixKV |
| 64 | LeaseKV |
| 65 | // Import is used when a node is transferring its KV to a remote node. |
| 66 | // Used when a new node joins or a node leaves gracefully |
| 67 | Import(ctx context.Context, keys [][]byte, values []*protocol.KVTransfer) error |
| 68 | // ListKeys is used when a node is traversing the network to list keys |
| 69 | // based on a prefix |
| 70 | ListKeys(ctx context.Context, prefix []byte) ([]*protocol.KeyComposite, error) |
| 71 | } |
| 72 | |
| 73 | type KVProvider interface { |
| 74 | KV |
| 75 | // Export is used when a Local node is retrieving relevant keys to transfer. |
| 76 | // Only used locally, not used for RPC |
| 77 | Export(ctx context.Context, keys [][]byte) ([]*protocol.KVTransfer, error) |
| 78 | // RangeKeys retrieve actual byte values of the keys, given the [low, high] |
| 79 | // range of key hashes. |
| 80 | // Only used locally, not used for RPC |
| 81 | RangeKeys(ctx context.Context, low, high uint64) ([][]byte, error) |
| 82 | // RemoveKeys hard delete keys from local node. |
| 83 | // Only used locally, not used for RPC |
| 84 | RemoveKeys(ctx context.Context, keys [][]byte) error |
| 85 | } |