ninjudd-bdb 0.0.7 → 0.0.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (5) hide show
  1. data/bdb.gemspec +1 -1
  2. data/ext/bdb.c +15 -9
  3. data/ext/extconf.rb +1 -1
  4. data/lib/bdb/simple.rb +34 -22
  5. metadata +1 -1
@@ -2,7 +2,7 @@ BDB_SPEC = Gem::Specification.new do |s|
2
2
  s.platform = Gem::Platform::RUBY
3
3
  s.required_ruby_version = '>=1.8.4'
4
4
  s.name = "bdb"
5
- s.version = "0.0.7"
5
+ s.version = "0.0.8"
6
6
  s.authors = ["Matt Bauer", "Dan Janowski"]
7
7
  s.email = "bauer@pedalbrain.com"
8
8
  s.summary = "A Ruby interface to BerkeleyDB"
data/ext/bdb.c CHANGED
@@ -1102,17 +1102,23 @@ void assoc_key(DBT* result, VALUE obj) {
1102
1102
  result->flags=LMEMFLAG;
1103
1103
  }
1104
1104
 
1105
- VALUE
1106
- assoc_callback2(VALUE *args)
1105
+ VALUE assoc_call(VALUE *args)
1107
1106
  {
1108
1107
  return rb_funcall(args[0],fv_call,3,args[1],args[2],args[3]);
1109
1108
  }
1110
1109
 
1110
+ VALUE assoc_rescue(VALUE *error, VALUE e)
1111
+ {
1112
+ VALUE message = StringValue(e);
1113
+ rb_warn(RSTRING_PTR(message));
1114
+ *error = e;
1115
+ }
1116
+
1111
1117
  int assoc_callback(DB *secdb, const DBT* key, const DBT* data, DBT* result)
1112
1118
  {
1113
1119
  t_dbh *dbh;
1114
1120
  VALUE proc;
1115
- int status;
1121
+ VALUE error = Qnil;
1116
1122
  VALUE retv;
1117
1123
  VALUE args[4];
1118
1124
  VALUE keys;
@@ -1130,15 +1136,15 @@ int assoc_callback(DB *secdb, const DBT* key, const DBT* data, DBT* result)
1130
1136
  fprintf(stderr,"assoc_data %*s", data->size, data->data);
1131
1137
  #endif
1132
1138
 
1133
- retv=rb_protect((VALUE(*)_((VALUE)))assoc_callback2,(VALUE)args,&status);
1134
-
1135
- if (status) return 99999;
1136
- if ( NIL_P(retv) )
1139
+ retv=rb_rescue((VALUE(*)_((VALUE)))assoc_call,(VALUE)args,(VALUE(*)_((VALUE)))assoc_rescue,(VALUE)&error);
1140
+
1141
+ if (!NIL_P(error)) return 99999;
1142
+ if (NIL_P(retv))
1137
1143
  return DB_DONOTINDEX;
1138
1144
 
1139
1145
  keys = rb_check_array_type(retv);
1140
1146
  if (!NIL_P(keys)) {
1141
- keys = rb_funcall(keys,fv_uniq,0); /* secondary keys must be uniq */
1147
+ keys = rb_funcall(keys,fv_uniq,0); /* secondary keys must be uniq */
1142
1148
  switch(RARRAY(keys)->len) {
1143
1149
  case 0:
1144
1150
  return DB_DONOTINDEX;
@@ -1152,7 +1158,7 @@ int assoc_callback(DB *secdb, const DBT* key, const DBT* data, DBT* result)
1152
1158
  memset(result->data,0,result->size * sizeof(DBT));
1153
1159
 
1154
1160
  for (i=0; i<result->size; i++) {
1155
- assoc_key(result->data + i*sizeof(DBT), (VALUE)RARRAY(keys)->ptr[i]);
1161
+ assoc_key(result->data + i*sizeof(DBT), (VALUE)RARRAY(keys)->ptr[i]);
1156
1162
  }
1157
1163
  return 0;
1158
1164
  }
@@ -35,7 +35,7 @@ Then try building again.
35
35
  end
36
36
  end
37
37
 
38
- versions=%w(db-4.7 db-4.6 db-4.5 db-4.4 db-4.3 db-4.2)
38
+ versions=%w(db-4.8 db-4.7 db-4.6 db-4.5 db-4.4 db-4.3 db-4.2)
39
39
  until versions.empty?
40
40
  (lib_ok = have_library(versions.shift,'db_version', 'db.h')) && break
41
41
  end
@@ -68,37 +68,49 @@ class Bdb::Simple
68
68
  @db = nil
69
69
  end
70
70
 
71
+ CLASS_ORDER = {}
72
+ [FalseClass, TrueClass, Fixnum, Numeric, Float, Symbol, String, Array].each_with_index {|c, i| CLASS_ORDER[c] = i}
73
+
71
74
  def self.compare_absolute(left, right)
72
- if left.class == right.class
73
- if left.is_a?(Array) and right.is_a?(Array)
75
+ if left.is_a?(right.class)
76
+ case left
77
+ when Array
74
78
  # Arrays: compare one element at a time.
75
- left.zip(right) do |l,r|
76
- comp = compare_absolute(l, r)
77
- return comp unless comp == 0
79
+ n = [left.size, right.size].min
80
+ n.times do |i|
81
+ comp = compare_absolute(left[i], right[i])
82
+ return comp if comp != 0
78
83
  end
79
- left.size == right.size ? 0 : -1
80
- elsif left.is_a?(Hash) and right.is_a?(Hash)
81
- # Hashes: sort the keys and compare as an array of arrays.
84
+ left.size <=> right.size
85
+ when Hash
86
+ # Hashes: sort the keys and compare as an array of arrays. This may be slow.
82
87
  left = left.to_a.sort {|a,b| compare_absolute(a[0],b[0])}
83
88
  right = right.to_a.sort {|a,b| compare_absolute(a[0],b[0])}
84
89
  compare_absolute(left, right)
90
+ when NilClass, TrueClass, FalseClass
91
+ 0
92
+ when Symbol
93
+ left.to_s <=> right.to_s
85
94
  else
86
- begin
87
- # Try to use the spaceship operator.
88
- left <=> right
89
- rescue NoMethodError => e
90
- left.hash <=> right.hash
91
- end
92
- end
95
+ # Use the spaceship operator.
96
+ left <=> right
97
+ end
98
+ elsif left.kind_of?(Numeric) and right.kind_of?(Numeric)
99
+ # Numerics are always comparable.
100
+ left <=> right
93
101
  else
94
- # Nil is the smallest. Hash is the largest. All other objects are sorted by class name.
95
- return -1 if left.is_a?(NilClass)
96
- return 1 if right.is_a?(NilClass)
97
- return 1 if left.is_a?(Hash)
98
- return -1 if right.is_a?(Hash)
102
+ # Nil is the smallest. Hash is the largest.
103
+ return -1 if left.is_a?(NilClass) or right.is_a?(Hash)
104
+ return 1 if left.is_a?(Hash) or right.is_a?(NilClass)
99
105
 
100
- # Compare class names and hashes as a last resort if that fails.
101
- right.class.name <=> left.class.name
106
+ # Try to use the class sort order so we don't have to do a string comparison.
107
+ left_order = CLASS_ORDER[left.class]
108
+ right_order = CLASS_ORDER[right.class]
109
+ if left_order.nil? and right_order.nil?
110
+ left.class.name <=> right.class.name
111
+ else
112
+ (left_order || 9999) <=> (right_order || 9999)
113
+ end
102
114
  end
103
115
  end
104
116
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ninjudd-bdb
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.7
4
+ version: 0.0.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matt Bauer