mirror of https://github.com/hak5/bolt.git
196 lines
4.1 KiB
Markdown
196 lines
4.1 KiB
Markdown
Bolt
|
|
====
|
|
|
|
## Overview
|
|
|
|
A low-level key/value database for Go.
|
|
|
|
|
|
## API
|
|
|
|
### Database
|
|
|
|
The database is the object that represents your data as a whole
|
|
It is split up into buckets which is analogous to tables in a relational database.
|
|
|
|
#### Opening and closing a database
|
|
|
|
```go
|
|
db := DB()
|
|
err := db.Open("/path/to/db", 0666)
|
|
...
|
|
err := db.Close()
|
|
```
|
|
|
|
|
|
### Transactions
|
|
|
|
Versioning of data in the bucket data happens through a Transaction.
|
|
These transactions can be either be read-only or read/write transactions.
|
|
Transactions are what keeps Bolt consistent and allows data to be rolled back if needed.
|
|
|
|
It may seem strange that read-only access needs to be wrapped in a transaction but this is so Bolt can keep track of what version of the data is currently in use.
|
|
The space used to hold data is kept until the transaction closes.
|
|
|
|
One important note is that long running transactions can cause the database to grow in size quickly.
|
|
Please double check that you are appropriately closing all transactions after you're done with them.
|
|
|
|
#### Creating and closing a read-only transaction
|
|
|
|
```go
|
|
t, err := db.Transaction()
|
|
t.Close()
|
|
```
|
|
|
|
#### Creating and committing a read/write transaction
|
|
|
|
```
|
|
t, err := db.RWTransaction()
|
|
err := t.Commit()
|
|
```
|
|
|
|
#### Creating and aborting a read/write transaction
|
|
|
|
```
|
|
t, err := db.RWTransaction()
|
|
err := t.Abort()
|
|
```
|
|
|
|
|
|
### Buckets
|
|
|
|
Buckets are where your actual key/value data gets stored.
|
|
You can create new buckets from the database and look them up by name.
|
|
|
|
#### Creating a bucket
|
|
|
|
```go
|
|
t, err := db.RWTransaction()
|
|
err := t.CreateBucket("widgets")
|
|
```
|
|
|
|
#### Renaming a bucket
|
|
|
|
```go
|
|
t, err := db.RWTransaction()
|
|
err := t.RenameBucket("widgets", "woojits")
|
|
```
|
|
|
|
#### Deleting a bucket
|
|
|
|
```go
|
|
t, err := db.RWTransaction()
|
|
err := t.DeleteBucket("widgets")
|
|
```
|
|
|
|
#### Retrieve an existing bucket
|
|
|
|
```go
|
|
t, err := db.Transaction()
|
|
b, err := t.Bucket("widgets")
|
|
```
|
|
|
|
#### Retrieve a list of all buckets
|
|
|
|
```go
|
|
t, err := db.Transaction()
|
|
buckets, err := db.Buckets()
|
|
```
|
|
|
|
|
|
|
|
### Cursors
|
|
|
|
Cursors provide access to a specific bucket within a transaction.
|
|
|
|
|
|
#### Creating a read-only cursor
|
|
|
|
```go
|
|
t, err := db.Transaction()
|
|
c, err := b.Cursor("widgets")
|
|
```
|
|
|
|
#### Creating a read/write cursor
|
|
|
|
```go
|
|
t, err := db.RWTransaction()
|
|
c, err := t.RWCursor("widgets")
|
|
```
|
|
|
|
#### Iterating over a cursor
|
|
|
|
```go
|
|
for k, v, err := c.First(); k != nil; k, v, err = c.Next() {
|
|
if err != nil {
|
|
return err
|
|
}
|
|
... DO SOMETHING ...
|
|
}
|
|
```
|
|
|
|
#### Retrieve a value for a specific key
|
|
|
|
```go
|
|
value, err := c.Get([]byte("foo"))
|
|
value, err := c.GetString("foo")
|
|
```
|
|
|
|
#### Set the value for a key (RWCursor only)
|
|
|
|
```go
|
|
err := c.Put([]byte("foo"), []byte("bar"))
|
|
err := c.PutString("foo", "bar")
|
|
```
|
|
|
|
#### Delete a given key
|
|
|
|
```go
|
|
err := c.Delete([]byte("foo"))
|
|
err := c.DeleteString("foo")
|
|
```
|
|
|
|
|
|
## Internals
|
|
|
|
The Bolt database is meant to be a clean, readable implementation of a fast single-level key/value data store.
|
|
This section gives an overview of the basic concepts and structure of the file format.
|
|
|
|
### B+ Tree
|
|
|
|
Bolt uses a data structure called an append-only B+ tree to store its data.
|
|
This structure allows for efficient traversal of data.
|
|
|
|
TODO: Explain better. :)
|
|
|
|
|
|
### Pages
|
|
|
|
Bolt stores its data in discrete units called pages.
|
|
The page size can be configured but is typically between 4KB and 32KB.
|
|
|
|
There are several different types of pages:
|
|
|
|
* Meta pages - The first two pages in a database are meta pages. These are used to store references to root pages for system buckets as well as keep track of the last transaction identifier.
|
|
|
|
* Branch pages - These pages store references to the location of deeper branch pages or leaf pages.
|
|
|
|
* Leaf pages - These pages store the actual key/value data.
|
|
|
|
* Overflow pages - These are special pages used when a key's data is too large for a leaf page and needs to spill onto additional pages.
|
|
|
|
|
|
### Nodes
|
|
|
|
Within each page there are one or more elements called nodes.
|
|
In branch pages, these nodes store references to other child pages in the tree.
|
|
In leaf pages, these nodes store the actual key/value data.
|
|
|
|
|
|
## TODO
|
|
|
|
The following is a list of items to do on the Bolt project:
|
|
|
|
1. Resize map. (Make sure there are no reader txns before resizing)
|
|
2. DB.Copy()
|