treestore 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/lib/backend/backend.rb +38 -0
- data/lib/backend/redis.rb +54 -0
- data/lib/treestore.rb +76 -0
- metadata +77 -0
@@ -0,0 +1,38 @@
|
|
1
|
+
class Backend
|
2
|
+
def initialize
|
3
|
+
raise NotImplementedError, "must instantiate a specific type of backend"
|
4
|
+
end
|
5
|
+
|
6
|
+
def retrieve(key)
|
7
|
+
raise NotImplementedError, "must instantiate a specific type of backend"
|
8
|
+
end
|
9
|
+
|
10
|
+
def addblob(value)
|
11
|
+
raise NotImplementedError, "must instantiate a specific type of backend"
|
12
|
+
end
|
13
|
+
|
14
|
+
def addtree(keys)
|
15
|
+
raise NotImplementedError, "must instantiate a specific type of backend"
|
16
|
+
end
|
17
|
+
|
18
|
+
def ref(name)
|
19
|
+
raise NotImplementedError, "must instantiate a specific type of backend"
|
20
|
+
end
|
21
|
+
|
22
|
+
def make_ref(name, key)
|
23
|
+
raise NotImplementedError, "must instantiate a specific type of backend"
|
24
|
+
end
|
25
|
+
|
26
|
+
def delete(key)
|
27
|
+
raise NotImplementedError, "must instantiate a specific type of backend"
|
28
|
+
end
|
29
|
+
|
30
|
+
def exists?(key)
|
31
|
+
raise NotImplementedError, "must instantiate a specific type of backend"
|
32
|
+
end
|
33
|
+
|
34
|
+
def type(key)
|
35
|
+
raise NotImplementedError, "must instantiate a specific type of backend"
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'redis'
|
2
|
+
require File.expand_path(File.dirname(__FILE__)) + '/backend'
|
3
|
+
|
4
|
+
class RedisBackend < Backend
|
5
|
+
def initialize(redis=nil)
|
6
|
+
@redis = redis || Redis.new
|
7
|
+
end
|
8
|
+
|
9
|
+
def retrieve(key)
|
10
|
+
type = @redis.type(key)
|
11
|
+
|
12
|
+
case type
|
13
|
+
when "string"
|
14
|
+
@redis.get(key)
|
15
|
+
when "set"
|
16
|
+
@redis.smembers(key)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def addblob(key, value)
|
21
|
+
@redis.set(key, value)
|
22
|
+
end
|
23
|
+
|
24
|
+
def addtree(treekey, keys)
|
25
|
+
@redis.sadd(treekey, keys)
|
26
|
+
end
|
27
|
+
|
28
|
+
def ref(name)
|
29
|
+
@redis.get(name)
|
30
|
+
end
|
31
|
+
|
32
|
+
def make_ref(name, key)
|
33
|
+
@redis.set(name, key)
|
34
|
+
end
|
35
|
+
|
36
|
+
def delete(key)
|
37
|
+
@redis.del(key)
|
38
|
+
end
|
39
|
+
|
40
|
+
def exists?(key)
|
41
|
+
@redis.exists(key)
|
42
|
+
end
|
43
|
+
|
44
|
+
def type(key)
|
45
|
+
case @redis.type(key)
|
46
|
+
when "string"
|
47
|
+
:blob
|
48
|
+
when "set"
|
49
|
+
:tree
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
|
data/lib/treestore.rb
ADDED
@@ -0,0 +1,76 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'digest/sha1'
|
3
|
+
require 'backend/redis'
|
4
|
+
|
5
|
+
class TreeStore
|
6
|
+
def initialize(backend=RedisBackend.new)
|
7
|
+
raise RuntimeError, "#{backend} is not an appropriate backend" if not backend.kind_of? Backend
|
8
|
+
@backend = backend
|
9
|
+
@namespace = "tree-store"
|
10
|
+
end
|
11
|
+
|
12
|
+
def add(item)
|
13
|
+
key = Digest::SHA1.hexdigest(item)
|
14
|
+
@backend.addblob(make_object_key(key), item)
|
15
|
+
key
|
16
|
+
end
|
17
|
+
|
18
|
+
def retrieve(key)
|
19
|
+
realkey = make_object_key(ref(key) || key)
|
20
|
+
@backend.retrieve(realkey)
|
21
|
+
end
|
22
|
+
|
23
|
+
def make_tree(keys)
|
24
|
+
realkeys = {}
|
25
|
+
keys.each do |key|
|
26
|
+
realkey = ref(key) || key
|
27
|
+
unless exists?(realkey)
|
28
|
+
raise RuntimeError, "Can't make tree, no item with key of #{key} or #{realkey} exists, make it first"
|
29
|
+
end
|
30
|
+
realkeys[realkey] = true
|
31
|
+
end
|
32
|
+
|
33
|
+
realkeys = realkeys.keys
|
34
|
+
treekey = Digest::SHA1.hexdigest(realkeys.join)
|
35
|
+
@backend.addtree(make_object_key(treekey), realkeys)
|
36
|
+
treekey
|
37
|
+
end
|
38
|
+
|
39
|
+
def ref(name)
|
40
|
+
@backend.ref(make_ref_key(name))
|
41
|
+
end
|
42
|
+
|
43
|
+
def make_ref(name, key)
|
44
|
+
realkey = ref(key) || key
|
45
|
+
@backend.make_ref(make_ref_key(name), realkey)
|
46
|
+
name
|
47
|
+
end
|
48
|
+
|
49
|
+
def delete(key)
|
50
|
+
ref = ref(key)
|
51
|
+
if ref.nil?
|
52
|
+
@backend.delete(make_object_key(key))
|
53
|
+
else
|
54
|
+
@backend.delete(make_ref_key(key))
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def type(key)
|
59
|
+
@backend.type(make_object_key(ref(key) || key))
|
60
|
+
end
|
61
|
+
|
62
|
+
def exists?(key)
|
63
|
+
@backend.exists?(make_object_key(ref(key) || key))
|
64
|
+
end
|
65
|
+
|
66
|
+
private
|
67
|
+
|
68
|
+
def make_object_key(key)
|
69
|
+
"#{@namespace}:object:#{key}"
|
70
|
+
end
|
71
|
+
|
72
|
+
def make_ref_key(key)
|
73
|
+
"#{@namespace}:ref:#{key}"
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
metadata
ADDED
@@ -0,0 +1,77 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: treestore
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Matthew Curry
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-04-01 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: redis
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0'
|
30
|
+
description: ! 'treestore stores two different types of data:
|
31
|
+
|
32
|
+
1) values, which are stored according to their SHA-1 hashcode
|
33
|
+
|
34
|
+
2) trees, which are sets of values and/or other trees, stored via a SHA-1 hashcode
|
35
|
+
|
36
|
+
|
37
|
+
In addition, there are references that allow you to ''bookmark'' a SHA-1 hashcode
|
38
|
+
for easier lookup.
|
39
|
+
|
40
|
+
|
41
|
+
If you think of the core git, but on any key-value backend store (like the included
|
42
|
+
Redis one), you''ve got the right idea.
|
43
|
+
|
44
|
+
'
|
45
|
+
email: mjcurry@gmail.com
|
46
|
+
executables: []
|
47
|
+
extensions: []
|
48
|
+
extra_rdoc_files: []
|
49
|
+
files:
|
50
|
+
- lib/treestore.rb
|
51
|
+
- lib/backend/backend.rb
|
52
|
+
- lib/backend/redis.rb
|
53
|
+
homepage:
|
54
|
+
licenses: []
|
55
|
+
post_install_message:
|
56
|
+
rdoc_options: []
|
57
|
+
require_paths:
|
58
|
+
- lib
|
59
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
60
|
+
none: false
|
61
|
+
requirements:
|
62
|
+
- - ! '>='
|
63
|
+
- !ruby/object:Gem::Version
|
64
|
+
version: '0'
|
65
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
66
|
+
none: false
|
67
|
+
requirements:
|
68
|
+
- - ! '>='
|
69
|
+
- !ruby/object:Gem::Version
|
70
|
+
version: '0'
|
71
|
+
requirements: []
|
72
|
+
rubyforge_project:
|
73
|
+
rubygems_version: 1.8.23
|
74
|
+
signing_key:
|
75
|
+
specification_version: 3
|
76
|
+
summary: Immutable storage of key values arranged in trees
|
77
|
+
test_files: []
|