mirror of https://github.com/etcd-io/bbolt.git
107 lines
2.2 KiB
Go
107 lines
2.2 KiB
Go
package bolt
|
|
|
|
// RWCursor represents a cursor that can read and write data for a bucket.
|
|
type RWCursor struct {
|
|
Cursor
|
|
transaction *RWTransaction
|
|
}
|
|
|
|
func (c *RWCursor) Put(key []byte, value []byte) error {
|
|
// Make sure this cursor was created by a transaction.
|
|
if c.transaction == nil {
|
|
return &Error{"invalid cursor", nil}
|
|
}
|
|
db := c.transaction.db
|
|
|
|
// Validate the key we're using.
|
|
if key == nil {
|
|
return &Error{"key required", nil}
|
|
} else if len(key) > db.maxKeySize {
|
|
return &Error{"key too large", nil}
|
|
}
|
|
|
|
// TODO: Validate data size based on MaxKeySize if DUPSORT.
|
|
|
|
// Validate the size of our data.
|
|
if len(data) > MaxDataSize {
|
|
return &Error{"data too large", nil}
|
|
}
|
|
|
|
// If we don't have a root page then add one.
|
|
if c.bucket.root == p_invalid {
|
|
p, err := c.newLeafPage()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
c.push(p)
|
|
c.bucket.root = p.id
|
|
c.bucket.root++
|
|
// TODO: *mc->mc_dbflag |= DB_DIRTY;
|
|
// TODO? mc->mc_flags |= C_INITIALIZED;
|
|
}
|
|
|
|
// TODO: Move to key.
|
|
exists, err := c.moveTo(key)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// TODO: spill?
|
|
if err := c.spill(key, data); err != nil {
|
|
return err
|
|
}
|
|
|
|
// Make sure all cursor pages are writable
|
|
if err := c.touch(); err != nil {
|
|
return err
|
|
}
|
|
|
|
// If key does not exist the
|
|
if exists {
|
|
node := c.currentNode()
|
|
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (c *Cursor) Delete(key []byte) error {
|
|
// TODO: Traverse to the correct node.
|
|
// TODO: If missing, exit.
|
|
// TODO: Remove node from page.
|
|
// TODO: If page is empty then add it to the freelist.
|
|
return nil
|
|
}
|
|
|
|
// newLeafPage allocates and initialize new a new leaf page.
|
|
func (c *RWCursor) newLeafPage() (*page, error) {
|
|
// Allocate page.
|
|
p, err := c.allocatePage(1)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// Set flags and bounds.
|
|
p.flags = p_leaf | p_dirty
|
|
p.lower = pageHeaderSize
|
|
p.upper = c.transaction.db.pageSize
|
|
|
|
return p, nil
|
|
}
|
|
|
|
// newBranchPage allocates and initialize new a new branch page.
|
|
func (b *RWCursor) newBranchPage() (*page, error) {
|
|
// Allocate page.
|
|
p, err := c.allocatePage(1)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// Set flags and bounds.
|
|
p.flags = p_branch | p_dirty
|
|
p.lower = pageHeaderSize
|
|
p.upper = c.transaction.db.pageSize
|
|
|
|
return p, nil
|
|
}
|