@cryptotaxi247 / kubo / commits / 8a7f6aca9

godeps: updated datastore

Juan Batiz-Benet committed Oct 3, 2014 at 14:38 UTC 8a7f6aca99cf6018bff6b0a20b8ad14a59d27bee
15 files changed +546 -27
Godeps/Godeps.json
+1 -1
@@ -64,7 +64,7 @@
64 },
65 {
66 "ImportPath": "github.com/jbenet/datastore.go",
67 - "Rev": "e89f0511689bb2d0608496e15491f241842de085"
67 + "Rev": "e7d6f7cb9e3c207a04c5397c449d10a6f9d403a0"
68 },
69 {
70 "ImportPath": "github.com/jbenet/go-base58",
Godeps/_workspace/src/github.com/jbenet/datastore.go/Godeps/Godeps.json new
+43
@@ -0,0 +1,43 @@
1 +{
2 + "ImportPath": "github.com/jbenet/datastore.go",
3 + "GoVersion": "go1.3.1",
4 + "Packages": [
5 + "./..."
6 + ],
7 + "Deps": [
8 + {
9 + "ImportPath": "code.google.com/p/go-uuid/uuid",
10 + "Comment": "null-12",
11 + "Rev": "7dda39b2e7d5e265014674c5af696ba4186679e9"
12 + },
13 + {
14 + "ImportPath": "code.google.com/p/snappy-go/snappy",
15 + "Comment": "null-15",
16 + "Rev": "12e4b4183793ac4b061921e7980845e750679fd0"
17 + },
18 + {
19 + "ImportPath": "github.com/codahale/blake2",
20 + "Rev": "3fa823583afba430e8fc7cdbcc670dbf90bfacc4"
21 + },
22 + {
23 + "ImportPath": "github.com/hashicorp/golang-lru",
24 + "Rev": "4dfff096c4973178c8f35cf6dd1a732a0a139370"
25 + },
26 + {
27 + "ImportPath": "github.com/mattbaird/elastigo/api",
28 + "Rev": "041b88c1fcf6489a5721ede24378ce1253b9159d"
29 + },
30 + {
31 + "ImportPath": "github.com/mattbaird/elastigo/core",
32 + "Rev": "041b88c1fcf6489a5721ede24378ce1253b9159d"
33 + },
34 + {
35 + "ImportPath": "github.com/syndtr/goleveldb/leveldb",
36 + "Rev": "9bca75c48d6c31becfbb127702b425e7226052e3"
37 + },
38 + {
39 + "ImportPath": "gopkg.in/check.v1",
40 + "Rev": "91ae5f88a67b14891cfd43895b01164f6c120420"
41 + }
42 + ]
43 +}
Godeps/_workspace/src/github.com/jbenet/datastore.go/Godeps/Readme new
+5
@@ -0,0 +1,5 @@
1 +This directory tree is generated automatically by godep.
2 +
3 +Please do not edit.
4 +
5 +See https://github.com/tools/godep for more information.
Godeps/_workspace/src/github.com/jbenet/datastore.go/basic_ds.go
+47 -18
@@ -1,28 +1,30 @@
1 package datastore
2
3 -import (
4 - "log"
5 -)
3 +import "log"
4
5 // Here are some basic datastore implementations.
6
9 -// MapDatastore uses a standard Go map for internal storage.
7 type keyMap map[Key]interface{}
8 +
9 +// MapDatastore uses a standard Go map for internal storage.
10 type MapDatastore struct {
11 values keyMap
12 }
13
14 +// NewMapDatastore constructs a MapDatastore
15 func NewMapDatastore() (d *MapDatastore) {
16 return &MapDatastore{
17 values: keyMap{},
18 }
19 }
20
21 +// Put implements Datastore.Put
22 func (d *MapDatastore) Put(key Key, value interface{}) (err error) {
23 d.values[key] = value
24 return nil
25 }
26
27 +// Get implements Datastore.Get
28 func (d *MapDatastore) Get(key Key) (value interface{}, err error) {
29 val, found := d.values[key]
30 if !found {
@@ -31,19 +33,22 @@ func (d *MapDatastore) Get(key Key) (value interface{}, err error) {
33 return val, nil
34 }
35
36 +// Has implements Datastore.Has
37 func (d *MapDatastore) Has(key Key) (exists bool, err error) {
38 _, found := d.values[key]
39 return found, nil
40 }
41
42 +// Delete implements Datastore.Delete
43 func (d *MapDatastore) Delete(key Key) (err error) {
44 delete(d.values, key)
45 return nil
46 }
47
48 +// KeyList implements Datastore.KeyList
49 func (d *MapDatastore) KeyList() ([]Key, error) {
50 var keys []Key
46 - for k, _ := range d.values {
51 + for k := range d.values {
52 keys = append(keys, k)
53 }
54 return keys, nil
@@ -54,26 +59,32 @@ func (d *MapDatastore) KeyList() ([]Key, error) {
59 type NullDatastore struct {
60 }
61
62 +// NewNullDatastore constructs a null datastoe
63 func NewNullDatastore() *NullDatastore {
64 return &NullDatastore{}
65 }
66
67 +// Put implements Datastore.Put
68 func (d *NullDatastore) Put(key Key, value interface{}) (err error) {
69 return nil
70 }
71
72 +// Get implements Datastore.Get
73 func (d *NullDatastore) Get(key Key) (value interface{}, err error) {
74 return nil, nil
75 }
76
77 +// Has implements Datastore.Has
78 func (d *NullDatastore) Has(key Key) (exists bool, err error) {
79 return false, nil
80 }
81
82 +// Delete implements Datastore.Delete
83 func (d *NullDatastore) Delete(key Key) (err error) {
84 return nil
85 }
86
87 +// KeyList implements Datastore.KeyList
88 func (d *NullDatastore) KeyList() ([]Key, error) {
89 return nil, nil
90 }
@@ -81,38 +92,56 @@ func (d *NullDatastore) KeyList() ([]Key, error) {
92 // LogDatastore logs all accesses through the datastore.
93 type LogDatastore struct {
94 Name string
84 - Child Datastore
95 + child Datastore
96 +}
97 +
98 +// Shim is a datastore which has a child.
99 +type Shim interface {
100 + Datastore
101 +
102 + Children() []Datastore
103 }
104
87 -func NewLogDatastore(ds Datastore, name string) *LogDatastore {
105 +// NewLogDatastore constructs a log datastore.
106 +func NewLogDatastore(ds Datastore, name string) Shim {
107 if len(name) < 1 {
108 name = "LogDatastore"
109 }
91 - return &LogDatastore{Name: name, Child: ds}
110 + return &LogDatastore{Name: name, child: ds}
111 +}
112 +
113 +// Children implements Shim
114 +func (d *LogDatastore) Children() []Datastore {
115 + return []Datastore{d.child}
116 }
117
118 +// Put implements Datastore.Put
119 func (d *LogDatastore) Put(key Key, value interface{}) (err error) {
95 - log.Printf("%s: Put %s", d.Name, key)
120 + log.Printf("%s: Put %s\n", d.Name, key)
121 // log.Printf("%s: Put %s ```%s```", d.Name, key, value)
97 - return d.Child.Put(key, value)
122 + return d.child.Put(key, value)
123 }
124
125 +// Get implements Datastore.Get
126 func (d *LogDatastore) Get(key Key) (value interface{}, err error) {
101 - log.Printf("%s: Get %s", d.Name, key)
102 - return d.Child.Get(key)
127 + log.Printf("%s: Get %s\n", d.Name, key)
128 + return d.child.Get(key)
129 }
130
131 +// Has implements Datastore.Has
132 func (d *LogDatastore) Has(key Key) (exists bool, err error) {
106 - log.Printf("%s: Has %s", d.Name, key)
107 - return d.Child.Has(key)
133 + log.Printf("%s: Has %s\n", d.Name, key)
134 + return d.child.Has(key)
135 }
136
137 +// Delete implements Datastore.Delete
138 func (d *LogDatastore) Delete(key Key) (err error) {
111 - log.Printf("%s: Delete %s", d.Name, key)
112 - return d.Child.Delete(key)
139 + log.Printf("%s: Delete %s\n", d.Name, key)
140 + return d.child.Delete(key)
141 }
142
143 +// KeyList implements Datastore.KeyList
144 func (d *LogDatastore) KeyList() ([]Key, error) {
116 - log.Printf("%s: Get KeyList.", d.Name)
117 - return d.Child.KeyList()
145 + log.Printf("%s: Get KeyList\n", d.Name)
146 + return d.child.KeyList()
147 }
Godeps/_workspace/src/github.com/jbenet/datastore.go/basic_ds_test.go new
+13
@@ -0,0 +1,13 @@
1 +package datastore_test
2 +
3 +import (
4 + . "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/datastore.go"
5 + . "launchpad.net/gocheck"
6 +)
7 +
8 +// Hook up gocheck into the "go test" runner.
9 +func Test(t *testing.T) { TestingT(t) }
10 +
11 +type BasicSuite struct{}
12 +
13 +var _ = Suite(&BasicSuite{})
Godeps/_workspace/src/github.com/jbenet/datastore.go/datastore.go
+11 -5
@@ -5,7 +5,7 @@ import (
5 )
6
7 /*
8 -A Datastore represents storage for any key-value pair.
8 +Datastore represents storage for any key-value pair.
9
10 Datastores are general enough to be backed by all kinds of different storage:
11 in-memory caches, databases, a remote datastore, flat files on disk, etc.
@@ -27,7 +27,6 @@ and thus it should behave predictably and handle exceptional conditions with
27 proper error reporting. Thus, all Datastore calls may return errors, which
28 should be checked by callers.
29 */
30 -
30 type Datastore interface {
31 // Put stores the object `value` named by `key`.
32 //
@@ -53,20 +52,27 @@ type Datastore interface {
52 // Delete removes the value for given `key`.
53 Delete(key Key) (err error)
54
56 - // Returns a list of keys in the datastore
55 + // KeyList returns a list of keys in the datastore
56 KeyList() ([]Key, error)
57 }
58
59 +// ThreadSafeDatastore is an interface that all threadsafe datastore should
60 +// implement to leverage type safety checks.
61 +type ThreadSafeDatastore interface {
62 + Datastore
63 + IsThreadSafe()
64 +}
65 +
66 // Errors
67
68 // ErrNotFound is returned by Get, Has, and Delete when a datastore does not
69 // map the given key to a value.
64 -var ErrNotFound = errors.New("datastore: key not found.")
70 +var ErrNotFound = errors.New("datastore: key not found")
71
72 // ErrInvalidType is returned by Put when a given value is incopatible with
73 // the type the datastore supports. This means a conversion (or serialization)
74 // is needed beforehand.
69 -var ErrInvalidType = errors.New("datastore: invalid type error.")
75 +var ErrInvalidType = errors.New("datastore: invalid type error")
76
77 // GetBackedHas provides a default Datastore.Has implementation.
78 // It exists so Datastore.Has implementations can use it, like so:
Godeps/_workspace/src/github.com/jbenet/datastore.go/fs/fs.go new
+122
@@ -0,0 +1,122 @@
1 +package fs
2 +
3 +import (
4 + "fmt"
5 + "io/ioutil"
6 + "os"
7 + "path/filepath"
8 + "strings"
9 +
10 + ds "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/datastore.go"
11 +)
12 +
13 +// Datastore uses a standard Go map for internal storage.
14 +type Datastore struct {
15 + path string
16 +}
17 +
18 +// NewDatastore returns a new fs Datastore at given `path`
19 +func NewDatastore(path string) (ds.Datastore, error) {
20 + if !isDir(path) {
21 + return nil, fmt.Errorf("Failed to find directory at: %v (file? perms?)", path)
22 + }
23 +
24 + return &Datastore{path: path}, nil
25 +}
26 +
27 +// KeyFilename returns the filename associated with `key`
28 +func (d *Datastore) KeyFilename(key ds.Key) string {
29 + return filepath.Join(d.path, key.String(), ".dsobject")
30 +}
31 +
32 +// Put stores the given value.
33 +func (d *Datastore) Put(key ds.Key, value interface{}) (err error) {
34 +
35 + // TODO: maybe use io.Readers/Writers?
36 + // r, err := dsio.CastAsReader(value)
37 + // if err != nil {
38 + // return err
39 + // }
40 +
41 + val, ok := value.([]byte)
42 + if !ok {
43 + return ds.ErrInvalidType
44 + }
45 +
46 + fn := d.KeyFilename(key)
47 +
48 + // mkdirall above.
49 + err = os.MkdirAll(filepath.Dir(fn), 0755)
50 + if err != nil {
51 + return err
52 + }
53 +
54 + return ioutil.WriteFile(fn, val, 0666)
55 +}
56 +
57 +// Get returns the value for given key
58 +func (d *Datastore) Get(key ds.Key) (value interface{}, err error) {
59 + fn := d.KeyFilename(key)
60 + if !isFile(fn) {
61 + return nil, ds.ErrNotFound
62 + }
63 +
64 + return ioutil.ReadFile(fn)
65 +}
66 +
67 +// Has returns whether the datastore has a value for a given key
68 +func (d *Datastore) Has(key ds.Key) (exists bool, err error) {
69 + return ds.GetBackedHas(d, key)
70 +}
71 +
72 +// Delete removes the value for given key
73 +func (d *Datastore) Delete(key ds.Key) (err error) {
74 + fn := d.KeyFilename(key)
75 + if !isFile(fn) {
76 + return ds.ErrNotFound
77 + }
78 +
79 + return os.Remove(fn)
80 +}
81 +
82 +// KeyList returns a list of all keys in the datastore
83 +func (d *Datastore) KeyList() ([]ds.Key, error) {
84 +
85 + keys := []ds.Key{}
86 +
87 + walkFn := func(path string, info os.FileInfo, err error) error {
88 + // remove ds path prefix
89 + if strings.HasPrefix(path, d.path) {
90 + path = path[len(d.path):]
91 + }
92 +
93 + if !info.IsDir() {
94 + key := ds.NewKey(path)
95 + keys = append(keys, key)
96 + }
97 + return nil
98 + }
99 +
100 + filepath.Walk(d.path, walkFn)
101 + return keys, nil
102 +}
103 +
104 +// isDir returns whether given path is a directory
105 +func isDir(path string) bool {
106 + finfo, err := os.Stat(path)
107 + if err != nil {
108 + return false
109 + }
110 +
111 + return finfo.IsDir()
112 +}
113 +
114 +// isFile returns whether given path is a file
115 +func isFile(path string) bool {
116 + finfo, err := os.Stat(path)
117 + if err != nil {
118 + return false
119 + }
120 +
121 + return !finfo.IsDir()
122 +}
Godeps/_workspace/src/github.com/jbenet/datastore.go/fs/fs_test.go new
+65
@@ -0,0 +1,65 @@
1 +package fs_test
2 +
3 +import (
4 + "bytes"
5 + "testing"
6 +
7 + ds "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/datastore.go"
8 + fs "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/datastore.go/fs"
9 + . "launchpad.net/gocheck"
10 +)
11 +
12 +// Hook up gocheck into the "go test" runner.
13 +func Test(t *testing.T) { TestingT(t) }
14 +
15 +type DSSuite struct {
16 + dir string
17 + ds ds.Datastore
18 +}
19 +
20 +var _ = Suite(&DSSuite{})
21 +
22 +func (ks *DSSuite) SetUpTest(c *C) {
23 + ks.dir = c.MkDir()
24 + ks.ds, _ = fs.NewDatastore(ks.dir)
25 +}
26 +
27 +func (ks *DSSuite) TestOpen(c *C) {
28 + _, err := fs.NewDatastore("/tmp/foo/bar/baz")
29 + c.Assert(err, Not(Equals), nil)
30 +
31 + // setup ds
32 + _, err = fs.NewDatastore(ks.dir)
33 + c.Assert(err, Equals, nil)
34 +}
35 +
36 +func (ks *DSSuite) TestBasic(c *C) {
37 +
38 + keys := strsToKeys([]string{
39 + "foo",
40 + "foo/bar",
41 + "foo/bar/baz",
42 + "foo/barb",
43 + "foo/bar/bazb",
44 + "foo/bar/baz/barb",
45 + })
46 +
47 + for _, k := range keys {
48 + err := ks.ds.Put(k, []byte(k.String()))
49 + c.Check(err, Equals, nil)
50 + }
51 +
52 + for _, k := range keys {
53 + v, err := ks.ds.Get(k)
54 + c.Check(err, Equals, nil)
55 + c.Check(bytes.Equal(v.([]byte), []byte(k.String())), Equals, true)
56 + }
57 +}
58 +
59 +func strsToKeys(strs []string) []ds.Key {
60 + keys := make([]ds.Key, len(strs))
61 + for i, s := range strs {
62 + keys[i] = ds.NewKey(s)
63 + }
64 + return keys
65 +}
Godeps/_workspace/src/github.com/jbenet/datastore.go/io/io.go new
+44
@@ -0,0 +1,44 @@
1 +package leveldb
2 +
3 +import (
4 + "bytes"
5 + "io"
6 +
7 + ds "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/datastore.go"
8 +)
9 +
10 +// CastAsReader does type assertions to find the type of a value and attempts
11 +// to turn it into an io.Reader. If not possible, will return ds.ErrInvalidType
12 +func CastAsReader(value interface{}) (io.Reader, error) {
13 + switch v := value.(type) {
14 + case io.Reader:
15 + return v, nil
16 +
17 + case []byte:
18 + return bytes.NewReader(v), nil
19 +
20 + case string:
21 + return bytes.NewReader([]byte(v)), nil
22 +
23 + default:
24 + return nil, ds.ErrInvalidType
25 + }
26 +}
27 +
28 +// // CastAsWriter does type assertions to find the type of a value and attempts
29 +// // to turn it into an io.Writer. If not possible, will return ds.ErrInvalidType
30 +// func CastAsWriter(value interface{}) (err error) {
31 +// switch v := value.(type) {
32 +// case io.Reader:
33 +// return v, nil
34 +//
35 +// case []byte:
36 +// return bytes.NewReader(v), nil
37 +//
38 +// case string:
39 +// return bytes.NewReader([]byte(v)), nil
40 +//
41 +// default:
42 +// return nil, ds.ErrInvalidType
43 +// }
44 +// }
Godeps/_workspace/src/github.com/jbenet/datastore.go/key_test.go
+3 -2
@@ -2,12 +2,13 @@ package datastore_test
2
3 import (
4 "bytes"
5 - . "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/datastore.go"
6 - . "launchpad.net/gocheck"
5 "math/rand"
6 "path"
7 "strings"
8 "testing"
9 +
10 + . "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/datastore.go"
11 + . "gopkg.in/check.v1"
12 )
13
14 // Hook up gocheck into the "go test" runner.
Godeps/_workspace/src/github.com/jbenet/datastore.go/leveldb/datastore.go
+3 -1
@@ -13,7 +13,7 @@ type Datastore struct {
13
14 type Options opt.Options
15
16 -func NewDatastore(path string, opts *Options) (*Datastore, error) {
16 +func NewDatastore(path string, opts *Options) (ds.ThreadSafeDatastore, error) {
17 var nopts opt.Options
18 if opts != nil {
19 nopts = opt.Options(*opts)
@@ -76,3 +76,5 @@ func (d *Datastore) KeyList() ([]ds.Key, error) {
76 func (d *Datastore) Close() (err error) {
77 return d.DB.Close()
78 }
79 +
80 +func (d *Datastore) IsThreadSafe() {}
Godeps/_workspace/src/github.com/jbenet/datastore.go/lru/datastore.go new
+54
@@ -0,0 +1,54 @@
1 +package lru
2 +
3 +import (
4 + "errors"
5 +
6 + lru "github.com/hashicorp/golang-lru"
7 + ds "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/datastore.go"
8 +)
9 +
10 +// Datastore uses golang-lru for internal storage.
11 +type Datastore struct {
12 + cache *lru.Cache
13 +}
14 +
15 +// NewDatastore constructs a new LRU Datastore with given capacity.
16 +func NewDatastore(capacity int) (*Datastore, error) {
17 + cache, err := lru.New(capacity)
18 + if err != nil {
19 + return nil, err
20 + }
21 +
22 + return &Datastore{cache: cache}, nil
23 +}
24 +
25 +// Put stores the object `value` named by `key`.
26 +func (d *Datastore) Put(key ds.Key, value interface{}) (err error) {
27 + d.cache.Add(key, value)
28 + return nil
29 +}
30 +
31 +// Get retrieves the object `value` named by `key`.
32 +func (d *Datastore) Get(key ds.Key) (value interface{}, err error) {
33 + val, ok := d.cache.Get(key)
34 + if !ok {
35 + return nil, ds.ErrNotFound
36 + }
37 + return val, nil
38 +}
39 +
40 +// Has returns whether the `key` is mapped to a `value`.
41 +func (d *Datastore) Has(key ds.Key) (exists bool, err error) {
42 + return ds.GetBackedHas(d, key)
43 +}
44 +
45 +// Delete removes the value for given `key`.
46 +func (d *Datastore) Delete(key ds.Key) (err error) {
47 + d.cache.Remove(key)
48 + return nil
49 +}
50 +
51 +// KeyList returns a list of keys in the datastore
52 +func (d *Datastore) KeyList() ([]ds.Key, error) {
53 + return nil, errors.New("KeyList not implemented.")
54 +}
Godeps/_workspace/src/github.com/jbenet/datastore.go/lru/datastore_test.go new
+52
@@ -0,0 +1,52 @@
1 +package lru_test
2 +
3 +import (
4 + "strconv"
5 + "testing"
6 +
7 + ds "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/datastore.go"
8 + lru "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/datastore.go/lru"
9 + . "gopkg.in/check.v1"
10 +)
11 +
12 +// Hook up gocheck into the "go test" runner.
13 +func Test(t *testing.T) { TestingT(t) }
14 +
15 +type DSSuite struct{}
16 +
17 +var _ = Suite(&DSSuite{})
18 +
19 +func (ks *DSSuite) TestBasic(c *C) {
20 + var size = 1000
21 +
22 + d, err := lru.NewDatastore(size)
23 + c.Check(err, Equals, nil)
24 +
25 + for i := 0; i < size; i++ {
26 + err := d.Put(ds.NewKey(strconv.Itoa(i)), i)
27 + c.Check(err, Equals, nil)
28 + }
29 +
30 + for i := 0; i < size; i++ {
31 + j, err := d.Get(ds.NewKey(strconv.Itoa(i)))
32 + c.Check(j, Equals, i)
33 + c.Check(err, Equals, nil)
34 + }
35 +
36 + for i := 0; i < size; i++ {
37 + err := d.Put(ds.NewKey(strconv.Itoa(i+size)), i)
38 + c.Check(err, Equals, nil)
39 + }
40 +
41 + for i := 0; i < size; i++ {
42 + j, err := d.Get(ds.NewKey(strconv.Itoa(i)))
43 + c.Check(j, Equals, nil)
44 + c.Check(err, Equals, ds.ErrNotFound)
45 + }
46 +
47 + for i := 0; i < size; i++ {
48 + j, err := d.Get(ds.NewKey(strconv.Itoa(i + size)))
49 + c.Check(j, Equals, i)
50 + c.Check(err, Equals, nil)
51 + }
52 +}
Godeps/_workspace/src/github.com/jbenet/datastore.go/query.go new
+19
@@ -0,0 +1,19 @@
1 +package datastore
2 +
3 +// type KeyIterator struct {
4 +// HasNext() bool
5 +// Next() interface{}
6 +// }
7 +
8 +// type Query struct {
9 +// }
10 +
11 +/*
12 +QueryDatastores support a Query interface. Queries are used to support
13 +searching for values (beyond simple key-based `Get`s).
14 +*/
15 +// type QueryDatastore interface {
16 +// // Query returns an Iterator of Keys whose Values match criteria
17 +// // expressed in `query`.
18 +// Query(Query) (iter Iterator, err error)
19 +// }
Godeps/_workspace/src/github.com/jbenet/datastore.go/sync/sync.go new
+64
@@ -0,0 +1,64 @@
1 +package sync
2 +
3 +import (
4 + "sync"
5 +
6 + ds "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/datastore.go"
7 +)
8 +
9 +// MutexDatastore contains a child datastire and a mutex.
10 +// used for coarse sync
11 +type MutexDatastore struct {
12 + sync.RWMutex
13 +
14 + child ds.Datastore
15 +}
16 +
17 +// MutexWrap constructs a datastore with a coarse lock around
18 +// the entire datastore, for every single operation
19 +func MutexWrap(d ds.Datastore) ds.ThreadSafeDatastore {
20 + return &MutexDatastore{child: d}
21 +}
22 +
23 +// Children implements Shim
24 +func (d *MutexDatastore) Children() []ds.Datastore {
25 + return []ds.Datastore{d.child}
26 +}
27 +
28 +// IsThreadSafe implements ThreadSafeDatastore
29 +func (d *MutexDatastore) IsThreadSafe() {}
30 +
31 +// Put implements Datastore.Put
32 +func (d *MutexDatastore) Put(key ds.Key, value interface{}) (err error) {
33 + d.Lock()
34 + defer d.Unlock()
35 + return d.child.Put(key, value)
36 +}
37 +
38 +// Get implements Datastore.Get
39 +func (d *MutexDatastore) Get(key ds.Key) (value interface{}, err error) {
40 + d.RLock()
41 + defer d.RUnlock()
42 + return d.child.Get(key)
43 +}
44 +
45 +// Has implements Datastore.Has
46 +func (d *MutexDatastore) Has(key ds.Key) (exists bool, err error) {
47 + d.RLock()
48 + defer d.RUnlock()
49 + return d.child.Has(key)
50 +}
51 +
52 +// Delete implements Datastore.Delete
53 +func (d *MutexDatastore) Delete(key ds.Key) (err error) {
54 + d.Lock()
55 + defer d.Unlock()
56 + return d.child.Delete(key)
57 +}
58 +
59 +// KeyList implements Datastore.KeyList
60 +func (d *MutexDatastore) KeyList() ([]ds.Key, error) {
61 + d.RLock()
62 + defer d.RUnlock()
63 + return d.child.KeyList()
64 +}