|
|
|
@ -12,20 +12,20 @@ import (
|
|
|
|
|
var ErrClosed = errors.New("database has been closed")
|
|
|
|
|
|
|
|
|
|
type DB struct {
|
|
|
|
|
sync.RWMutex // Locking
|
|
|
|
|
data map[string]string // Current state of the database
|
|
|
|
|
file *os.File // Data storage
|
|
|
|
|
sync.RWMutex // locking
|
|
|
|
|
data map[string]string // current state of the database
|
|
|
|
|
file *os.File // data storage
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Open an existing database file, loading the contents to memory
|
|
|
|
|
// OpenDB opens an existing database file, loading the contents to memory.
|
|
|
|
|
func OpenDB(path string) (*DB, error) {
|
|
|
|
|
file, err := os.OpenFile(path, os.O_RDWR, 0 /* not used */)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// TODO we might want a recover flag that just reads as much as it can
|
|
|
|
|
// instead of returning io.ErrUnexpectedEOF
|
|
|
|
|
// TODO: We might want a recover flag that just reads as much as it can
|
|
|
|
|
// instead of returning io.ErrUnexpectedEOF.
|
|
|
|
|
db := &DB{data: make(map[string]string), file: file}
|
|
|
|
|
for {
|
|
|
|
|
var header struct{ KeyLen, ValueLen int32 }
|
|
|
|
@ -64,7 +64,7 @@ func OpenDB(path string) (*DB, error) {
|
|
|
|
|
return db, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Create a new database, overwriting any previous contents of the file
|
|
|
|
|
// CreateDB creates a new database, overwriting any previous file contents.
|
|
|
|
|
func CreateDB(path string) (*DB, error) {
|
|
|
|
|
file, err := os.OpenFile(path, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0644)
|
|
|
|
|
if err != nil {
|
|
|
|
@ -73,7 +73,7 @@ func CreateDB(path string) (*DB, error) {
|
|
|
|
|
return &DB{data: make(map[string]string), file: file}, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Retrieve the value corresponding to the given key
|
|
|
|
|
// Get retrieves the value corresponding to the given key.
|
|
|
|
|
func (db *DB) Get(key string) (string, bool, error) {
|
|
|
|
|
db.RLock()
|
|
|
|
|
defer db.RUnlock()
|
|
|
|
@ -106,7 +106,7 @@ func put(file *os.File, key, value string) error {
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Save a key-value pair in the database storage
|
|
|
|
|
// Put saves a key-value pair in the database storage.
|
|
|
|
|
func (db *DB) Put(key, value string) error {
|
|
|
|
|
db.Lock()
|
|
|
|
|
defer db.Unlock()
|
|
|
|
@ -127,7 +127,7 @@ func (db *DB) Put(key, value string) error {
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Delete a key from the database storage
|
|
|
|
|
// Delete deletes a key from the database storage.
|
|
|
|
|
func (db *DB) Delete(key string) error {
|
|
|
|
|
db.Lock()
|
|
|
|
|
defer db.Unlock()
|
|
|
|
@ -157,7 +157,7 @@ func (db *DB) Delete(key string) error {
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Get rid of historical data in the database file
|
|
|
|
|
// Checkpoint gets rid of historical data in the database file.
|
|
|
|
|
func (db *DB) Checkpoint() error {
|
|
|
|
|
db.Lock()
|
|
|
|
|
defer db.Unlock()
|
|
|
|
@ -194,7 +194,7 @@ func (db *DB) Checkpoint() error {
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Close the database file, rendering the object unusable
|
|
|
|
|
// Close closes the database file, rendering the object unusable.
|
|
|
|
|
func (db *DB) Close() error {
|
|
|
|
|
db.Lock()
|
|
|
|
|
defer db.Unlock()
|
|
|
|
|