diff options
| author | r <r@freesoftwareextremist.com> | 2019-12-17 20:17:25 +0000 | 
|---|---|---|
| committer | r <r@freesoftwareextremist.com> | 2019-12-17 20:17:25 +0000 | 
| commit | 59aad78f66cf58be7f88f2c0675f94a858163560 (patch) | |
| tree | 95f00d18a8c847cdf4ee587e412de26960770a28 /kv | |
| parent | 3b50f40c081c499c2ecb8913b54186c622561d76 (diff) | |
| download | bloat-59aad78f66cf58be7f88f2c0675f94a858163560.tar.gz bloat-59aad78f66cf58be7f88f2c0675f94a858163560.zip | |
Use filesystem based kv store instead of sqlite
Diffstat (limited to 'kv')
| -rw-r--r-- | kv/kv.go | 92 | 
1 files changed, 92 insertions, 0 deletions
| diff --git a/kv/kv.go b/kv/kv.go new file mode 100644 index 0000000..2cfcd60 --- /dev/null +++ b/kv/kv.go @@ -0,0 +1,92 @@ +package kv + +import ( +	"errors" +	"io/ioutil" +	"os" +	"path/filepath" +	"strings" +	"sync" +) + +var ( +	errInvalidKey = errors.New("invalid key") +	errNoSuchKey  = errors.New("no such key") +) + +type Database struct { +	data    map[string][]byte +	basedir string +	m       sync.RWMutex +} + +func NewDatabse(basedir string) (db *Database, err error) { +	err = os.Mkdir(basedir, 0755) +	if err != nil && !os.IsExist(err) { +		return +	} + +	return &Database{ +		data:    make(map[string][]byte), +		basedir: basedir, +	}, nil +} + +func (db *Database) Set(key string, val []byte) (err error) { +	if len(key) < 1 { +		return errInvalidKey +	} + +	db.m.Lock() +	defer func() { +		if err != nil { +			delete(db.data, key) +		} +		db.m.Unlock() +	}() + +	db.data[key] = val + +	err = ioutil.WriteFile(filepath.Join(db.basedir, key), val, 0644) + +	return +} + +func (db *Database) Get(key string) (val []byte, err error) { +	if len(key) < 1 { +		return nil, errInvalidKey +	} + +	db.m.RLock() +	defer db.m.RUnlock() + +	data, ok := db.data[key] +	if !ok { +		data, err = ioutil.ReadFile(filepath.Join(db.basedir, key)) +		if err != nil { +			err = errNoSuchKey +			return nil, err +		} + +		db.data[key] = data +	} + +	val = make([]byte, len(data)) +	copy(val, data) + +	return +} + +func (db *Database) Remove(key string) { +	if len(key) < 1 || strings.ContainsRune(key, os.PathSeparator) { +		return +	} + +	db.m.Lock() +	defer db.m.Unlock() + +	delete(db.data, key) +	os.Remove(filepath.Join(db.basedir, key)) + +	return +} | 
