ninjudd-bdb 0.0.7 → 0.0.8

Sign up to get free protection for your applications and to get access to all the features.
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