sparkey 0.0.1 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/Rakefile +7 -0
- data/lib/sparkey.rb +17 -2
- data/lib/sparkey/errors.rb +11 -0
- data/lib/sparkey/hash_reader.rb +49 -0
- data/lib/sparkey/hash_writer.rb +10 -0
- data/lib/sparkey/log_iterator.rb +81 -0
- data/lib/sparkey/log_reader.rb +35 -0
- data/lib/sparkey/log_writer.rb +51 -0
- data/lib/sparkey/native.rb +98 -0
- data/lib/sparkey/store.rb +108 -0
- data/lib/sparkey/testing.rb +15 -0
- data/sparkey.gemspec +7 -7
- data/spec/sparkey_spec.rb +38 -0
- metadata +37 -26
- data/LICENSE.txt +0 -22
- data/lib/sparkey/version.rb +0 -3
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 1d02b7853fe52790fde3dd206f8af7febc4c01f8
|
4
|
+
data.tar.gz: 34f41f81cbf31b608fa6faed0ba9b252c1e4b1b8
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 2719e8fd06e6f6d108f5eab7a856a37fafddfafa712b8daff293315293d458c56709a26e6891b68ffdbefd122affad22b8d6e8a79b498e4bbcece8222591c965
|
7
|
+
data.tar.gz: 81397ce7bf58162b23ad076d2334a1acb63d8064f9cf6bc12da2e71eaa4b3d5ab8fda1c10b84d237437904557c54bd3fee7d529f769694bcb486a647ec0e06a0
|
data/Rakefile
CHANGED
data/lib/sparkey.rb
CHANGED
@@ -1,5 +1,20 @@
|
|
1
|
-
require "
|
1
|
+
require "ffi"
|
2
2
|
|
3
3
|
module Sparkey
|
4
|
-
|
4
|
+
def self.create(filename)
|
5
|
+
Store.create(filename)
|
6
|
+
end
|
7
|
+
|
8
|
+
def self.open(filename)
|
9
|
+
Store.open(filename)
|
10
|
+
end
|
5
11
|
end
|
12
|
+
|
13
|
+
require "sparkey/native"
|
14
|
+
require "sparkey/errors"
|
15
|
+
require "sparkey/store"
|
16
|
+
require "sparkey/log_writer"
|
17
|
+
require "sparkey/log_reader"
|
18
|
+
require "sparkey/log_iterator"
|
19
|
+
require "sparkey/hash_writer"
|
20
|
+
require "sparkey/hash_reader"
|
@@ -0,0 +1,49 @@
|
|
1
|
+
class Sparkey::HashReader
|
2
|
+
include Sparkey::Errors
|
3
|
+
|
4
|
+
def open(filename)
|
5
|
+
hash_filename = "#{filename}.spi"
|
6
|
+
log_filename = "#{filename}.spl"
|
7
|
+
ptr = FFI::MemoryPointer.new(:pointer)
|
8
|
+
|
9
|
+
handle_status Sparkey::Native.hash_open(ptr, hash_filename, log_filename)
|
10
|
+
|
11
|
+
@hash_reader_ptr = ptr.get_pointer(0)
|
12
|
+
end
|
13
|
+
|
14
|
+
def close
|
15
|
+
ptr = FFI::MemoryPointer.new(:pointer)
|
16
|
+
ptr.put_pointer(0, @hash_reader_ptr)
|
17
|
+
|
18
|
+
Sparkey::Native.hash_close(ptr)
|
19
|
+
end
|
20
|
+
|
21
|
+
def seek(key)
|
22
|
+
iterator = Sparkey::LogIterator.new(log_reader)
|
23
|
+
|
24
|
+
key_length = key.size
|
25
|
+
key_ptr = FFI::MemoryPointer.new(:uint8, key_length)
|
26
|
+
key_ptr.put_bytes(0, key)
|
27
|
+
|
28
|
+
handle_status Sparkey::Native.hash_get(@hash_reader_ptr, key_ptr, key_length, iterator.ptr)
|
29
|
+
|
30
|
+
iterator
|
31
|
+
end
|
32
|
+
|
33
|
+
def size
|
34
|
+
Sparkey::Native.hash_numentries(@hash_reader_ptr)
|
35
|
+
end
|
36
|
+
|
37
|
+
def log_reader
|
38
|
+
reader_ptr = Sparkey::Native.hash_getreader(@hash_reader_ptr)
|
39
|
+
|
40
|
+
log_reader = Sparkey::LogReader.new
|
41
|
+
log_reader.ptr = reader_ptr
|
42
|
+
|
43
|
+
log_reader
|
44
|
+
end
|
45
|
+
|
46
|
+
def ptr
|
47
|
+
@hash_reader_ptr
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
class Sparkey::LogIterator
|
2
|
+
include Sparkey::Errors
|
3
|
+
|
4
|
+
def initialize(log_reader, hash_reader = nil)
|
5
|
+
@log_reader = log_reader
|
6
|
+
@hash_reader = hash_reader
|
7
|
+
|
8
|
+
ptr = FFI::MemoryPointer.new(:pointer)
|
9
|
+
|
10
|
+
handle_status Sparkey::Native.logiter_create(ptr, @log_reader.ptr)
|
11
|
+
|
12
|
+
@log_iter_ptr = ptr.get_pointer(0)
|
13
|
+
end
|
14
|
+
|
15
|
+
def next
|
16
|
+
handle_status Sparkey::Native.logiter_next(@log_iter_ptr, @log_reader.ptr)
|
17
|
+
end
|
18
|
+
|
19
|
+
def hash_next
|
20
|
+
handle_status Sparkey::Native.logiter_hashnext(@log_iter_ptr, @hash_reader.ptr)
|
21
|
+
end
|
22
|
+
|
23
|
+
def state
|
24
|
+
Sparkey::Native.logiter_state(@log_iter_ptr)
|
25
|
+
end
|
26
|
+
|
27
|
+
def type
|
28
|
+
Sparkey::Native.logiter_type(@log_iter_ptr)
|
29
|
+
end
|
30
|
+
|
31
|
+
def <=>(iterator)
|
32
|
+
ptr = FFI::MemoryPointer.new(:int, 1)
|
33
|
+
|
34
|
+
handle_status Sparkey::Native.logiter_keycmp(@log_iter_ptr, interator.ptr, @log_reader.ptr, ptr)
|
35
|
+
|
36
|
+
ptr.read_int
|
37
|
+
end
|
38
|
+
|
39
|
+
def active?
|
40
|
+
state == :iter_active
|
41
|
+
end
|
42
|
+
|
43
|
+
def key_length
|
44
|
+
Sparkey::Native.logiter_keylen(@log_iter_ptr)
|
45
|
+
end
|
46
|
+
|
47
|
+
def value_length
|
48
|
+
Sparkey::Native.logiter_valuelen(@log_iter_ptr)
|
49
|
+
end
|
50
|
+
|
51
|
+
def get_key
|
52
|
+
wanted_key_length = key_length
|
53
|
+
key_ptr = FFI::MemoryPointer.new(:uint8, wanted_key_length)
|
54
|
+
actual_key_length_ptr = FFI::MemoryPointer.new(:uint64, 1)
|
55
|
+
|
56
|
+
handle_status Sparkey::Native.logiter_fill_key(@log_iter_ptr, @log_reader.ptr, wanted_key_length, key_ptr, actual_key_length_ptr)
|
57
|
+
|
58
|
+
key_ptr.read_bytes(actual_key_length_ptr.read_uint64)
|
59
|
+
end
|
60
|
+
|
61
|
+
def get_value
|
62
|
+
wanted_value_length = value_length
|
63
|
+
value_ptr = FFI::MemoryPointer.new(:uint8, wanted_value_length)
|
64
|
+
actual_value_length_ptr = FFI::MemoryPointer.new(:uint64, 1)
|
65
|
+
|
66
|
+
handle_status Sparkey::Native.logiter_fill_value(@log_iter_ptr, @log_reader.ptr, wanted_value_length, value_ptr, actual_value_length_ptr)
|
67
|
+
|
68
|
+
value_ptr.read_bytes(actual_value_length_ptr.read_uint64)
|
69
|
+
end
|
70
|
+
|
71
|
+
def close
|
72
|
+
ptr = FFI::MemoryPointer.new(:pointer)
|
73
|
+
ptr.put_pointer(0, @log_iter_ptr)
|
74
|
+
|
75
|
+
Sparkey::Native.logiter_close(ptr)
|
76
|
+
end
|
77
|
+
|
78
|
+
def ptr
|
79
|
+
@log_iter_ptr
|
80
|
+
end
|
81
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
class Sparkey::LogReader
|
2
|
+
include Sparkey::Errors
|
3
|
+
|
4
|
+
def open(filename)
|
5
|
+
log_filename = "#{filename}.spl"
|
6
|
+
ptr = FFI::MemoryPointer.new(:pointer)
|
7
|
+
|
8
|
+
handle_status Sparkey::Native.logreader_open(ptr, log_filename)
|
9
|
+
|
10
|
+
@log_reader_ptr = ptr.get_pointer(0)
|
11
|
+
end
|
12
|
+
|
13
|
+
def close
|
14
|
+
ptr = FFI::MemoryPointer.new(:pointer)
|
15
|
+
ptr.put_pointer(0, @log_reader_ptr)
|
16
|
+
|
17
|
+
Sparkey::Native.logreader_close(ptr)
|
18
|
+
end
|
19
|
+
|
20
|
+
def max_key_length
|
21
|
+
Sparkey::Native.logreader_maxkeylen(@log_reader_ptr)
|
22
|
+
end
|
23
|
+
|
24
|
+
def max_value_length
|
25
|
+
Sparkey::Native.logreader_maxvaluelen(@log_reader_ptr)
|
26
|
+
end
|
27
|
+
|
28
|
+
def ptr=(ptr)
|
29
|
+
@log_reader_ptr = ptr
|
30
|
+
end
|
31
|
+
|
32
|
+
def ptr
|
33
|
+
@log_reader_ptr
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
class Sparkey::LogWriter
|
2
|
+
include Sparkey::Errors
|
3
|
+
|
4
|
+
def create(filename, compression, block_size)
|
5
|
+
ptr = FFI::MemoryPointer.new(:pointer)
|
6
|
+
log_filename = "#{filename}.spl"
|
7
|
+
|
8
|
+
handle_status Sparkey::Native.logwriter_create(ptr, log_filename, compression, block_size)
|
9
|
+
|
10
|
+
@log_writer_ptr = ptr.get_pointer(0)
|
11
|
+
end
|
12
|
+
|
13
|
+
def open(filename)
|
14
|
+
ptr = FFI::MemoryPointer.new(:pointer)
|
15
|
+
log_filename = "#{filename}.spl"
|
16
|
+
|
17
|
+
handle_status Sparkey::Native.logwriter_append(ptr, log_filename)
|
18
|
+
@log_writer_ptr = ptr.get_pointer(0)
|
19
|
+
end
|
20
|
+
|
21
|
+
def put(key, value)
|
22
|
+
key_length = key.bytesize
|
23
|
+
key_ptr = FFI::MemoryPointer.new(:uint8, key_length)
|
24
|
+
key_ptr.put_bytes(0, key)
|
25
|
+
|
26
|
+
value_length = value.bytesize
|
27
|
+
value_ptr = FFI::MemoryPointer.new(:uint8, value_length)
|
28
|
+
value_ptr.put_bytes(0, value)
|
29
|
+
|
30
|
+
handle_status Sparkey::Native.logwriter_put(@log_writer_ptr, key_length, key_ptr, value_length, value_ptr)
|
31
|
+
end
|
32
|
+
|
33
|
+
def delete(key)
|
34
|
+
key_length = key.bytesize
|
35
|
+
key_ptr = FFI::MemoryPointer.new(:uint8, key_length)
|
36
|
+
key_ptr.put_bytes(0, key)
|
37
|
+
|
38
|
+
handle_status Sparkey::Native.logwriter_delete(@log_writer_ptr, key_length, key_ptr)
|
39
|
+
end
|
40
|
+
|
41
|
+
def flush
|
42
|
+
handle_status Sparkey::Native.logwriter_flush(@log_writer_ptr)
|
43
|
+
end
|
44
|
+
|
45
|
+
def close
|
46
|
+
ptr = FFI::MemoryPointer.new(:pointer)
|
47
|
+
ptr.put_pointer(0, @log_writer_ptr)
|
48
|
+
|
49
|
+
Sparkey::Native.logwriter_close(ptr)
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,98 @@
|
|
1
|
+
module Sparkey::Native
|
2
|
+
extend FFI::Library
|
3
|
+
|
4
|
+
ffi_lib ["libsparkey"]
|
5
|
+
|
6
|
+
RETURN_CODE = enum :success, 0,
|
7
|
+
:internal_error, -1,
|
8
|
+
|
9
|
+
:file_not_found, -100,
|
10
|
+
:permission_denied, -101,
|
11
|
+
:too_many_open_files, -102,
|
12
|
+
:file_too_large, -103,
|
13
|
+
:file_already_exists, -104,
|
14
|
+
:file_busy, -105,
|
15
|
+
:file_is_directory, -106,
|
16
|
+
:file_size_exceeded, -107,
|
17
|
+
:file_closed, -108,
|
18
|
+
:out_of_disk, -109,
|
19
|
+
:unexpected_eof, -110,
|
20
|
+
:mmap_failed, -111,
|
21
|
+
|
22
|
+
:wrong_log_magic_number, -200,
|
23
|
+
:wrong_log_major_version, -201,
|
24
|
+
:unsupported_log_minor_version, -202,
|
25
|
+
:log_too_small, -203,
|
26
|
+
:log_closed, -204,
|
27
|
+
:log_iterator_inactive, -205,
|
28
|
+
:log_iterator_mismatch, -206,
|
29
|
+
:log_iterator_closed, -207,
|
30
|
+
:log_header_corrupt, -208,
|
31
|
+
:invalid_compression_block_size, -209,
|
32
|
+
:invalid_compression_type, -210,
|
33
|
+
|
34
|
+
:wrong_hash_magic_number, -300,
|
35
|
+
:wrong_hash_major_version, -301,
|
36
|
+
:unsupported_hash_minor_version, -302,
|
37
|
+
:hash_too_small, -303,
|
38
|
+
:hash_closed, -304,
|
39
|
+
:file_identifier_mismatch, -305,
|
40
|
+
:hash_header_corrupt, -306,
|
41
|
+
:hash_size_invalid, -307
|
42
|
+
|
43
|
+
COMPRESSION_TYPE = enum :compression_none,
|
44
|
+
:compression_snappy
|
45
|
+
|
46
|
+
ENTRY_TYPE = enum :entry_put,
|
47
|
+
:entry_delete
|
48
|
+
|
49
|
+
ITER_STATE = enum :iter_new,
|
50
|
+
:iter_active,
|
51
|
+
:iter_closed,
|
52
|
+
:iter_invalid
|
53
|
+
|
54
|
+
|
55
|
+
attach_function :logwriter_create, :sparkey_logwriter_create, [:pointer, :string, COMPRESSION_TYPE, :int], RETURN_CODE
|
56
|
+
attach_function :logwriter_append, :sparkey_logwriter_append, [:pointer, :string], RETURN_CODE
|
57
|
+
|
58
|
+
attach_function :logwriter_put, :sparkey_logwriter_put, [:pointer, :uint64, :pointer, :uint64, :pointer], RETURN_CODE
|
59
|
+
attach_function :logwriter_delete, :sparkey_logwriter_delete, [:pointer, :uint64, :pointer], RETURN_CODE
|
60
|
+
|
61
|
+
attach_function :logwriter_flush, :sparkey_logwriter_flush, [:pointer], RETURN_CODE
|
62
|
+
attach_function :logwriter_close, :sparkey_logwriter_close, [:pointer], RETURN_CODE
|
63
|
+
|
64
|
+
attach_function :logreader_open, :sparkey_logreader_open, [:pointer, :string], RETURN_CODE
|
65
|
+
attach_function :logreader_close, :sparkey_logreader_close, [:pointer], :void
|
66
|
+
attach_function :logreader_maxkeylen, :sparkey_logreader_maxkeylen, [:pointer], :uint64
|
67
|
+
attach_function :logreader_maxvaluelen, :sparkey_logreader_maxvaluelen, [:pointer], :uint64
|
68
|
+
|
69
|
+
attach_function :logiter_create, :sparkey_logiter_create, [:pointer, :pointer], RETURN_CODE
|
70
|
+
attach_function :logiter_close, :sparkey_logiter_close, [:pointer], :void
|
71
|
+
attach_function :logiter_seek, :sparkey_logiter_seek, [:pointer, :pointer, :uint64], RETURN_CODE
|
72
|
+
attach_function :logiter_skip, :sparkey_logiter_skip, [:pointer, :pointer, :int], RETURN_CODE
|
73
|
+
attach_function :logiter_next, :sparkey_logiter_next, [:pointer, :pointer], RETURN_CODE
|
74
|
+
attach_function :logiter_reset, :sparkey_logiter_reset, [:pointer, :pointer], RETURN_CODE
|
75
|
+
attach_function :logiter_keychunk, :sparkey_logiter_keychunk, [:pointer, :pointer, :uint64, :pointer, :pointer], RETURN_CODE
|
76
|
+
attach_function :logiter_valuechunk, :sparkey_logiter_valuechunk, [:pointer, :pointer, :uint64, :pointer, :pointer], RETURN_CODE
|
77
|
+
attach_function :logiter_fill_key, :sparkey_logiter_fill_key, [:pointer, :pointer, :uint64, :pointer, :pointer], RETURN_CODE
|
78
|
+
attach_function :logiter_fill_value, :sparkey_logiter_fill_value, [:pointer, :pointer, :uint64, :pointer, :pointer], RETURN_CODE
|
79
|
+
attach_function :logiter_keycmp, :sparkey_logiter_keycmp, [:pointer, :pointer, :pointer, :pointer], RETURN_CODE
|
80
|
+
attach_function :logiter_state, :sparkey_logiter_state, [:pointer], ITER_STATE
|
81
|
+
attach_function :logiter_type, :sparkey_logiter_type, [:pointer], ENTRY_TYPE
|
82
|
+
attach_function :logiter_keylen, :sparkey_logiter_keylen, [:pointer], :uint64
|
83
|
+
attach_function :logiter_valuelen, :sparkey_logiter_valuelen, [:pointer], :uint64
|
84
|
+
attach_function :logiter_hashnext, :sparkey_logiter_hashnext, [:pointer, :pointer], RETURN_CODE
|
85
|
+
attach_function :logiter_close, :sparkey_logiter_close, [:pointer], :void
|
86
|
+
|
87
|
+
attach_function :hash_write, :sparkey_hash_write, [:pointer, :string, :int], RETURN_CODE
|
88
|
+
attach_function :hash_open, :sparkey_hash_open, [:pointer, :string, :string], RETURN_CODE
|
89
|
+
attach_function :hash_getreader, :sparkey_hash_getreader, [:pointer], :pointer
|
90
|
+
attach_function :hash_close, :sparkey_hash_close, [:pointer], :void
|
91
|
+
attach_function :hash_get, :sparkey_hash_get, [:pointer, :pointer, :uint64, :pointer], RETURN_CODE
|
92
|
+
attach_function :hash_numentries, :sparkey_hash_numentries, [:pointer], :uint64
|
93
|
+
attach_function :hash_numcollisions, :sparkey_hash_numcollisions, [:pointer], :uint64
|
94
|
+
|
95
|
+
attach_function :create_log_filename, :sparkey_create_log_filename, [:string], :string
|
96
|
+
|
97
|
+
attach_function :error_string, :sparkey_errstring, [RETURN_CODE], :string
|
98
|
+
end
|
@@ -0,0 +1,108 @@
|
|
1
|
+
class Sparkey::Store
|
2
|
+
attr_accessor :filename, :log_writer, :log_reader,
|
3
|
+
:hash_writer, :hash_reader
|
4
|
+
|
5
|
+
def self.create(filename, compression_type = :compression_none, block_size = 1000)
|
6
|
+
store = new(filename)
|
7
|
+
|
8
|
+
store.log_writer = Sparkey::LogWriter.new
|
9
|
+
store.log_writer.create(filename, compression_type, block_size)
|
10
|
+
|
11
|
+
store.log_reader = Sparkey::LogReader.new
|
12
|
+
store.log_reader.open(filename)
|
13
|
+
|
14
|
+
store.hash_writer = Sparkey::HashWriter.new
|
15
|
+
store.hash_writer.create(filename)
|
16
|
+
|
17
|
+
store.hash_reader = Sparkey::HashReader.new
|
18
|
+
store.hash_reader.open(filename)
|
19
|
+
|
20
|
+
store
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.open(filename)
|
24
|
+
store = new(filename)
|
25
|
+
|
26
|
+
store.log_writer = Sparkey::LogWriter.new
|
27
|
+
store.log_writer.open(filename)
|
28
|
+
|
29
|
+
store.log_reader = Sparkey::LogReader.new
|
30
|
+
store.log_reader.open(filename)
|
31
|
+
|
32
|
+
store.hash_writer = Sparkey::HashWriter.new
|
33
|
+
store.hash_writer.create(filename)
|
34
|
+
|
35
|
+
store.hash_reader = Sparkey::HashReader.new
|
36
|
+
store.hash_reader.open(filename)
|
37
|
+
|
38
|
+
store
|
39
|
+
end
|
40
|
+
|
41
|
+
def initialize(filename)
|
42
|
+
@filename = filename
|
43
|
+
end
|
44
|
+
|
45
|
+
def close
|
46
|
+
log_writer.close
|
47
|
+
log_reader.close
|
48
|
+
hash_reader.close
|
49
|
+
end
|
50
|
+
|
51
|
+
def size
|
52
|
+
hash_reader.size
|
53
|
+
end
|
54
|
+
|
55
|
+
def get(key)
|
56
|
+
iterator = hash_reader.seek(key)
|
57
|
+
|
58
|
+
iterator.get_value
|
59
|
+
end
|
60
|
+
|
61
|
+
def each_from_hash
|
62
|
+
log_reader = hash_reader.log_reader
|
63
|
+
iterator = Sparkey::LogIterator.new(log_reader, hash_reader)
|
64
|
+
|
65
|
+
loop do
|
66
|
+
iterator.hash_next
|
67
|
+
|
68
|
+
break unless iterator.active?
|
69
|
+
|
70
|
+
yield iterator.get_key, iterator.get_value
|
71
|
+
end
|
72
|
+
|
73
|
+
iterator.close
|
74
|
+
end
|
75
|
+
alias_method :each, :each_from_hash
|
76
|
+
|
77
|
+
def each_from_log
|
78
|
+
iterator = Sparkey::LogIterator.new(log_reader)
|
79
|
+
|
80
|
+
loop do
|
81
|
+
iterator.next
|
82
|
+
|
83
|
+
break unless iterator.active?
|
84
|
+
|
85
|
+
yield iterator.get_key, iterator.get_value
|
86
|
+
end
|
87
|
+
|
88
|
+
iterator.close
|
89
|
+
end
|
90
|
+
|
91
|
+
def put(key, value)
|
92
|
+
log_writer.put(key, value)
|
93
|
+
end
|
94
|
+
|
95
|
+
def delete(key)
|
96
|
+
log_writer.delete(key)
|
97
|
+
end
|
98
|
+
|
99
|
+
def flush
|
100
|
+
yield self if block_given?
|
101
|
+
|
102
|
+
log_writer.flush
|
103
|
+
|
104
|
+
# Reset the hash headers
|
105
|
+
hash_writer.create(filename)
|
106
|
+
hash_reader.open(filename)
|
107
|
+
end
|
108
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require "securerandom"
|
2
|
+
|
3
|
+
module Sparkey::Testing
|
4
|
+
def random_filename
|
5
|
+
"test-#{SecureRandom.hex(16)}"
|
6
|
+
end
|
7
|
+
|
8
|
+
def delete(filename)
|
9
|
+
log_file = "#{filename}.spl"
|
10
|
+
index_file = "#{filename}.spi"
|
11
|
+
|
12
|
+
File.delete(log_file) if File.exists?(log_file)
|
13
|
+
File.delete(index_file) if File.exists?(index_file)
|
14
|
+
end
|
15
|
+
end
|
data/sparkey.gemspec
CHANGED
@@ -1,23 +1,23 @@
|
|
1
1
|
# coding: utf-8
|
2
|
-
lib = File.expand_path(
|
2
|
+
lib = File.expand_path("../lib", __FILE__)
|
3
3
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
-
require 'sparkey/version'
|
5
4
|
|
6
5
|
Gem::Specification.new do |spec|
|
7
6
|
spec.name = "sparkey"
|
8
|
-
spec.version =
|
7
|
+
spec.version = "1.0.0"
|
9
8
|
spec.authors = ["Adam Tanner"]
|
10
9
|
spec.email = ["adam@adamtanner.org"]
|
11
|
-
spec.description = %
|
12
|
-
spec.summary = %
|
13
|
-
spec.homepage = ""
|
10
|
+
spec.description = %{ Ruby FFI bindings for Spotify's Sparkey }
|
11
|
+
spec.summary = %{ Ruby FFI bindings for Spotify's Sparkey }
|
12
|
+
spec.homepage = "https://github.com/adamtanner/sparkey"
|
14
13
|
spec.license = "MIT"
|
15
14
|
|
16
15
|
spec.files = `git ls-files`.split($/)
|
17
16
|
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
-
spec.test_files = spec.files.grep(%r{^
|
17
|
+
spec.test_files = spec.files.grep(%r{^spec/})
|
19
18
|
spec.require_paths = ["lib"]
|
20
19
|
|
20
|
+
spec.add_dependency "ffi"
|
21
21
|
spec.add_development_dependency "bundler", "~> 1.3"
|
22
22
|
spec.add_development_dependency "rake"
|
23
23
|
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require "minitest/autorun"
|
2
|
+
require "sparkey"
|
3
|
+
require "sparkey/testing"
|
4
|
+
|
5
|
+
describe Sparkey do
|
6
|
+
include Sparkey::Testing
|
7
|
+
|
8
|
+
before { @filename = random_filename }
|
9
|
+
after { delete(@filename) }
|
10
|
+
|
11
|
+
it "functions as a key value store" do
|
12
|
+
sparkey = Sparkey::Store.create(@filename, :compression_snappy, 1000)
|
13
|
+
sparkey.put("first", "Michael")
|
14
|
+
sparkey.put("second", "Adam")
|
15
|
+
sparkey.put("third", "Tanner")
|
16
|
+
sparkey.close
|
17
|
+
|
18
|
+
sparkey = Sparkey::Store.open(@filename)
|
19
|
+
|
20
|
+
sparkey.size.must_equal 3
|
21
|
+
|
22
|
+
sparkey.get("first").must_equal("Michael")
|
23
|
+
sparkey.delete("second")
|
24
|
+
sparkey.flush
|
25
|
+
|
26
|
+
sparkey.size.must_equal 2
|
27
|
+
|
28
|
+
hash = Hash.new
|
29
|
+
sparkey.each do |key, value|
|
30
|
+
hash[key] = value
|
31
|
+
end
|
32
|
+
|
33
|
+
hash.must_equal(
|
34
|
+
"first" => "Michael",
|
35
|
+
"third" => "Tanner"
|
36
|
+
)
|
37
|
+
end
|
38
|
+
end
|
metadata
CHANGED
@@ -1,20 +1,32 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sparkey
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
5
|
-
prerelease:
|
4
|
+
version: 1.0.0
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- Adam Tanner
|
9
8
|
autorequire:
|
10
9
|
bindir: bin
|
11
10
|
cert_chain: []
|
12
|
-
date: 2013-
|
11
|
+
date: 2013-11-17 00:00:00.000000000 Z
|
13
12
|
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: ffi
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - '>='
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - '>='
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
14
27
|
- !ruby/object:Gem::Dependency
|
15
28
|
name: bundler
|
16
29
|
requirement: !ruby/object:Gem::Requirement
|
17
|
-
none: false
|
18
30
|
requirements:
|
19
31
|
- - ~>
|
20
32
|
- !ruby/object:Gem::Version
|
@@ -22,7 +34,6 @@ dependencies:
|
|
22
34
|
type: :development
|
23
35
|
prerelease: false
|
24
36
|
version_requirements: !ruby/object:Gem::Requirement
|
25
|
-
none: false
|
26
37
|
requirements:
|
27
38
|
- - ~>
|
28
39
|
- !ruby/object:Gem::Version
|
@@ -30,20 +41,18 @@ dependencies:
|
|
30
41
|
- !ruby/object:Gem::Dependency
|
31
42
|
name: rake
|
32
43
|
requirement: !ruby/object:Gem::Requirement
|
33
|
-
none: false
|
34
44
|
requirements:
|
35
|
-
- -
|
45
|
+
- - '>='
|
36
46
|
- !ruby/object:Gem::Version
|
37
47
|
version: '0'
|
38
48
|
type: :development
|
39
49
|
prerelease: false
|
40
50
|
version_requirements: !ruby/object:Gem::Requirement
|
41
|
-
none: false
|
42
51
|
requirements:
|
43
|
-
- -
|
52
|
+
- - '>='
|
44
53
|
- !ruby/object:Gem::Version
|
45
54
|
version: '0'
|
46
|
-
description: Ruby FFI bindings for Spotify's Sparkey
|
55
|
+
description: ' Ruby FFI bindings for Spotify''s Sparkey '
|
47
56
|
email:
|
48
57
|
- adam@adamtanner.org
|
49
58
|
executables: []
|
@@ -53,41 +62,43 @@ files:
|
|
53
62
|
- .gitignore
|
54
63
|
- Gemfile
|
55
64
|
- LICENSE
|
56
|
-
- LICENSE.txt
|
57
65
|
- README.md
|
58
66
|
- Rakefile
|
59
67
|
- lib/sparkey.rb
|
60
|
-
- lib/sparkey/
|
68
|
+
- lib/sparkey/errors.rb
|
69
|
+
- lib/sparkey/hash_reader.rb
|
70
|
+
- lib/sparkey/hash_writer.rb
|
71
|
+
- lib/sparkey/log_iterator.rb
|
72
|
+
- lib/sparkey/log_reader.rb
|
73
|
+
- lib/sparkey/log_writer.rb
|
74
|
+
- lib/sparkey/native.rb
|
75
|
+
- lib/sparkey/store.rb
|
76
|
+
- lib/sparkey/testing.rb
|
61
77
|
- sparkey.gemspec
|
62
|
-
|
78
|
+
- spec/sparkey_spec.rb
|
79
|
+
homepage: https://github.com/adamtanner/sparkey
|
63
80
|
licenses:
|
64
81
|
- MIT
|
82
|
+
metadata: {}
|
65
83
|
post_install_message:
|
66
84
|
rdoc_options: []
|
67
85
|
require_paths:
|
68
86
|
- lib
|
69
87
|
required_ruby_version: !ruby/object:Gem::Requirement
|
70
|
-
none: false
|
71
88
|
requirements:
|
72
|
-
- -
|
89
|
+
- - '>='
|
73
90
|
- !ruby/object:Gem::Version
|
74
91
|
version: '0'
|
75
|
-
segments:
|
76
|
-
- 0
|
77
|
-
hash: 71288456881923243
|
78
92
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
79
|
-
none: false
|
80
93
|
requirements:
|
81
|
-
- -
|
94
|
+
- - '>='
|
82
95
|
- !ruby/object:Gem::Version
|
83
96
|
version: '0'
|
84
|
-
segments:
|
85
|
-
- 0
|
86
|
-
hash: 71288456881923243
|
87
97
|
requirements: []
|
88
98
|
rubyforge_project:
|
89
|
-
rubygems_version:
|
99
|
+
rubygems_version: 2.0.3
|
90
100
|
signing_key:
|
91
|
-
specification_version:
|
101
|
+
specification_version: 4
|
92
102
|
summary: Ruby FFI bindings for Spotify's Sparkey
|
93
|
-
test_files:
|
103
|
+
test_files:
|
104
|
+
- spec/sparkey_spec.rb
|
data/LICENSE.txt
DELETED
@@ -1,22 +0,0 @@
|
|
1
|
-
Copyright (c) 2013 Adam Tanner
|
2
|
-
|
3
|
-
MIT License
|
4
|
-
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
-
a copy of this software and associated documentation files (the
|
7
|
-
"Software"), to deal in the Software without restriction, including
|
8
|
-
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
-
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
-
permit persons to whom the Software is furnished to do so, subject to
|
11
|
-
the following conditions:
|
12
|
-
|
13
|
-
The above copyright notice and this permission notice shall be
|
14
|
-
included in all copies or substantial portions of the Software.
|
15
|
-
|
16
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
-
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
-
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
-
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
-
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
-
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
-
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/lib/sparkey/version.rb
DELETED