kyotocabinet-ffi 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 7a217d689172b77a9ed48327116644b3d5d2e8bb
4
+ data.tar.gz: f7777511183cac42863b3ab84035d932c36ad5cd
5
+ SHA512:
6
+ metadata.gz: 6f8c12f2f832e8d849bc3587e3d8fcb285adf4bebdd0fa12d77beb97d6ac24da0961768351d5931e80d06e561adb1a4ac8ee557dc200b2be9c744b43433f6c4a
7
+ data.tar.gz: 10fbcc82c5907afe1c6c509942d59c72b4e1a1d05c19fe3c9e8f1afe7c3ab7d5360272cfb26c2f475c91f252b846c1d83fac07573d072f93dcb40c792410258b
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2014-2015 Anthony Bargnesi
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
@@ -0,0 +1,6 @@
1
+ require_relative 'kyotocabinet_ffi/libkyotocabinet_ffi'
2
+ require_relative 'kyotocabinet_ffi/db/db'
3
+ require_relative 'kyotocabinet_ffi/db/polymorphic_db'
4
+ require_relative 'kyotocabinet_ffi/db/memory_hash_db'
5
+ require_relative 'kyotocabinet_ffi/db/file_hash_db'
6
+ require_relative 'kyotocabinet_ffi/version'
@@ -0,0 +1,120 @@
1
+ require_relative '../libkyotocabinet_ffi'
2
+
3
+ module KyotoCabinet
4
+
5
+ # in-memory (or prototype) database types
6
+ MEMORY_HASH = :-
7
+ MEMORY_TREE = :+
8
+ MEMORY_STASH = :':'
9
+ MEMORY_CACHE_HASH = :*
10
+ MEMORY_CACHE_TREE = :%
11
+
12
+ # on-disk database types
13
+ FILE_HASH = :".kch"
14
+ FILE_TREE = :".kct"
15
+ FILE_PLAIN_TEXT = :".kcx"
16
+ DIR_HASH = :".kcd"
17
+ DIR_TREE = :".kcf"
18
+
19
+ MEMORY_DB_TYPE = [
20
+ MEMORY_HASH,
21
+ MEMORY_TREE,
22
+ MEMORY_STASH,
23
+ MEMORY_CACHE_HASH,
24
+ MEMORY_CACHE_TREE
25
+ ]
26
+
27
+ FILE_DB_TYPE = [
28
+ FILE_HASH,
29
+ FILE_TREE,
30
+ FILE_PLAIN_TEXT,
31
+ DIR_HASH,
32
+ DIR_TREE
33
+ ]
34
+
35
+ DEFAULT_TEMP_PREFIX = 'kyoto-db'
36
+
37
+ def self.match_memorydb_type? value
38
+ return false unless value
39
+ value_s = value.to_s
40
+ MEMORY_DB_TYPE.any? { |ext| value_s == ext.to_s }
41
+ end
42
+
43
+ def self.match_filedb_type? value
44
+ return false unless value
45
+ value_s = value.to_s
46
+ FILE_DB_TYPE.any? { |ext| value_s.end_with? ext.to_s }
47
+ end
48
+
49
+ module Db
50
+
51
+ def new
52
+ @kc_db_pointer = LibKyotoCabinet::kcdbnew
53
+ end
54
+
55
+ def last_error_code
56
+ LibKyotoCabinet::kcdbecode(@kc_db_pointer)
57
+ end
58
+
59
+ def last_error_message
60
+ LibKyotoCabinet::kcdbemsg(@kc_db_pointer)
61
+ end
62
+
63
+ def last_error
64
+ SystemCallError.new(last_error_message, last_error_code)
65
+ end
66
+
67
+ def open(path, *options)
68
+ mode = (options & LibKyotoCabinet::MODES.keys).map { |k|
69
+ LibKyotoCabinet::MODES[k]
70
+ }.reduce(0, :|)
71
+ bool_return(LibKyotoCabinet::kcdbopen(@kc_db_pointer, path.to_s, mode))
72
+ end
73
+
74
+ def open!(path, *options)
75
+ fail last_error if not open(path, *options)
76
+ end
77
+
78
+ def size
79
+ LibKyotoCabinet::kcdbcount(@kc_db_pointer)
80
+ end
81
+
82
+ def get(key)
83
+ key_string = key.to_s
84
+ value_size_ptr = LibKyotoCabinet::FFI::MemoryPointer.new :pointer
85
+ LibKyotoCabinet::kcdbget(@kc_db_pointer, key_string, key_string.length, value_size_ptr)
86
+ end
87
+
88
+ def set(key, value)
89
+ key_string = key.to_s
90
+ value_string = value.to_s
91
+ bool_return(LibKyotoCabinet::kcdbset(@kc_db_pointer, key_string, key_string.length, value_string, value_string.length))
92
+ end
93
+
94
+ def set!(key, value)
95
+ fail last_error if not set(key, value)
96
+ end
97
+
98
+ def clear
99
+ bool_return(LibKyotoCabinet::kcdbclear(@kc_db_pointer))
100
+ end
101
+
102
+ def clear!
103
+ fail last_error if not clear
104
+ end
105
+
106
+ def close
107
+ bool_return(LibKyotoCabinet::kcdbclose(@kc_db_pointer))
108
+ end
109
+
110
+ def close!
111
+ fail last_error if not close
112
+ end
113
+
114
+ private
115
+
116
+ def bool_return(int_value)
117
+ int_value != 0
118
+ end
119
+ end
120
+ end
@@ -0,0 +1,22 @@
1
+ module KyotoCabinet
2
+ module Db
3
+
4
+ # deprecated - use PolymorphicDb directly
5
+ class FileHash < PolymorphicDb
6
+ attr_reader :file_path
7
+
8
+ def initialize(file_path, *options)
9
+ fail ArgumentError.new('file_path must be set') unless file_path
10
+
11
+ if not file_path.end_with? KyotoCabinet::FILE_HASH.to_s
12
+ file_path << KyotoCabinet::FILE_HASH.to_s
13
+ end
14
+
15
+ @file_path = file_path
16
+
17
+ self.new
18
+ self.open!(@file_path, *options)
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,12 @@
1
+ module KyotoCabinet
2
+ module Db
3
+
4
+ # deprecated - use PolymorphicDb directly
5
+ class MemoryHash < PolymorphicDb
6
+ def initialize(*options)
7
+ self.new
8
+ self.open!(KyotoCabinet::MEMORY_HASH, *options)
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,69 @@
1
+ require 'pathname'
2
+ require 'fileutils'
3
+
4
+ module KyotoCabinet
5
+ module Db
6
+ class PolymorphicDb
7
+ include Db
8
+
9
+ def initialize(path, options = {})
10
+ path_s = path.to_s
11
+ db_options = options.delete(:db_options) || []
12
+ unless KyotoCabinet::match_filedb_type? (path_s) or
13
+ KyotoCabinet::match_memorydb_type? (path_s)
14
+ msg = %Q{
15
+ The path value \"#{path || '(nil)'}\" does not match one of the memory
16
+ db types #{KyotoCabinet::MEMORY_DB_TYPE.map(&:to_s).join(', ')} or
17
+ one of the file db types #{KyotoCabinet::FILE_DB_TYPE.map(&:to_s).join(', ')}.
18
+ }.gsub(%r{^\s+}, ' ').gsub(%r{\n}, '')
19
+ fail ArgumentError.new(msg)
20
+ end
21
+
22
+ self.new
23
+ self.open!(path, *db_options)
24
+ end
25
+
26
+ def self.tmp_filedb(type, options = {})
27
+ prefix = options[:prefix]
28
+ path = make_temp(type, prefix)
29
+
30
+ self.new(path, {
31
+ :db_options => [:create, :reader, :writer]
32
+ })
33
+ end
34
+
35
+ def [](key)
36
+ self.get(key)
37
+ end
38
+
39
+ def []=(key, value)
40
+ self.set(key, value)
41
+ end
42
+
43
+ def empty?
44
+ self.size <= 0
45
+ end
46
+
47
+ def clear
48
+ super
49
+ end
50
+
51
+ private
52
+
53
+ def self.make_temp(ext, prefix)
54
+ unless KyotoCabinet::match_filedb_type?(ext)
55
+ msg = %Q{
56
+ The ext value \"#{ext || '(nil)'}\" does not match one of the file
57
+ db types #{KyotoCabinet::FILE_DB_TYPE.map(&:to_s).join(', ')}.
58
+ }.gsub(%r{^\s+}, ' ').gsub(%r{\n}, '')
59
+ msg = "The extension \"#{ext || '(nil)'}\" does not match one of #{KyotoCabinet::FILE_DB_TYPE}"
60
+ fail ArgumentError.new(msg)
61
+ end
62
+
63
+ epoch_millis = (Time.now.to_f * 1000).to_i
64
+ prefix = prefix || DEFAULT_TEMP_PREFIX
65
+ (Pathname(Dir.tmpdir) + "#{prefix}-#{epoch_millis}#{ext}").to_s
66
+ end
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,91 @@
1
+ # @api private
2
+ # FFI bindings
3
+ module LibKyotoCabinet
4
+
5
+ class << self
6
+
7
+ def mri?
8
+ defined?(RUBY_DESCRIPTION) && (/^ruby/ =~ RUBY_DESCRIPTION)
9
+ end
10
+
11
+ def jruby?
12
+ defined?(RUBY_PLATFORM) && ("java" == RUBY_PLATFORM)
13
+ end
14
+
15
+ def rubinius?
16
+ defined?(RUBY_ENGINE) && ("rbx" == RUBY_ENGINE)
17
+ end
18
+
19
+ # @api_private
20
+ # Determine FFI constant for this ruby engine.
21
+ def find_ffi
22
+ if defined?(RUBY_ENGINE) && RUBY_ENGINE == "rbx"
23
+ if const_defined? "::Rubinius::FFI"
24
+ ::Rubinius::FFI
25
+ elsif const_defined? "::FFI"
26
+ ::FFI
27
+ else
28
+ require "ffi"
29
+ ::FFI
30
+ end
31
+ else # mri, jruby, etc
32
+ require "ffi"
33
+ ::FFI
34
+ end
35
+ end
36
+
37
+ # @api_private
38
+ # Extend with the correct ffi implementation.
39
+ def load_ffi
40
+ ffi_module = LibKyotoCabinet::find_ffi
41
+ extend ffi_module::Library
42
+ ffi_module
43
+ end
44
+
45
+ # @api_private
46
+ # Loads the libkyotocabinet shared library.
47
+ def load_libkyotocabinet
48
+ ffi_module = find_ffi
49
+ extend ffi_module::Library
50
+
51
+ begin
52
+ ffi_lib "kyotocabinet"
53
+ rescue LoadError
54
+ begin
55
+ ffi_lib "libkyotocabinet.so"
56
+ rescue LoadError
57
+ ffi_lib "libkyotocabinet.so.16"
58
+ end
59
+ end
60
+ end
61
+ end
62
+
63
+ # Constant holding the FFI module for this ruby engine.
64
+ FFI = LibKyotoCabinet::load_ffi
65
+ LibKyotoCabinet::load_libkyotocabinet
66
+
67
+ # mode options
68
+ MODES = {
69
+ :reader => (1 << 0),
70
+ :writer => (1 << 1),
71
+ :create => (1 << 2),
72
+ :truncate => (1 << 3),
73
+ :auto_transaction => (1 << 4),
74
+ :auto_synchronize => (1 << 5),
75
+ :no_file_locking => (1 << 6),
76
+ :non_blocking_lock => (1 << 7),
77
+ :no_file_repair => (1 << 8)
78
+ }
79
+
80
+ attach_function :kcdbecode, [:pointer], :int32
81
+ attach_function :kcdbemsg, [:pointer], :string
82
+ attach_function :kcdbnew, [], :pointer
83
+ attach_function :kcdbopen, [:pointer, :string, :uint32], :int32
84
+ attach_function :kcdbcount, [:pointer], :int64
85
+ attach_function :kcdbset, [:pointer, :string, :size_t, :string, :size_t], :int32
86
+ attach_function :kcdbadd, [:pointer, :string, :size_t, :string, :size_t], :int32
87
+ attach_function :kcdbget, [:pointer, :string, :size_t, :pointer], :string
88
+ attach_function :kcdbclear, [:pointer], :int32
89
+ attach_function :kcdbclose, [:pointer], :int32
90
+ attach_function :kcdbdel, [:pointer], :void
91
+ end
@@ -0,0 +1,3 @@
1
+ module KyotoCabinet
2
+ VERSION = '0.1.0'
3
+ end
metadata ADDED
@@ -0,0 +1,96 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: kyotocabinet-ffi
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Anthony Bargnesi
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-06-25 00:00:00.000000000 Z
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: '1.9'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.9'
27
+ - !ruby/object:Gem::Dependency
28
+ name: minitest
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '5.4'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '5.4'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '10.4'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '10.4'
55
+ description: Kyoto Cabinet provided DBM interface to efficient key value stores both
56
+ in-memory and on-disk. This gem wraps Kyoto Cabinet's C API using FFI (foregin function
57
+ interface) to support MRI, JRuby, and Rubinius.
58
+ email: abargnesi@gmail.com
59
+ executables: []
60
+ extensions: []
61
+ extra_rdoc_files: []
62
+ files:
63
+ - LICENSE
64
+ - lib/kyotocabinet_ffi.rb
65
+ - lib/kyotocabinet_ffi/db/db.rb
66
+ - lib/kyotocabinet_ffi/db/file_hash_db.rb
67
+ - lib/kyotocabinet_ffi/db/memory_hash_db.rb
68
+ - lib/kyotocabinet_ffi/db/polymorphic_db.rb
69
+ - lib/kyotocabinet_ffi/libkyotocabinet_ffi.rb
70
+ - lib/kyotocabinet_ffi/version.rb
71
+ homepage: https://github.com/abargnesi/kyotocabinet-ffi
72
+ licenses:
73
+ - MIT
74
+ metadata: {}
75
+ post_install_message:
76
+ rdoc_options: []
77
+ require_paths:
78
+ - lib
79
+ required_ruby_version: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - ">="
82
+ - !ruby/object:Gem::Version
83
+ version: '0'
84
+ required_rubygems_version: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - ">="
87
+ - !ruby/object:Gem::Version
88
+ version: '0'
89
+ requirements: []
90
+ rubyforge_project:
91
+ rubygems_version: 2.4.5
92
+ signing_key:
93
+ specification_version: 4
94
+ summary: FFI wrapper to Kyoto Cabinet's C API.
95
+ test_files: []
96
+ has_rdoc: