Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Adding the core database functionality. Queries are still needed and …
…I'm punting on tctdbputproc() until I can compare if it could be better implemented with queries than the weak function supplied.
- Loading branch information
Showing
17 changed files
with
714 additions
and
134 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
module OklahomaMixer | ||
class HashMap # :nodoc: | ||
def initialize(pointer = C.new) | ||
@pointer = pointer | ||
end | ||
|
||
attr_reader :pointer | ||
|
||
def update(pairs) | ||
pairs.each do |key, value| | ||
C.put(@pointer, *[yield(key), yield(value)].flatten) | ||
end | ||
end | ||
|
||
def each | ||
C.iterinit(@pointer) | ||
loop do | ||
return self unless key = C.read_from_func(:iternext, :no_free, @pointer) | ||
yield [key, C.read_from_func(:get, :no_free, @pointer, key, key.size)] | ||
end | ||
end | ||
|
||
def free | ||
C.del(@pointer) | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
module OklahomaMixer | ||
class HashMap | ||
module C # :nodoc: | ||
extend OklahomaMixer::Utilities::FFIDSL | ||
|
||
prefix :tcmap | ||
|
||
def_new_and_del_funcs | ||
|
||
func :name => :put, | ||
:args => [:pointer, :pointer, :int, :pointer, :int] | ||
func :name => :get, | ||
:args => [:pointer, :pointer, :int, :pointer], | ||
:returns => :pointer | ||
|
||
func :name => :iterinit, | ||
:args => :pointer | ||
func :name => :iternext, | ||
:args => [:pointer, :pointer], | ||
:returns => :pointer | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
module OklahomaMixer | ||
class TableDatabase < HashDatabase | ||
################################ | ||
### Getting and Setting Keys ### | ||
################################ | ||
|
||
def store(key, value, mode = nil, &dup_handler) | ||
if mode == :add and dup_handler.nil? | ||
super | ||
else | ||
Utilities.temp_map do |map| | ||
map.update(value) { |key_or_value| | ||
cast_to_bytes_and_length(key_or_value) | ||
} | ||
result = super(key, map, mode, &dup_handler) | ||
result == map ? value : result | ||
end | ||
end | ||
end | ||
alias_method :[]=, :store | ||
|
||
def fetch(key, *default) | ||
if value = try( :get, cast_key_in(key), | ||
:failure => lambda { |value| value.address.zero? }, | ||
:no_error => {22 => nil} ) | ||
cast_value_out(value) | ||
else | ||
if block_given? | ||
warn "block supersedes default value argument" unless default.empty? | ||
yield key | ||
elsif not default.empty? | ||
default.first | ||
else | ||
fail IndexError, "key not found" | ||
end | ||
end | ||
end | ||
################# | ||
### Iteration ### | ||
################# | ||
|
||
def each | ||
try(:iterinit) | ||
loop do | ||
begin | ||
pointer = try( :iternext3, | ||
:failure => lambda { |value| value.address.zero? }, | ||
:no_error => {22 => nil} ) | ||
return self unless pointer | ||
map = HashMap.new(pointer) | ||
key, value = nil, { } | ||
map.each do |k, v| | ||
if k.empty? | ||
key = v | ||
else | ||
value[k] = v | ||
end | ||
end | ||
yield [key, value] | ||
ensure | ||
map.free if map | ||
end | ||
end | ||
end | ||
alias_method :each_pair, :each | ||
|
||
####### | ||
private | ||
####### | ||
|
||
def tune(options) | ||
super | ||
if options.values_at(:bnum, :apow, :fpow, :opts).any? | ||
optimize(options.merge(:tune => true)) | ||
end | ||
if options.values_at(:rcnum, :lcnum, :ncnum).any? | ||
setcache(options) | ||
end | ||
end | ||
|
||
def setcache(options) | ||
try( :setcache, | ||
options.fetch(:rcnum, 0).to_i, | ||
options.fetch(:lcnum, 0).to_i, | ||
options.fetch(:ncnum, 0).to_i ) | ||
end | ||
|
||
def cast_value_in(value) | ||
value.pointer | ||
end | ||
|
||
def cast_value_out(pointer) | ||
map = HashMap.new(pointer) | ||
hash = { } | ||
map.each do |key, value| | ||
hash[cast_to_encoded_string(key)] = cast_to_encoded_string(value) | ||
end | ||
hash | ||
ensure | ||
map.free if map | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
module OklahomaMixer | ||
class TableDatabase < HashDatabase | ||
module C # :nodoc: | ||
extend OklahomaMixer::Utilities::FFIDSL | ||
|
||
prefix :tctdb | ||
|
||
const :OPTS, %w[TLARGE TDEFLATE TBZIP TTCBS] | ||
INDEXES = enum :TDBITLEXICAL, 0, | ||
:TDBITDECIMAL, 1, | ||
:TDBITTOKEN, 2, | ||
:TDBITQGRAM, 3, | ||
:TDBITOPT, 9998, | ||
:TDBITVOID, 9999, | ||
:TDBITKEEP, 1 << 24 | ||
|
||
def_core_database_consts_and_funcs | ||
|
||
func :name => :tune, | ||
:args => [:pointer, :int64, :int8, :int8, OPTS], | ||
:returns => :bool | ||
func :name => :setcache, | ||
:args => [:pointer, :int32, :int32, :int32], | ||
:returns => :bool | ||
func :name => :setxmsiz, | ||
:args => [:pointer, :int64], | ||
:returns => :bool | ||
func :name => :setdfunit, | ||
:args => [:pointer, :int32], | ||
:returns => :bool | ||
func :name => :optimize, | ||
:args => [:pointer, :int64, :int8, :int8, OPTS], | ||
:returns => :bool | ||
|
||
func :name => :put, | ||
:args => [:pointer, :pointer, :int, :pointer], | ||
:returns => :bool | ||
func :name => :putkeep, | ||
:args => [:pointer, :pointer, :int, :pointer], | ||
:returns => :bool | ||
func :name => :putcat, | ||
:args => [:pointer, :pointer, :int, :pointer], | ||
:returns => :bool | ||
call :name => :TCPDPROC, | ||
:args => [:pointer, :int, :pointer, :pointer], | ||
:returns => :pointer | ||
func :name => :putproc, | ||
:args => [:pointer, :pointer, :int, :pointer, :int, :TCPDPROC, | ||
:pointer], | ||
:returns => :bool | ||
func :name => :addint, | ||
:args => [:pointer, :pointer, :int, :int], | ||
:returns => :int | ||
func :name => :adddouble, | ||
:args => [:pointer, :pointer, :int, :double], | ||
:returns => :double | ||
func :name => :out, | ||
:args => [:pointer, :pointer, :int], | ||
:returns => :bool | ||
func :name => :get, | ||
:args => [:pointer, :pointer, :int], | ||
:returns => :pointer | ||
func :name => :fwmkeys, | ||
:args => [:pointer, :pointer, :int, :int], | ||
:returns => :pointer | ||
func :name => :genuid, | ||
:args => :pointer, | ||
:returns => :int64 | ||
|
||
func :name => :iterinit, | ||
:args => :pointer, | ||
:returns => :bool | ||
func :name => :iternext, | ||
:args => [:pointer, :pointer], | ||
:returns => :pointer | ||
func :name => :iternext3, | ||
:args => :pointer, | ||
:returns => :pointer | ||
|
||
func :name => :setindex, | ||
:args => [:pointer, :string, INDEXES], | ||
:returns => :bool | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
require "test_helper" | ||
require "shared_iteration" | ||
|
||
class TestDocumentIteration < Test::Unit::TestCase | ||
def setup | ||
@db = tdb | ||
@keys = %w[a b c] | ||
@values = @keys.map { |key| | ||
Hash[*@keys.map { |k| [key + k, "abc".index(k).to_s] }.flatten] | ||
} | ||
@keys.zip(@values) do |key, value| | ||
@db[key] = value | ||
end | ||
end | ||
|
||
def teardown | ||
@db.close | ||
remove_db_files | ||
end | ||
|
||
include SharedIteration | ||
end |
Oops, something went wrong.