diff options
author | Jakob Borg <jakob@nym.se> | 2015-08-06 11:29:25 +0200 |
---|---|---|
committer | Jakob Borg <jakob@nym.se> | 2015-08-09 09:35:26 +0200 |
commit | 7705a6c1f165a9a81856d0c493eac5042b6e18bf (patch) | |
tree | 4def8ef959ea73e655edd0189e7ee88ef57377f4 /lib/db/namespaced.go | |
parent | 0a803891a465254376ed776ee82aa4220fc2eb23 (diff) |
mv internal lib
Diffstat (limited to 'lib/db/namespaced.go')
-rw-r--r-- | lib/db/namespaced.go | 159 |
1 files changed, 159 insertions, 0 deletions
diff --git a/lib/db/namespaced.go b/lib/db/namespaced.go new file mode 100644 index 0000000000..d1b1bf15a0 --- /dev/null +++ b/lib/db/namespaced.go @@ -0,0 +1,159 @@ +// Copyright (C) 2014 The Syncthing Authors. +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this file, +// You can obtain one at http://mozilla.org/MPL/2.0/. + +package db + +import ( + "encoding/binary" + "time" + + "github.com/syndtr/goleveldb/leveldb" + "github.com/syndtr/goleveldb/leveldb/util" +) + +// NamespacedKV is a simple key-value store using a specific namespace within +// a leveldb. +type NamespacedKV struct { + db *leveldb.DB + prefix []byte +} + +// NewNamespacedKV returns a new NamespacedKV that lives in the namespace +// specified by the prefix. +func NewNamespacedKV(db *leveldb.DB, prefix string) *NamespacedKV { + return &NamespacedKV{ + db: db, + prefix: []byte(prefix), + } +} + +// Reset removes all entries in this namespace. +func (n *NamespacedKV) Reset() { + it := n.db.NewIterator(util.BytesPrefix(n.prefix), nil) + defer it.Release() + batch := new(leveldb.Batch) + for it.Next() { + batch.Delete(it.Key()) + if batch.Len() > batchFlushSize { + if err := n.db.Write(batch, nil); err != nil { + panic(err) + } + batch.Reset() + } + } + if batch.Len() > 0 { + if err := n.db.Write(batch, nil); err != nil { + panic(err) + } + } +} + +// PutInt64 stores a new int64. Any existing value (even if of another type) +// is overwritten. +func (n *NamespacedKV) PutInt64(key string, val int64) { + keyBs := append(n.prefix, []byte(key)...) + var valBs [8]byte + binary.BigEndian.PutUint64(valBs[:], uint64(val)) + n.db.Put(keyBs, valBs[:], nil) +} + +// Int64 returns the stored value interpreted as an int64 and a boolean that +// is false if no value was stored at the key. +func (n *NamespacedKV) Int64(key string) (int64, bool) { + keyBs := append(n.prefix, []byte(key)...) + valBs, err := n.db.Get(keyBs, nil) + if err != nil { + return 0, false + } + val := binary.BigEndian.Uint64(valBs) + return int64(val), true +} + +// PutTime stores a new time.Time. Any existing value (even if of another +// type) is overwritten. +func (n *NamespacedKV) PutTime(key string, val time.Time) { + keyBs := append(n.prefix, []byte(key)...) + valBs, _ := val.MarshalBinary() // never returns an error + n.db.Put(keyBs, valBs, nil) +} + +// Time returns the stored value interpreted as a time.Time and a boolean +// that is false if no value was stored at the key. +func (n NamespacedKV) Time(key string) (time.Time, bool) { + var t time.Time + keyBs := append(n.prefix, []byte(key)...) + valBs, err := n.db.Get(keyBs, nil) + if err != nil { + return t, false + } + err = t.UnmarshalBinary(valBs) + return t, err == nil +} + +// PutString stores a new string. Any existing value (even if of another type) +// is overwritten. +func (n *NamespacedKV) PutString(key, val string) { + keyBs := append(n.prefix, []byte(key)...) + n.db.Put(keyBs, []byte(val), nil) +} + +// String returns the stored value interpreted as a string and a boolean that +// is false if no value was stored at the key. +func (n NamespacedKV) String(key string) (string, bool) { + keyBs := append(n.prefix, []byte(key)...) + valBs, err := n.db.Get(keyBs, nil) + if err != nil { + return "", false + } + return string(valBs), true +} + +// PutBytes stores a new byte slice. Any existing value (even if of another type) +// is overwritten. +func (n *NamespacedKV) PutBytes(key string, val []byte) { + keyBs := append(n.prefix, []byte(key)...) + n.db.Put(keyBs, val, nil) +} + +// Bytes returns the stored value as a raw byte slice and a boolean that +// is false if no value was stored at the key. +func (n NamespacedKV) Bytes(key string) ([]byte, bool) { + keyBs := append(n.prefix, []byte(key)...) + valBs, err := n.db.Get(keyBs, nil) + if err != nil { + return nil, false + } + return valBs, true +} + +// PutBool stores a new boolean. Any existing value (even if of another type) +// is overwritten. +func (n *NamespacedKV) PutBool(key string, val bool) { + keyBs := append(n.prefix, []byte(key)...) + if val { + n.db.Put(keyBs, []byte{0x0}, nil) + } else { + n.db.Put(keyBs, []byte{0x1}, nil) + } +} + +// Bool returns the stored value as a boolean and a boolean that +// is false if no value was stored at the key. +func (n NamespacedKV) Bool(key string) (bool, bool) { + keyBs := append(n.prefix, []byte(key)...) + valBs, err := n.db.Get(keyBs, nil) + if err != nil { + return false, false + } + return valBs[0] == 0x0, true +} + +// Delete deletes the specified key. It is allowed to delete a nonexistent +// key. +func (n NamespacedKV) Delete(key string) { + keyBs := append(n.prefix, []byte(key)...) + n.db.Delete(keyBs, nil) +} |