oklahoma_mixer 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/AUTHORS.rdoc ADDED
@@ -0,0 +1 @@
1
+ <b>James Edward Gray II</b>:: {james@graysoftinc.com}[mailto:james@graysoftinc.com]
data/CHANGELOG.rdoc ADDED
@@ -0,0 +1,7 @@
1
+ = Change Log
2
+
3
+ Below is a complete listing of changes for each revision of Oklahoma Mixer.
4
+
5
+ == 0.1.0
6
+
7
+ * Initial public release with Hash Database support
data/INSTALL.rdoc ADDED
@@ -0,0 +1,22 @@
1
+ = Installing Oklahoma Mixer
2
+
3
+ RubyGems is the preferred install method for Oklahoma Mixer.
4
+
5
+ == Installing the Gem
6
+
7
+ Oklahoma Mixer is intended to be installed via the
8
+ RubyGems[http://rubyforge.org/projects/rubygems/] system. To get the latest
9
+ version, simply enter the following into your command prompt:
10
+
11
+ $ sudo gem install oklahoma_mixer
12
+
13
+ You must have RubyGems[http://rubyforge.org/projects/rubygems/] installed for
14
+ the above to work.
15
+
16
+ == Running the Tests
17
+
18
+ If you would like to run Oklahoma Mixer's test suite on your system and you have
19
+ Rake installed, just issue the following command from the root of the project
20
+ directory:
21
+
22
+ $ rake
data/MIT-LICENSE ADDED
@@ -0,0 +1,19 @@
1
+ Copyright (c) 2010 James Edward Gray II
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in
11
+ all copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,48 @@
1
+ = What is Oklahoma Mixer?
2
+
3
+ Oklahoma Mixer is a Ruby FFI interface to the C library for Tokyo Cabinet. It allows you to use the key-value store from Ruby.
4
+
5
+ == Why not just use rufus-tokyo?
6
+
7
+ There is already a Ruby FFI interface to Tokyo Cabinet and more called {rufus-tokyo}[http://github.com/jmettraux/rufus-tokyo]. I am a huge fan of rufus-tokyo and have contributed to that project. I have learned a ton from working with rufus-tokyo and that code was my inspiration for this library.
8
+
9
+ That said, I did want to change some things that would require big changes in rufus-tokyo. Here are the things I plan to do differently with Oklahoma Mixer:
10
+
11
+ * Tokyo Cabinet's B+Tree Database has some neat features, like custom ordering
12
+ functions, that are hard to expose through rufus-tokyo due to the way it is
13
+ designed. I would have had to rewrite pretty much that entire section of the
14
+ library anyway to add these features.
15
+ * There are some places where rufus-tokyo uses more memory than it absolutely
16
+ must or slows itself down a bit with extra iterations of the data. Again,
17
+ this is a result of how it is designed. It allows more code reuse at the cost
18
+ of some efficiency. I wanted to improve performance in those areas.
19
+ * I'm working on some higher level abstractions for Tokyo Cabinet that I
20
+ eventually plan to include in this library. These extra tools are the reason
21
+ I needed to make these changes and additions.
22
+ * Finally, rufus-tokyo paved the way to a Ruby-like interface for Tokyo Cabinet.
23
+ Previous choices were scary in comparison. I wanted to push that movement
24
+ even further though and get an even more Hash- and File-like interface, where
25
+ possible.
26
+
27
+ It's important to note though that rufus-tokyo does do some things better and it always will. Its advantages are:
28
+
29
+ * It offers a nice Ruby interface over a raw C extension which is faster than
30
+ using FFI. I have no intention of duplicating that interface, so rufus-tokyo
31
+ will remain the right choice for raw speed when using MRI.
32
+ * For now, rufus-tokyo is more full featured. It provides interfaces for Tokyo
33
+ Tyrant and Tokyo Dystopia. I would like to add these eventually, but I'm
34
+ starting with just Tokyo Cabinet.
35
+ * It offers a pure Ruby interface for communicating with Tokyo Tyrant without
36
+ needing the C libraries installed. I won't be copying that either, so it will
37
+ remain the right choice for a no dependency install.
38
+ * For now, it's more mature. A lot of developers have used it and contributed
39
+ to it. It's probably the safer library to trust for production applications
40
+ at this time.
41
+
42
+ == Why did you call it Oklahoma Mixer?
43
+
44
+ When I was in Japan, people would ask where I was from. When I would tell them, "Oklahoma, U.S.A.," they often replied with, "Ah, I know the Oklahoma Mixer." Some would even dance a little when they said it.
45
+
46
+ It turns out Oklahoma Mixer is a song in Japan. I had to track it down in a music store. It's kind of a camp song medley, including things like the Hokey Pokey. I'm not too sure what that has to do with Oklahoma, but at least they had heard of where I'm from.
47
+
48
+ On a more practical side, this interface to Tokyo Cabinet is from Oklahoma. I intend it to _mix_ together all of the great features of that library in some exciting new ways. Thus, Oklahoma Mixer it is.
data/Rakefile ADDED
@@ -0,0 +1,61 @@
1
+ require "rake/testtask"
2
+ require "rake/rdoctask"
3
+ require "rubygems"
4
+ require "rake/gempackagetask"
5
+
6
+ desc "Default task: run all tests"
7
+ task :default => :test
8
+
9
+ Rake::TestTask.new do |test|
10
+ test.libs << "test"
11
+ test.pattern = "test/*_test.rb"
12
+ test.warning = true
13
+ test.verbose = true
14
+ end
15
+
16
+ Rake::RDocTask.new do |rdoc|
17
+ rdoc.main = "README.rdoc"
18
+ rdoc.rdoc_dir = "doc/html"
19
+ rdoc.title = "Oklahoma Mixer Documentation"
20
+ rdoc.rdoc_files.include *%w[ README.rdoc INSTALL.rdoc
21
+ TODO.rdoc CHANGELOG.rdoc
22
+ AUTHORS.rdoc MIT-LICENSE
23
+ lib/ ]
24
+ end
25
+
26
+ spec = Gem::Specification.new do |spec|
27
+ spec.name = "oklahoma_mixer"
28
+ spec.version = File.read(
29
+ File.join(File.dirname(__FILE__), *%w[lib oklahoma_mixer.rb])
30
+ )[/^\s*VERSION\s*=\s*(['"])(\d\.\d\.\d)\1/, 2]
31
+
32
+ spec.platform = Gem::Platform::RUBY
33
+ spec.summary = "An full featured and robust FFI interface to Tokyo Cabinet."
34
+
35
+ spec.test_files = Dir.glob("test/*_test.rb")
36
+ spec.files = Dir.glob("{lib,test}/**/*.rb") +
37
+ Dir.glob("*.rdoc") +
38
+ %w[MIT-LICENSE Rakefile]
39
+
40
+ spec.has_rdoc = true
41
+ spec.extra_rdoc_files = %w[ README.rdoc INSTALL.rdoc
42
+ TODO.rdoc CHANGELOG.rdoc
43
+ AUTHORS.rdoc MIT-LICENSE ]
44
+ spec.rdoc_options << "--title" << "Oklahoma Mixer Documentation" <<
45
+ "--main" << "README.rdoc"
46
+
47
+ spec.add_dependency("ffi", ">= 0.5.4")
48
+ spec.add_development_dependency("rake")
49
+
50
+ spec.author = "James Edward Gray II"
51
+ spec.email = "james@graysoftinc.com"
52
+ spec.homepage = "http://github.com/JEG2/oklahoma_mixer"
53
+ spec.description = <<END_DESC
54
+ Oklahoma Mixer is a intended to be an all inclusive wrapper for Tokyo Cabinet.
55
+ It provides Rubyish interfaces for all database types and supports the full
56
+ range of features provided.
57
+ END_DESC
58
+ end
59
+ Rake::GemPackageTask.new(spec) do |pkg|
60
+ # do nothing: the spec is all we need
61
+ end
data/TODO.rdoc ADDED
@@ -0,0 +1,11 @@
1
+ = To Do List
2
+
3
+ The following is a list of planned expansions for Oklahoma Mixer in the order I
4
+ intend to address them.
5
+
6
+ 1. Add support for B+Tree and Fixed-length Databases
7
+ 2. Add support for Table Databases
8
+ 3. Ensure Ruby 1.9 compatibility
9
+ 4. Add support for Tokyo Tyrant
10
+ 5. Add support for Tokyo Dystopia
11
+ 6. Include some higher level abstractions like mixed tables, queues, and shards
@@ -0,0 +1,15 @@
1
+ module OklahomaMixer
2
+ class ArrayList
3
+ module C # :nodoc:
4
+ extend OklahomaMixer::Utilities::FFIDSL
5
+
6
+ prefix :tclist
7
+
8
+ def_new_and_del_funcs
9
+
10
+ func :name => :shift,
11
+ :args => [:pointer, :pointer],
12
+ :returns => :pointer
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,23 @@
1
+ module OklahomaMixer
2
+ class ArrayList # :nodoc:
3
+ def initialize(pointer = C.new)
4
+ @pointer = pointer
5
+ end
6
+
7
+ def shift
8
+ C.read_from_func(:shift, @pointer)
9
+ end
10
+
11
+ include Enumerable
12
+
13
+ def each
14
+ while value = shift
15
+ yield value
16
+ end
17
+ end
18
+
19
+ def free
20
+ C.del(@pointer)
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,6 @@
1
+ module OklahomaMixer
2
+ module Error
3
+ class TransactionError < RuntimeError; end
4
+ class CabinetError < RuntimeError; end
5
+ end
6
+ end
@@ -0,0 +1,18 @@
1
+ module OklahomaMixer
2
+ class ExtensibleString
3
+ module C # :nodoc:
4
+ extend OklahomaMixer::Utilities::FFIDSL
5
+
6
+ prefix :tcxstr
7
+
8
+ def_new_and_del_funcs
9
+
10
+ func :name => :ptr,
11
+ :args => :pointer,
12
+ :returns => :pointer
13
+ func :name => :size,
14
+ :args => :pointer,
15
+ :returns => :int
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,27 @@
1
+ module OklahomaMixer
2
+ class ExtensibleString # :nodoc:
3
+ def initialize(pointer = C.new)
4
+ @pointer = pointer
5
+ end
6
+
7
+ attr_reader :pointer
8
+
9
+ def to_s
10
+ data_pointer.get_bytes(0, data_size)
11
+ end
12
+
13
+ def free
14
+ C.del(@pointer)
15
+ end
16
+
17
+ private
18
+
19
+ def data_pointer
20
+ C.ptr(@pointer)
21
+ end
22
+
23
+ def data_size
24
+ C.size(@pointer)
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,128 @@
1
+ module OklahomaMixer
2
+ class HashDatabase
3
+ module C # :nodoc:
4
+ extend OklahomaMixer::Utilities::FFIDSL
5
+
6
+ MODES = enum :HDBOREADER, 1 << 0,
7
+ :HDBOWRITER, 1 << 1,
8
+ :HDBOCREAT, 1 << 2,
9
+ :HDBOTRUNC, 1 << 3,
10
+ :HDBONOLCK, 1 << 4,
11
+ :HDBOLCKNB, 1 << 5,
12
+ :HDBOTSYNC, 1 << 6
13
+ OPTS = enum :HDBTLARGE, 1 << 0,
14
+ :HDBTDEFLATE, 1 << 1,
15
+ :HDBTBZIP, 1 << 2,
16
+ :HDBTTCBS, 1 << 3
17
+
18
+ prefix :tchdb
19
+
20
+ def_new_and_del_funcs
21
+ func :name => :open,
22
+ :args => [:pointer, :string, MODES],
23
+ :returns => :bool
24
+ func :name => :sync,
25
+ :args => :pointer,
26
+ :returns => :bool
27
+ func :name => :fsiz,
28
+ :args => :pointer,
29
+ :returns => :uint64
30
+ func :name => :copy,
31
+ :args => [:pointer, :string],
32
+ :returns => :bool
33
+ func :name => :defrag,
34
+ :args => [:pointer, :int64],
35
+ :returns => :bool
36
+
37
+ func :name => :ecode,
38
+ :args => :pointer,
39
+ :returns => :int
40
+ func :name => :errmsg,
41
+ :args => :int,
42
+ :returns => :string
43
+
44
+ func :name => :setmutex,
45
+ :args => :pointer,
46
+ :returns => :bool
47
+ func :name => :tune,
48
+ :args => [:pointer, :int64, :int8, :int8, OPTS],
49
+ :returns => :bool
50
+ func :name => :setcache,
51
+ :args => [:pointer, :int32],
52
+ :returns => :bool
53
+ func :name => :setxmsiz,
54
+ :args => [:pointer, :int64],
55
+ :returns => :bool
56
+ func :name => :setdfunit,
57
+ :args => [:pointer, :int32],
58
+ :returns => :bool
59
+ func :name => :optimize,
60
+ :args => [:pointer, :int64, :int8, :int8, OPTS],
61
+ :returns => :bool
62
+
63
+ func :name => :put,
64
+ :args => [:pointer, :pointer, :int, :pointer, :int],
65
+ :returns => :bool
66
+ func :name => :putkeep,
67
+ :args => [:pointer, :pointer, :int, :pointer, :int],
68
+ :returns => :bool
69
+ func :name => :putcat,
70
+ :args => [:pointer, :pointer, :int, :pointer, :int],
71
+ :returns => :bool
72
+ func :name => :putasync,
73
+ :args => [:pointer, :pointer, :int, :pointer, :int],
74
+ :returns => :bool
75
+ call :name => :TCPDPROC,
76
+ :args => [:pointer, :int, :pointer, :pointer],
77
+ :returns => :pointer
78
+ func :name => :putproc,
79
+ :args => [:pointer, :pointer, :int, :pointer, :int, :TCPDPROC,
80
+ :pointer],
81
+ :returns => :bool
82
+ func :name => :addint,
83
+ :args => [:pointer, :pointer, :int, :int],
84
+ :returns => :int
85
+ func :name => :adddouble,
86
+ :args => [:pointer, :pointer, :int, :double],
87
+ :returns => :double
88
+ func :name => :out,
89
+ :args => [:pointer, :pointer, :int],
90
+ :returns => :bool
91
+ func :name => :get,
92
+ :args => [:pointer, :pointer, :int, :pointer],
93
+ :returns => :pointer
94
+ func :name => :vanish,
95
+ :args => :pointer,
96
+ :returns => :bool
97
+ func :name => :vanish,
98
+ :args => :pointer,
99
+ :returns => :bool
100
+ func :name => :fwmkeys,
101
+ :args => [:pointer, :pointer, :int, :int],
102
+ :returns => :pointer
103
+ func :name => :rnum,
104
+ :args => :pointer,
105
+ :returns => :uint64
106
+
107
+ func :name => :iterinit,
108
+ :args => [:pointer],
109
+ :returns => :bool
110
+ func :name => :iternext,
111
+ :args => [:pointer, :pointer],
112
+ :returns => :pointer
113
+ func :name => :iternext3,
114
+ :args => [:pointer, :pointer, :pointer],
115
+ :returns => :bool
116
+
117
+ func :name => :tranbegin,
118
+ :args => :pointer,
119
+ :returns => :bool
120
+ func :name => :trancommit,
121
+ :args => :pointer,
122
+ :returns => :bool
123
+ func :name => :tranabort,
124
+ :args => :pointer,
125
+ :returns => :bool
126
+ end
127
+ end
128
+ end