-
Notifications
You must be signed in to change notification settings - Fork 174
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Table store #774
Merged
Merged
Table store #774
Changes from 40 commits
Commits
Show all changes
43 commits
Select commit
Hold shift + click to select a range
c939ace
Created table store.
cody-littley 8889ea2
Incremental progress.
cody-littley 967b01c
Simplify by making max table count fixed.
cody-littley 3f65d47
Use last table indices for internal tables.
cody-littley 8894e43
Make table deletion atomic.
cody-littley 61d8407
Cleanup.
cody-littley 58d321c
Added table view.
cody-littley a85f0ee
Fix table view iteration.
cody-littley 4a37778
Write some unit tests.
cody-littley 4ebe6d0
checkin
cody-littley 2695d49
Add random test, fix bugs.
cody-littley b288669
Added logging.
cody-littley 0913aff
Fix lint issues.
cody-littley fc4b707
lint
cody-littley 27d7f0b
Checkin.
cody-littley 98bdde9
Small tweak to naming.
cody-littley 5bed795
Finished conversion, now for the unit tests
cody-littley b6cd49b
Partially migrate to new API.
cody-littley efc7be6
Now compiles.
cody-littley 0dc38c2
Get store tests working.
cody-littley a11e3b4
Unit tests are passing.
cody-littley dfe422a
Cleanup.
cody-littley 091e6bb
Cleanup and unit tests.
cody-littley 39a3521
Cleanup.
cody-littley 3921d4a
Made suggested changes.
cody-littley ca76d4c
Made suggested changes.
cody-littley f424892
Refactored builder, need to convert unit tests
cody-littley 6d0c2b5
Things compile, many tests commented out
cody-littley 551e6cf
Enable more unit tests.
cody-littley 2117cd6
Enabled remainder of tests.
cody-littley d0c3654
Partial conversion, compiles
cody-littley 1a3c9ec
Enabled most unit tests.
cody-littley 2a287ea
Incremental progress.
cody-littley 0d90c45
Start shuffling things.
cody-littley c2a29c0
Re-enable last commented test.
cody-littley eef049f
More refactors.
cody-littley 5302e68
Finish simplifying builder.
cody-littley b16a83f
Made suggested changes, cleanup
cody-littley 1dbafb5
Made suggested changes.
cody-littley 473e483
Made suggested change.
cody-littley dcd087e
Add ability to load store without changing tables.
cody-littley 553b6c4
Made suggested changes.
cody-littley 2780af4
Make suggested change.
cody-littley File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
package kvstore | ||
|
||
// Batch is a collection of key / value pairs that can be written atomically to a database. | ||
type Batch[K any] interface { | ||
// Put stores the given key / value pair in the batch, overwriting any existing value for that key. | ||
// If nil is passed as the value, a byte slice of length 0 will be stored. | ||
Put(key K, value []byte) | ||
// Delete removes the key from the batch. | ||
Delete(key K) | ||
// Apply atomically writes all the key / value pairs in the batch to the database. | ||
Apply() error | ||
// Size returns the number of operations in the batch. | ||
Size() uint32 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
package kvstore | ||
|
||
import "errors" | ||
|
||
// ErrTableLimitExceeded is returned when the maximum number of tables has been reached. | ||
var ErrTableLimitExceeded = errors.New("table limit exceeded") | ||
|
||
// ErrTableNotFound is returned when a table is not found. | ||
var ErrTableNotFound = errors.New("table not found") | ||
|
||
// Table can be used to operate on data in a specific table in a TableStore. | ||
type Table interface { | ||
// Store permits access to the table as if it were a store. | ||
Store | ||
|
||
// Name returns the name of the table. | ||
Name() string | ||
|
||
// TableKey creates a new key scoped to this table that can be used for batch operations that modify this table. | ||
TableKey(key []byte) TableKey | ||
} | ||
|
||
// TableKey is a key scoped to a particular table. It can be used to perform batch operations that modify multiple | ||
// table keys atomically. | ||
type TableKey []byte | ||
|
||
// TableBatch is a collection of operations that can be applied atomically to a TableStore. | ||
type TableBatch Batch[TableKey] | ||
|
||
// TableStore implements a key-value store, with the addition of the abstraction of tables. | ||
// A "table" in this context is a disjoint keyspace. Keys in one table to not collide with keys in another table, | ||
// and keys within a particular table can be iterated over efficiently. | ||
// | ||
// A TableStore is only required to support a maximum of 2^32-X unique, where X is a small integer number of tables | ||
// reserved for internal use by the table store. The exact value of X is implementation dependent. | ||
// | ||
// Implementations of this interface are expected to be thread-safe, except where noted. | ||
type TableStore interface { | ||
|
||
// GetTable gets the table with the given name. If the table does not exist, it is first created. | ||
// Returns ErrTableNotFound if the table does not exist and cannot be created. | ||
GetTable(name string) (Table, error) | ||
|
||
// GetTables returns a list of all tables in the store in no particular order. | ||
GetTables() []Table | ||
|
||
// NewBatch creates a new batch that can be used to perform multiple operations across tables atomically. | ||
NewBatch() TableBatch | ||
|
||
// Shutdown shuts down the store, flushing any remaining data to disk. | ||
Shutdown() error | ||
|
||
// Destroy shuts down and permanently deletes all data in the store. | ||
Destroy() error | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
package tablestore | ||
|
||
import ( | ||
"github.com/Layr-Labs/eigenda/common/kvstore" | ||
"github.com/Layr-Labs/eigensdk-go/logging" | ||
) | ||
|
||
var _ kvstore.TableStore = &tableStore{} | ||
|
||
// tableStore is an implementation of TableStore that wraps a Store. | ||
type tableStore struct { | ||
logger logging.Logger | ||
|
||
// A base store implementation that this TableStore wraps. | ||
base kvstore.Store | ||
|
||
// A map from table names to tables. | ||
tableMap map[string]kvstore.Table | ||
} | ||
|
||
// wrapper wraps the given Store to create a TableStore. | ||
// | ||
// WARNING: it is not safe to access the wrapped store directly while the TableStore is in use. The TableStore uses | ||
// special key formatting, and direct access to the wrapped store may violate the TableStore's invariants, resulting | ||
// in undefined behavior. | ||
func newTableStore( | ||
logger logging.Logger, | ||
base kvstore.Store, | ||
tables map[string]kvstore.Table) kvstore.TableStore { | ||
|
||
return &tableStore{ | ||
logger: logger, | ||
base: base, | ||
tableMap: tables, | ||
} | ||
} | ||
|
||
// GetTable gets the table with the given name. If the table does not exist, it is first created. | ||
func (t *tableStore) GetTable(name string) (kvstore.Table, error) { | ||
table, ok := t.tableMap[name] | ||
if !ok { | ||
return nil, kvstore.ErrTableNotFound | ||
} | ||
|
||
return table, nil | ||
} | ||
|
||
// GetTables returns a list of all tables in the store in no particular order. | ||
func (t *tableStore) GetTables() []kvstore.Table { | ||
tables := make([]kvstore.Table, 0, len(t.tableMap)) | ||
for _, table := range t.tableMap { | ||
tables = append(tables, table) | ||
} | ||
|
||
return tables | ||
} | ||
|
||
// NewBatch creates a new batch for writing to the store. | ||
func (t *tableStore) NewBatch() kvstore.TableBatch { | ||
return &tableStoreBatch{ | ||
store: t, | ||
batch: t.base.NewBatch(), | ||
} | ||
} | ||
|
||
// Shutdown shuts down the store, flushing any remaining cached data to disk. | ||
func (t *tableStore) Shutdown() error { | ||
return t.base.Shutdown() | ||
} | ||
|
||
// Destroy shuts down and permanently deletes all data in the store. | ||
func (t *tableStore) Destroy() error { | ||
return t.base.Destroy() | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
package tablestore | ||
|
||
import "github.com/Layr-Labs/eigenda/common/kvstore" | ||
|
||
// tableStoreBatch is a batch for writing to a table store. | ||
type tableStoreBatch struct { | ||
store *tableStore | ||
batch kvstore.StoreBatch | ||
} | ||
|
||
// Put adds a key-value pair to the batch. | ||
func (t *tableStoreBatch) Put(key kvstore.TableKey, value []byte) { | ||
if value == nil { | ||
value = []byte{} | ||
} | ||
t.batch.Put(key, value) | ||
} | ||
|
||
// Delete removes a key-value pair from the batch. | ||
func (t *tableStoreBatch) Delete(key kvstore.TableKey) { | ||
t.batch.Delete(key) | ||
} | ||
|
||
// Apply applies the batch to the store. | ||
func (t *tableStoreBatch) Apply() error { | ||
return t.batch.Apply() | ||
} | ||
|
||
// Size returns the number of operations in the batch. | ||
func (t *tableStoreBatch) Size() uint32 { | ||
return t.batch.Size() | ||
} |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit:
can be written
->will be written
atomically?Mention that the Batch is not thread safe
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oops, noticed this after I pressed the merge button. I will include this change in the follow up PR I am working on right now.