From cbe9e6ed8a0e481e87d5e65fb95b7c1181d5e9e4 Mon Sep 17 00:00:00 2001 From: Ash Moran Date: Fri, 19 Aug 2011 09:47:07 +0100 Subject: [PATCH 01/13] Remove redundant commented-out code --- ext/tuple.c | 21 --------------------- 1 file changed, 21 deletions(-) diff --git a/ext/tuple.c b/ext/tuple.c index 5faf13a..7c9fbc9 100644 --- a/ext/tuple.c +++ b/ext/tuple.c @@ -174,27 +174,6 @@ static VALUE empty_bignum(int sign, int len) { #error unsupported RUBY_VERSION #endif } -// static VALUE empty_bignum(int sign, int len) { -// /* Create an empty bignum with the right number of digits. */ -// NEWOBJ(num, struct RBignum); -// OBJSETUP(num, rb_cBignum, T_BIGNUM); -// #if defined(RUBY_1_9_x) -// RBIGNUM_SET_SIGN(num, sign ? 1 : 0); -// // RBIGNUM_LEN(num) = len; -// // RBIGNUM_DIGITS(num) = ALLOC_N(BDIGIT, len); -// RBIGNUM(num)->len = len; -// num->digits = ALLOC_N(BDIGIT, len); -// #elif defined(RUBY_1_8_x) -// num->sign = sign ? 1 : 0; -// num->len = len; -// num->digits = ALLOC_N(BDIGIT, len); -// #else -// #error unsupported RUBY_VERSION -// #endif -// -// return (VALUE)num; -// } - static VALUE tuple_parse(void **data, int data_len) { VALUE tuple = rb_ary_new(); From e44a5ef266c95dce0a2158a07d50d0b3123b99b7 Mon Sep 17 00:00:00 2001 From: Ash Moran Date: Mon, 22 Aug 2011 18:21:52 +0100 Subject: [PATCH 02/13] Version bump to 0.1.2 --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 6da28dd..8294c18 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.1.1 \ No newline at end of file +0.1.2 \ No newline at end of file From d6b41d928b7e870581d5812eeaa95ae8ccf905ab Mon Sep 17 00:00:00 2001 From: Ash Moran Date: Mon, 22 Aug 2011 18:40:53 +0100 Subject: [PATCH 03/13] Run `rake gemspec` to prepare for v0.1.2 --- Rakefile | 2 +- tuple.gemspec | 32 +++++++++++++------------------- 2 files changed, 14 insertions(+), 20 deletions(-) diff --git a/Rakefile b/Rakefile index 875d35d..6c99ba8 100644 --- a/Rakefile +++ b/Rakefile @@ -10,7 +10,7 @@ begin s.email = "code@justinbalthrop.com" s.homepage = "http://github.com/ninjudd/tuple" s.description = "Fast, binary-sortable serialization for arrays of simple Ruby types." - s.authors = ["Justin Balthrop"] + s.authors = ["Justin Balthrop", "Ash Moran"] s.files = ["README.rdoc", "VERSION.yml", "ext/tuple.c", "ext/extconf.rb", "test/test_helper.rb", "test/tuple_test.rb"] s.extensions = ["ext/extconf.rb"] s.require_paths = ["ext"] diff --git a/tuple.gemspec b/tuple.gemspec index e810525..bb40299 100644 --- a/tuple.gemspec +++ b/tuple.gemspec @@ -1,44 +1,38 @@ # Generated by jeweler # DO NOT EDIT THIS FILE DIRECTLY -# Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command +# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec' # -*- encoding: utf-8 -*- Gem::Specification.new do |s| s.name = %q{tuple} - s.version = "0.1.1" + s.version = "0.1.2" s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version= - s.authors = ["Justin Balthrop"] - s.date = %q{2009-11-20} + s.authors = [%q{Justin Balthrop}, %q{Ash Moran}] + s.date = %q{2011-08-22} s.description = %q{Fast, binary-sortable serialization for arrays of simple Ruby types.} s.email = %q{code@justinbalthrop.com} - s.extensions = ["ext/extconf.rb"] + s.extensions = [%q{ext/extconf.rb}] s.extra_rdoc_files = [ "LICENSE", - "README.rdoc" + "README.rdoc" ] s.files = [ "README.rdoc", - "ext/extconf.rb", - "ext/tuple.c", - "test/test_helper.rb", - "test/tuple_test.rb" + "ext/extconf.rb", + "ext/tuple.c", + "test/test_helper.rb", + "test/tuple_test.rb" ] s.homepage = %q{http://github.com/ninjudd/tuple} - s.rdoc_options = ["--charset=UTF-8"] - s.require_paths = ["ext"] - s.rubygems_version = %q{1.3.5} + s.require_paths = [%q{ext}] + s.rubygems_version = %q{1.8.6} s.summary = %q{Tuple serialization functions.} - s.test_files = [ - "test/test_helper.rb", - "test/tuple_test.rb" - ] if s.respond_to? :specification_version then - current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION s.specification_version = 3 - if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then + if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then else end else From 8366441b2430031e31be14ec7a857d0da6013f30 Mon Sep 17 00:00:00 2001 From: Ash Moran Date: Wed, 24 Aug 2011 11:21:57 +0100 Subject: [PATCH 04/13] Regenerate gemspec for version 0.1.2 --- tuple.gemspec | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tuple.gemspec b/tuple.gemspec index bb40299..9fc105f 100644 --- a/tuple.gemspec +++ b/tuple.gemspec @@ -9,7 +9,7 @@ Gem::Specification.new do |s| s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version= s.authors = [%q{Justin Balthrop}, %q{Ash Moran}] - s.date = %q{2011-08-22} + s.date = %q{2011-08-24} s.description = %q{Fast, binary-sortable serialization for arrays of simple Ruby types.} s.email = %q{code@justinbalthrop.com} s.extensions = [%q{ext/extconf.rb}] @@ -26,7 +26,7 @@ Gem::Specification.new do |s| ] s.homepage = %q{http://github.com/ninjudd/tuple} s.require_paths = [%q{ext}] - s.rubygems_version = %q{1.8.6} + s.rubygems_version = %q{1.8.7} s.summary = %q{Tuple serialization functions.} if s.respond_to? :specification_version then From 98c850e96388fde608c41e6b0cf0a7b94f50760d Mon Sep 17 00:00:00 2001 From: topac Date: Mon, 13 Apr 2015 15:07:16 +0200 Subject: [PATCH 05/13] refactor to use rake-compiler convensions --- .gitignore | 16 +++++++++- Gemfile | 3 ++ Rakefile | 63 ++++++++++---------------------------- VERSION | 1 - ext/.gitignore | 3 -- ext/{ => tuple}/extconf.rb | 4 ++- ext/{ => tuple}/tuple.c | 12 ++++++-- lib/tuple.rb | 2 ++ lib/tuple/version.rb | 3 ++ tuple.gemspec | 56 +++++++++++++-------------------- tuple.rb | 2 ++ tuple/version.rb | 3 ++ 12 files changed, 79 insertions(+), 89 deletions(-) create mode 100644 Gemfile delete mode 100644 VERSION delete mode 100644 ext/.gitignore rename ext/{ => tuple}/extconf.rb (70%) rename ext/{ => tuple}/tuple.c (97%) create mode 100644 lib/tuple.rb create mode 100644 lib/tuple/version.rb create mode 100644 tuple.rb create mode 100644 tuple/version.rb diff --git a/.gitignore b/.gitignore index 0c6117d..cc63d1e 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,15 @@ -pkg \ No newline at end of file +/.bundle/ +/.yardoc +/Gemfile.lock +/_yardoc/ +/coverage/ +/doc/ +/pkg/ +/spec/reports/ +/tmp/ + +.DS_Store + +Makefile +tuple.bundle +tuple.o diff --git a/Gemfile b/Gemfile new file mode 100644 index 0000000..fa75df1 --- /dev/null +++ b/Gemfile @@ -0,0 +1,3 @@ +source 'https://rubygems.org' + +gemspec diff --git a/Rakefile b/Rakefile index 6c99ba8..44d5a55 100644 --- a/Rakefile +++ b/Rakefile @@ -1,56 +1,27 @@ -require 'rake' require 'rake/testtask' -require 'rake/rdoctask' +require "rake/extensiontask" -begin - require 'jeweler' - Jeweler::Tasks.new do |s| - s.name = "tuple" - s.summary = %Q{Tuple serialization functions.} - s.email = "code@justinbalthrop.com" - s.homepage = "http://github.com/ninjudd/tuple" - s.description = "Fast, binary-sortable serialization for arrays of simple Ruby types." - s.authors = ["Justin Balthrop", "Ash Moran"] - s.files = ["README.rdoc", "VERSION.yml", "ext/tuple.c", "ext/extconf.rb", "test/test_helper.rb", "test/tuple_test.rb"] - s.extensions = ["ext/extconf.rb"] - s.require_paths = ["ext"] - end - Jeweler::GemcutterTasks.new -rescue LoadError - puts "Jeweler not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com" -end - -Rake::TestTask.new do |t| - t.libs << "ext" - t.pattern = 'test/**/*_test.rb' - t.verbose = false +def gemspec + @clean_gemspec ||= eval(File.read(File.expand_path('../tuple.gemspec', __FILE__))) end -Rake::RDocTask.new do |rdoc| - rdoc.rdoc_dir = 'rdoc' - rdoc.title = 'tuple' - rdoc.options << '--line-numbers' << '--inline-source' - rdoc.rdoc_files.include('README*') - rdoc.rdoc_files.include('lib/**/*.rb') -end +Rake::ExtensionTask.new('tuple', gemspec) do |ext| + ext.cross_compile = true + ext.cross_platform = ['x86-mingw32', 'x86-mswin32-60'] + ext.lib_dir = File.join('lib', 'tuple') -begin - require 'rcov/rcovtask' - Rcov::RcovTask.new do |t| - t.libs << 'test' - t.test_files = FileList['test/**/*_test.rb'] - t.verbose = true + # inject 1.8/1.9 pure-ruby entry point when cross compiling only + ext.cross_compiling do |spec| + spec.files << 'lib/tuple/tuple.rb' end -rescue LoadError + + # Clean compiled extension + CLEAN.include "#{ext.lib_dir}/*.#{RbConfig::CONFIG['DLEXT']}" end -desc "Clean" -task :clean do - include FileUtils - Dir.chdir('ext') do - rm(Dir.glob('*') - ['tuple.c', 'extconf.rb']) - end - rm_rf 'pkg' +Rake::TestTask.new(:test) do |test| + test.pattern = 'test/**/test_*.rb' end -task :default => :test +desc "Compile and then run tests" +task :default => [:compile, :test] diff --git a/VERSION b/VERSION deleted file mode 100644 index 8294c18..0000000 --- a/VERSION +++ /dev/null @@ -1 +0,0 @@ -0.1.2 \ No newline at end of file diff --git a/ext/.gitignore b/ext/.gitignore deleted file mode 100644 index b009ee0..0000000 --- a/ext/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -Makefile -tuple.bundle -tuple.o diff --git a/ext/extconf.rb b/ext/tuple/extconf.rb similarity index 70% rename from ext/extconf.rb rename to ext/tuple/extconf.rb index bc87756..784a7e3 100644 --- a/ext/extconf.rb +++ b/ext/tuple/extconf.rb @@ -5,8 +5,10 @@ $CFLAGS += ' -DRUBY_1_8_x' when /\A1\.9/ $CFLAGS += ' -DRUBY_1_9_x' +when /\A2\.(0|1)/ + $CFLAGS += ' -DRUBY_1_9_x' else raise "unsupported Ruby version: #{RUBY_VERSION}" end -create_makefile('tuple') +create_makefile('tuple/tuple') diff --git a/ext/tuple.c b/ext/tuple/tuple.c similarity index 97% rename from ext/tuple.c rename to ext/tuple/tuple.c index 7c9fbc9..2f9601e 100644 --- a/ext/tuple.c +++ b/ext/tuple/tuple.c @@ -1,5 +1,13 @@ #include "ruby.h" -#include + +#ifdef _WIN32 + #include + + typedef uint8_t u_int8_t; + typedef uint32_t u_int32_t; +#else + #include +#endif VALUE mTuple; VALUE rb_cDate; @@ -15,7 +23,7 @@ VALUE rb_cDate; #define FALSE_SORT 1 // FalseClass #define NIL_SORT 0 // NilClass -#define BDIGITS(x) ((BDIGIT*)RBIGNUM(x)->digits) +// #define BDIGITS(x) ((BDIGIT*)RBIGNUM(x)->digits) static void null_pad(VALUE data, int len) { static u_int8_t null = 0; diff --git a/lib/tuple.rb b/lib/tuple.rb new file mode 100644 index 0000000..b32d6f5 --- /dev/null +++ b/lib/tuple.rb @@ -0,0 +1,2 @@ +require "tuple/version" +require "tuple/tuple" diff --git a/lib/tuple/version.rb b/lib/tuple/version.rb new file mode 100644 index 0000000..cbf2cc3 --- /dev/null +++ b/lib/tuple/version.rb @@ -0,0 +1,3 @@ +module Tuple + VERSION = "0.1.2" +end diff --git a/tuple.gemspec b/tuple.gemspec index 9fc105f..99fa087 100644 --- a/tuple.gemspec +++ b/tuple.gemspec @@ -1,41 +1,27 @@ -# Generated by jeweler -# DO NOT EDIT THIS FILE DIRECTLY -# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec' -# -*- encoding: utf-8 -*- +$:.unshift File.expand_path("../lib", __FILE__) +require "tuple/version" -Gem::Specification.new do |s| - s.name = %q{tuple} - s.version = "0.1.2" +Gem::Specification.new do |spec| + spec.name = "tuple" + spec.authors = ["Justin Balthrop", "Ash Moran", "topac"] + spec.email = "code@justinbalthrop.com" + spec.description = "Fast, binary-sortable serialization for arrays of simple Ruby types" + spec.summary = "Tuple serialization functions" + spec.homepage = "http://github.com/ninjudd/tuple" + spec.version = Tuple::VERSION + spec.license = "MIT" - s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version= - s.authors = [%q{Justin Balthrop}, %q{Ash Moran}] - s.date = %q{2011-08-24} - s.description = %q{Fast, binary-sortable serialization for arrays of simple Ruby types.} - s.email = %q{code@justinbalthrop.com} - s.extensions = [%q{ext/extconf.rb}] - s.extra_rdoc_files = [ - "LICENSE", - "README.rdoc" - ] - s.files = [ - "README.rdoc", - "ext/extconf.rb", - "ext/tuple.c", - "test/test_helper.rb", - "test/tuple_test.rb" - ] - s.homepage = %q{http://github.com/ninjudd/tuple} - s.require_paths = [%q{ext}] - s.rubygems_version = %q{1.8.7} - s.summary = %q{Tuple serialization functions.} + spec.files = `git ls-files`.split($\) - if s.respond_to? :specification_version then - s.specification_version = 3 + spec.executables = spec.files.grep(%r{^bin/}).map{ |f| File.basename(f) } + spec.test_files = spec.files.grep(%r{^(test|spec|features)/}) + spec.extensions = ["ext/tuple/extconf.rb"] + spec.require_paths = ["lib"] - if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then - else - end - else + if spec.respond_to?(:metadata) + spec.metadata['allowed_push_host'] = "TODO: Set to 'http://mygemserver.com' to prevent pushes to rubygems.org, or delete to allow pushes to any server." end -end + spec.add_development_dependency 'rake-compiler', '~> 0.8.3' + spec.add_development_dependency 'test-unit', '~> 2.0' +end diff --git a/tuple.rb b/tuple.rb new file mode 100644 index 0000000..b32d6f5 --- /dev/null +++ b/tuple.rb @@ -0,0 +1,2 @@ +require "tuple/version" +require "tuple/tuple" diff --git a/tuple/version.rb b/tuple/version.rb new file mode 100644 index 0000000..cbf2cc3 --- /dev/null +++ b/tuple/version.rb @@ -0,0 +1,3 @@ +module Tuple + VERSION = "0.1.2" +end From ff7c5e354ada609a71cc2b2fe6b1d858274aee46 Mon Sep 17 00:00:00 2001 From: topac Date: Mon, 13 Apr 2015 15:07:29 +0200 Subject: [PATCH 06/13] use markdown --- README.rdoc => README.md | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) rename README.rdoc => README.md (52%) diff --git a/README.rdoc b/README.md similarity index 52% rename from README.rdoc rename to README.md index a482034..62f4a24 100644 --- a/README.rdoc +++ b/README.md @@ -1,12 +1,13 @@ -= Tuple +# Tuple -Tuple provides fast, binary-sortable serialization for arrays of simple Ruby types. This -means you do not have to deserialize your tuples to store them. This leads to significant +Tuple provides fast, binary-sortable serialization for arrays of simple Ruby types. + +This means you do not have to deserialize your tuples to store them. This leads to significant performance benifits when using Tuples as keys for a BTree. A Tuple is just an Array of any number of simple Ruby types. The following types are supported (listed in ascending sort order): - + 1. NilClass 2. FalseClass 3. Integer (Fixnum or Bignum) @@ -14,19 +15,23 @@ supported (listed in ascending sort order): 5. Symbol 6. True -== Usage: - +## Usage + +```ruby require 'tuple' data = Tuple.dump([1, -43, :foo, "bar", true, false, nil]) - => "\000\000\020\000\000\000\000\001..." + # => "\000\000\020\000\000\000\000\001..." Tuple.load(data) - => [1, -43, :foo, "bar", true, false, nil] + # => [1, -43, :foo, "bar", true, false, nil] +``` -== Install: +## Install - sudo gem install ninjudd-tuple -s http://gems.github.com +``` + gem install tuple +``` -== License: +## License -Copyright (c) 2009 Justin Balthrop, Geni.com; Published under The MIT License, see LICENSE \ No newline at end of file +Copyright (c) 2009 Justin Balthrop; Published under The MIT License, see LICENSE file. \ No newline at end of file From 1c1592da6cdebf9d311bc91f117aac9f6a2debf6 Mon Sep 17 00:00:00 2001 From: topac Date: Mon, 13 Apr 2015 15:07:49 +0200 Subject: [PATCH 07/13] refactor + split into multiple files --- test/helper.rb | 32 +++++++++++++++++++++ test/test_bignums.rb | 11 +++++++ test/test_dump_and_load.rb | 12 ++++++++ test/test_helper.rb | 22 -------------- test/{tuple_test.rb => test_sort.rb} | 43 ++++------------------------ test/test_time.rb | 12 ++++++++ 6 files changed, 72 insertions(+), 60 deletions(-) create mode 100644 test/helper.rb create mode 100644 test/test_bignums.rb create mode 100644 test/test_dump_and_load.rb delete mode 100644 test/test_helper.rb rename test/{tuple_test.rb => test_sort.rb} (56%) create mode 100644 test/test_time.rb diff --git a/test/helper.rb b/test/helper.rb new file mode 100644 index 0000000..5f78372 --- /dev/null +++ b/test/helper.rb @@ -0,0 +1,32 @@ +require 'rubygems' +require 'test/unit' +require 'tuple' + +if not [].respond_to?(:shuffle) + class Array + def shuffle + t_self = self.dup + t_size = self.size + result=[] + t_size.times { result << t_self.slice!(rand(t_self.size)) } + result + end + end +end + +class Time + def ==(other) + # Ignore microseconds for testing. + to_i == other.to_i + end +end + +class TestTuple < Test::Unit::TestCase + def now + @now ||= Time.now + end + + def today + @today ||= Date.today + end +end diff --git a/test/test_bignums.rb b/test/test_bignums.rb new file mode 100644 index 0000000..53b764e --- /dev/null +++ b/test/test_bignums.rb @@ -0,0 +1,11 @@ +require_relative "helper" + +class TestTuple + def test_bignums + t = [2**64, 2**38, 2**32, 2**32 - 1, 2**31, 2**31 - 1, 1, 0] + t = t + t.reverse.collect {|n| -n} + + assert_equal t, Tuple.load(Tuple.dump(t)) + assert_equal t.reverse, t.sort_by {|i| Tuple.dump(i)} + end +end diff --git a/test/test_dump_and_load.rb b/test/test_dump_and_load.rb new file mode 100644 index 0000000..c75e3e1 --- /dev/null +++ b/test/test_dump_and_load.rb @@ -0,0 +1,12 @@ +require_relative "helper" + +class TestTuple + def test_dump_and_load + t = [1, true, :foo, "foo", -1001, false, nil, now, today - 7, [:foo, 1, 4, nil]] + assert_equal t, Tuple.load(Tuple.dump(t)) + end + + def test_single_value + assert_equal [1], Tuple.load(Tuple.dump(1)) + end +end diff --git a/test/test_helper.rb b/test/test_helper.rb deleted file mode 100644 index 98a2486..0000000 --- a/test/test_helper.rb +++ /dev/null @@ -1,22 +0,0 @@ -require 'rubygems' -require 'test/unit' -require 'shoulda' -require 'mocha' - -$LOAD_PATH.unshift(File.dirname(__FILE__) + '/../ext') -require 'tuple' - -if not [].respond_to?(:shuffle) - class Array - def shuffle - t_self = self.dup - t_size = self.size - result=[] - t_size.times { result << t_self.slice!(rand(t_self.size)) } - result - end - end -end - -class Test::Unit::TestCase -end diff --git a/test/tuple_test.rb b/test/test_sort.rb similarity index 56% rename from test/tuple_test.rb rename to test/test_sort.rb index 98cbfa6..a085106 100644 --- a/test/tuple_test.rb +++ b/test/test_sort.rb @@ -1,41 +1,7 @@ -require File.dirname(__FILE__) + '/test_helper' - -class Time - def ==(other) - # Ignore microseconds for testing. - to_i == other.to_i - end -end - -class TupleTest < Test::Unit::TestCase - should "dump and load arrays of simple types" do - t = [1, true, :foo, "foo", -1001, false, nil, Time.now, Date.today - 7, [:foo, 1, 4, nil]] - assert_equal t, Tuple.load(Tuple.dump(t)) - end - - should "dump, load, and sort fixnums and bignums" do - t = [2**64, 2**38, 2**32, 2**32 - 1, 2**31, 2**31 - 1, 1, 0] - t = t + t.reverse.collect {|n| -n} - assert_equal t, Tuple.load(Tuple.dump(t)) - assert_equal t.reverse, t.sort_by {|i| Tuple.dump(i)} - end - - should "convert single value into array" do - assert_equal [1], Tuple.load(Tuple.dump(1)) - end - - should "dump times consistently" do - t = '2009-10-15 1:23:45 PM' - tuple = Tuple.dump(Time.parse(t)) - 100000.times do - assert_equal tuple, Tuple.dump(Time.parse(t)) - end - end - - should "sort tuples using binary" do - now = Time.now.getgm - today = Date.parse(now.to_s) +require_relative "helper" +class TestTuple + def test_sort tuples = [ [1, "foo"], [1, true], @@ -87,10 +53,11 @@ class TupleTest < Test::Unit::TestCase [today + 1], [true] ] + assert_equal expected, tuples.sort_by {|t| Tuple.dump(t)} 100.times do assert_equal expected, tuples.shuffle.sort_by {|t| Tuple.dump(t)} end - end + end end diff --git a/test/test_time.rb b/test/test_time.rb new file mode 100644 index 0000000..789aad6 --- /dev/null +++ b/test/test_time.rb @@ -0,0 +1,12 @@ +require_relative "helper" + +class TestTuple + def test_time + t = '2009-10-15 1:23:45 PM' + tuple = Tuple.dump(Time.parse(t)) + + 10000.times do + assert_equal tuple, Tuple.dump(Time.parse(t)) + end + end +end From 501d4458deb64e1151fd79c4f064d7ccd4541ae4 Mon Sep 17 00:00:00 2001 From: topac Date: Mon, 13 Apr 2015 15:08:06 +0200 Subject: [PATCH 08/13] travis config file --- .travis.yml | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..df8c040 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,10 @@ +language: ruby +rvm: + - 1.8.7 + - 1.9.2 + - 1.9.3 + - 2.0.0 + - rbx +os: + - linux + - osx From 773d1d424c82dda382023a83a4b86f0a3d469a6a Mon Sep 17 00:00:00 2001 From: topac Date: Mon, 13 Apr 2015 15:32:42 +0200 Subject: [PATCH 09/13] require_relative does not work with ruby 1.8.7 --- test/test_bignums.rb | 2 +- test/test_dump_and_load.rb | 2 +- test/test_sort.rb | 2 +- test/test_time.rb | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/test/test_bignums.rb b/test/test_bignums.rb index 53b764e..1c9eef7 100644 --- a/test/test_bignums.rb +++ b/test/test_bignums.rb @@ -1,4 +1,4 @@ -require_relative "helper" +require File.join(File.dirname(__FILE__), 'helper') class TestTuple def test_bignums diff --git a/test/test_dump_and_load.rb b/test/test_dump_and_load.rb index c75e3e1..7b0c705 100644 --- a/test/test_dump_and_load.rb +++ b/test/test_dump_and_load.rb @@ -1,4 +1,4 @@ -require_relative "helper" +require File.join(File.dirname(__FILE__), 'helper') class TestTuple def test_dump_and_load diff --git a/test/test_sort.rb b/test/test_sort.rb index a085106..f77552f 100644 --- a/test/test_sort.rb +++ b/test/test_sort.rb @@ -1,4 +1,4 @@ -require_relative "helper" +require File.join(File.dirname(__FILE__), 'helper') class TestTuple def test_sort diff --git a/test/test_time.rb b/test/test_time.rb index 789aad6..e3a2266 100644 --- a/test/test_time.rb +++ b/test/test_time.rb @@ -1,4 +1,4 @@ -require_relative "helper" +require File.join(File.dirname(__FILE__), 'helper') class TestTuple def test_time From 669ea6e7b4e201356e233fd4ae95bfc66eefb7d2 Mon Sep 17 00:00:00 2001 From: topac Date: Mon, 13 Apr 2015 15:34:52 +0200 Subject: [PATCH 10/13] add ruby 2.1.x to travis config file --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index df8c040..5ffb472 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,6 +4,7 @@ rvm: - 1.9.2 - 1.9.3 - 2.0.0 + - 2.1 - rbx os: - linux From df81a443d67ca90b6e31732641cb121de3d32ebd Mon Sep 17 00:00:00 2001 From: topac Date: Mon, 13 Apr 2015 18:05:52 +0200 Subject: [PATCH 11/13] add support for ruby 2.2.x --- .travis.yml | 2 +- ext/tuple/extconf.rb | 6 +++++- ext/tuple/tuple.c | 20 ++++++++++++++------ 3 files changed, 20 insertions(+), 8 deletions(-) diff --git a/.travis.yml b/.travis.yml index 5ffb472..ba74f49 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,7 +5,7 @@ rvm: - 1.9.3 - 2.0.0 - 2.1 - - rbx + - 2.2 os: - linux - osx diff --git a/ext/tuple/extconf.rb b/ext/tuple/extconf.rb index 784a7e3..ce4e688 100644 --- a/ext/tuple/extconf.rb +++ b/ext/tuple/extconf.rb @@ -6,7 +6,11 @@ when /\A1\.9/ $CFLAGS += ' -DRUBY_1_9_x' when /\A2\.(0|1)/ - $CFLAGS += ' -DRUBY_1_9_x' + $CFLAGS += ' -DRUBY_2_x_x' + $CFLAGS += ' -DRUBY_2_1_x' +when /\A2\.2/ + $CFLAGS += ' -DRUBY_2_x_x' + $CFLAGS += ' -DRUBY_2_2_x' else raise "unsupported Ruby version: #{RUBY_VERSION}" end diff --git a/ext/tuple/tuple.c b/ext/tuple/tuple.c index 2f9601e..040c012 100644 --- a/ext/tuple/tuple.c +++ b/ext/tuple/tuple.c @@ -23,7 +23,15 @@ VALUE rb_cDate; #define FALSE_SORT 1 // FalseClass #define NIL_SORT 0 // NilClass -// #define BDIGITS(x) ((BDIGIT*)RBIGNUM(x)->digits) +#if defined(RUBY_2_2_x) + #ifdef HAVE_INT64_T + # define BDIGIT uint32_t + #else + # define BDIGIT uint16_t + #endif +#endif + +#define BDIGITS(x) ((BDIGIT*)RBIGNUM(x)->digits) static void null_pad(VALUE data, int len) { static u_int8_t null = 0; @@ -67,7 +75,7 @@ static VALUE tuple_dump(VALUE self, VALUE tuple) { if (TYPE(tuple) != T_ARRAY) tuple = rb_ary_new4(1, &tuple); -#if defined(RUBY_1_9_x) +#if defined(RUBY_1_9_x) || defined(RUBY_2_x_x) for (i = 0; i < RARRAY_LEN(tuple); i++) { item = RARRAY_PTR(tuple)[i]; #elif defined(RUBY_1_8_x) @@ -95,7 +103,7 @@ static VALUE tuple_dump(VALUE self, VALUE tuple) { digit = htonl(sign ? digit : UINT_MAX - digit); rb_str_cat(data, (char*)&digit, sizeof(digit)); } else if (TYPE(item) == T_BIGNUM) { -#if defined(RUBY_1_9_x) +#if defined(RUBY_1_9_x) || defined(RUBY_2_x_x) sign = RBIGNUM_SIGN(item); len = RBIGNUM_LEN(item); #elif defined(RUBY_1_8_x) @@ -108,7 +116,7 @@ static VALUE tuple_dump(VALUE self, VALUE tuple) { header[3] = sign ? len : UCHAR_MAX - len; rb_str_cat(data, (char*)&header, sizeof(header)); -#if defined(RUBY_1_9_x) +#if defined(RUBY_1_9_x) || defined(RUBY_2_x_x) digits = RBIGNUM_DIGITS(item); #elif defined(RUBY_1_8_x) digits = BDIGITS(item); @@ -166,7 +174,7 @@ static VALUE tuple_dump(VALUE self, VALUE tuple) { } static VALUE empty_bignum(int sign, int len) { -#if defined(RUBY_1_9_x) +#if defined(RUBY_1_9_x) || defined(RUBY_2_x_x) return rb_big_new(len, sign); #elif defined(RUBY_1_8_x) /* Create an empty bignum with the right number of digits. */ @@ -207,7 +215,7 @@ static VALUE tuple_parse(void **data, int data_len) { len = sign ? header[3] : (UCHAR_MAX - header[3]); item = empty_bignum(sign, len); -#if defined(RUBY_1_9_x) +#if defined(RUBY_1_9_x) || defined(RUBY_2_x_x) digits = RBIGNUM_DIGITS(item); #elif defined(RUBY_1_8_x) digits = BDIGITS(item); From d8d08ccad78d23eb1b057a03824d015300f30365 Mon Sep 17 00:00:00 2001 From: topac Date: Tue, 14 Apr 2015 11:39:54 +0200 Subject: [PATCH 12/13] bignum from ruby 2.2.x --- ext/tuple/bignum.h | 66 ++++++++++++++++++++++++++++++++++++++++++++++ ext/tuple/tuple.c | 25 ++++++++++-------- 2 files changed, 80 insertions(+), 11 deletions(-) create mode 100644 ext/tuple/bignum.h diff --git a/ext/tuple/bignum.h b/ext/tuple/bignum.h new file mode 100644 index 0000000..df0d403 --- /dev/null +++ b/ext/tuple/bignum.h @@ -0,0 +1,66 @@ +#ifndef BDIGIT +# if SIZEOF_INT*2 <= SIZEOF_LONG_LONG +# define BDIGIT unsigned int +# define SIZEOF_BDIGIT SIZEOF_INT +# elif SIZEOF_INT*2 <= SIZEOF_LONG +# define BDIGIT unsigned int +# define SIZEOF_BDIGIT SIZEOF_INT +# elif SIZEOF_SHORT*2 <= SIZEOF_LONG +# define BDIGIT unsigned short +# define SIZEOF_BDIGIT SIZEOF_SHORT +# else +# define BDIGIT unsigned short +# define SIZEOF_BDIGIT (SIZEOF_LONG/2) +# define SIZEOF_ACTUAL_BDIGIT SIZEOF_LONG +# endif +#endif + +#ifndef SIZEOF_ACTUAL_BDIGIT +# define SIZEOF_ACTUAL_BDIGIT SIZEOF_BDIGIT +#endif + +#define BIGNUM_EMBED_LEN_NUMBITS 3 +#ifndef BIGNUM_EMBED_LEN_MAX +# if (SIZEOF_VALUE*3/SIZEOF_ACTUAL_BDIGIT) < (1 << BIGNUM_EMBED_LEN_NUMBITS)-1 +# define BIGNUM_EMBED_LEN_MAX (SIZEOF_VALUE*3/SIZEOF_ACTUAL_BDIGIT) +# else +# define BIGNUM_EMBED_LEN_MAX ((1 << BIGNUM_EMBED_LEN_NUMBITS)-1) +# endif +#endif + +struct RBignum { + struct RBasic basic; + union { + struct { + size_t len; + BDIGIT *digits; + } heap; + BDIGIT ary[BIGNUM_EMBED_LEN_MAX]; + } as; +}; + +#define BIGNUM_SIGN_BIT FL_USER1 +/* sign: positive:1, negative:0 */ +#define BIGNUM_SIGN(b) ((RBASIC(b)->flags & BIGNUM_SIGN_BIT) != 0) +#define BIGNUM_SET_SIGN(b,sign) \ + ((sign) ? (RBASIC(b)->flags |= BIGNUM_SIGN_BIT) \ + : (RBASIC(b)->flags &= ~BIGNUM_SIGN_BIT)) +#define BIGNUM_POSITIVE_P(b) BIGNUM_SIGN(b) +#define BIGNUM_NEGATIVE_P(b) (!BIGNUM_SIGN(b)) + +#define BIGNUM_EMBED_FLAG FL_USER2 +#define BIGNUM_EMBED_LEN_MASK (FL_USER5|FL_USER4|FL_USER3) +#define BIGNUM_EMBED_LEN_SHIFT (FL_USHIFT+BIGNUM_EMBED_LEN_NUMBITS) +#define BIGNUM_LEN(b) \ + ((RBASIC(b)->flags & BIGNUM_EMBED_FLAG) ? \ + (long)((RBASIC(b)->flags >> BIGNUM_EMBED_LEN_SHIFT) & \ + (BIGNUM_EMBED_LEN_MASK >> BIGNUM_EMBED_LEN_SHIFT)) : \ + RBIGNUM(b)->as.heap.len) +/* LSB:BIGNUM_DIGITS(b)[0], MSB:BIGNUM_DIGITS(b)[BIGNUM_LEN(b)-1] */ +#define BIGNUM_DIGITS(b) \ + ((RBASIC(b)->flags & BIGNUM_EMBED_FLAG) ? \ + RBIGNUM(b)->as.ary : \ + RBIGNUM(b)->as.heap.digits) +#define BIGNUM_LENINT(b) rb_long2int(BIGNUM_LEN(b)) + +#define RBIGNUM(obj) (R_CAST(RBignum)(obj)) diff --git a/ext/tuple/tuple.c b/ext/tuple/tuple.c index 040c012..cddb15b 100644 --- a/ext/tuple/tuple.c +++ b/ext/tuple/tuple.c @@ -9,6 +9,10 @@ #include #endif +#if defined(RUBY_2_2_x) + #include "bignum.h" +#endif + VALUE mTuple; VALUE rb_cDate; @@ -23,14 +27,6 @@ VALUE rb_cDate; #define FALSE_SORT 1 // FalseClass #define NIL_SORT 0 // NilClass -#if defined(RUBY_2_2_x) - #ifdef HAVE_INT64_T - # define BDIGIT uint32_t - #else - # define BDIGIT uint16_t - #endif -#endif - #define BDIGITS(x) ((BDIGIT*)RBIGNUM(x)->digits) static void null_pad(VALUE data, int len) { @@ -103,7 +99,10 @@ static VALUE tuple_dump(VALUE self, VALUE tuple) { digit = htonl(sign ? digit : UINT_MAX - digit); rb_str_cat(data, (char*)&digit, sizeof(digit)); } else if (TYPE(item) == T_BIGNUM) { -#if defined(RUBY_1_9_x) || defined(RUBY_2_x_x) +#if defined(RUBY_2_2_x) + sign = BIGNUM_SIGN(item); + len = BIGNUM_LEN(item); +#elif defined(RUBY_1_9_x) || defined(RUBY_2_x_x) sign = RBIGNUM_SIGN(item); len = RBIGNUM_LEN(item); #elif defined(RUBY_1_8_x) @@ -116,7 +115,9 @@ static VALUE tuple_dump(VALUE self, VALUE tuple) { header[3] = sign ? len : UCHAR_MAX - len; rb_str_cat(data, (char*)&header, sizeof(header)); -#if defined(RUBY_1_9_x) || defined(RUBY_2_x_x) +#if defined(RUBY_2_2_x) + digits = BIGNUM_DIGITS(item); +#elif defined(RUBY_1_9_x) || defined(RUBY_2_x_x) digits = RBIGNUM_DIGITS(item); #elif defined(RUBY_1_8_x) digits = BDIGITS(item); @@ -215,7 +216,9 @@ static VALUE tuple_parse(void **data, int data_len) { len = sign ? header[3] : (UCHAR_MAX - header[3]); item = empty_bignum(sign, len); -#if defined(RUBY_1_9_x) || defined(RUBY_2_x_x) +#if defined(RUBY_2_2_x) + digits = BIGNUM_DIGITS(item); +#elif defined(RUBY_1_9_x) || defined(RUBY_2_x_x) digits = RBIGNUM_DIGITS(item); #elif defined(RUBY_1_8_x) digits = BDIGITS(item); From a34d217ac183681d7c47055749d49eb8b2c94e62 Mon Sep 17 00:00:00 2001 From: topac Date: Tue, 14 Apr 2015 11:40:06 +0200 Subject: [PATCH 13/13] clean task --- Rakefile | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/Rakefile b/Rakefile index 44d5a55..8ed78ad 100644 --- a/Rakefile +++ b/Rakefile @@ -25,3 +25,15 @@ end desc "Compile and then run tests" task :default => [:compile, :test] + +task :clean do + include FileUtils + + rm_rf("tmp") + + Dir["*/**/*"].each do |path| + if path =~ /(\.o|\.bundle|\/Makefile)\z/ + rm_f(path) + end + end +end