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
+}