bson_ext 1.0.7 → 1.0.9

Sign up to get free protection for your applications and to get access to all the features.
Files changed (3) hide show
  1. data/ext/cbson/cbson.c +56 -48
  2. data/ext/cbson/version.h +1 -1
  3. metadata +4 -4
data/ext/cbson/cbson.c CHANGED
@@ -31,10 +31,6 @@
31
31
  # define RSTRING_LEN(v) RSTRING(v)->len
32
32
  #endif
33
33
 
34
- #ifndef RARRAY_PTR
35
- # define RARRAY_PTR(v) RARRAY(v)->ptr
36
- #endif
37
-
38
34
  #ifndef RARRAY_LEN
39
35
  # define RARRAY_LEN(v) RARRAY(v)->len
40
36
  #endif
@@ -72,6 +68,12 @@
72
68
 
73
69
  #define MAX_HOSTNAME_LENGTH 256
74
70
 
71
+ static ID element_assignment_method;
72
+ static ID unpack_method;
73
+ static ID utc_method;
74
+ static ID lt_operator;
75
+ static ID gt_operator;
76
+
75
77
  static VALUE Binary;
76
78
  static VALUE ObjectID;
77
79
  static VALUE ObjectId;
@@ -177,6 +179,9 @@ static void write_utf8(buffer_t buffer, VALUE string, char check_null) {
177
179
  static char zero = 0;
178
180
  static char one = 1;
179
181
 
182
+ static char hostname_digest[17];
183
+ static unsigned int object_id_inc = 0;
184
+
180
185
  static int cmp_char(const void* a, const void* b) {
181
186
  return *(char*)a - *(char*)b;
182
187
  }
@@ -231,23 +236,27 @@ static int write_element(VALUE key, VALUE value, VALUE extra, int allow_id) {
231
236
 
232
237
  switch(TYPE(value)) {
233
238
  case T_BIGNUM:
234
- case T_FIXNUM:
235
239
  {
236
- if (rb_funcall(value, rb_intern(">"), 1, LL2NUM(9223372036854775807LL)) == Qtrue ||
237
- rb_funcall(value, rb_intern("<"), 1, LL2NUM(-9223372036854775808ULL)) == Qtrue) {
240
+ if (rb_funcall(value, gt_operator, 1, LL2NUM(9223372036854775807LL)) == Qtrue ||
241
+ rb_funcall(value, lt_operator, 1, LL2NUM(-9223372036854775808ULL)) == Qtrue) {
238
242
  buffer_free(buffer);
239
243
  rb_raise(rb_eRangeError, "MongoDB can only handle 8-byte ints");
240
244
  }
241
- if (rb_funcall(value, rb_intern(">"), 1, INT2NUM(2147483647L)) == Qtrue ||
242
- rb_funcall(value, rb_intern("<"), 1, INT2NUM(-2147483648L)) == Qtrue) {
243
- long long ll_value;
245
+ }
246
+ // NOTE: falls through to T_FIXNUM code
247
+ case T_FIXNUM:
248
+ {
249
+ long long ll_value;
250
+ ll_value = NUM2LL(value);
251
+
252
+ if (ll_value > 2147483647L ||
253
+ ll_value < -2147483648L) {
244
254
  write_name_and_type(buffer, key, 0x12);
245
- ll_value = NUM2LL(value);
246
255
  SAFE_WRITE(buffer, (char*)&ll_value, 8);
247
256
  } else {
248
257
  int int_value;
249
258
  write_name_and_type(buffer, key, 0x10);
250
- int_value = NUM2LL(value);
259
+ int_value = ll_value;
251
260
  SAFE_WRITE(buffer, (char*)&int_value, 4);
252
261
  }
253
262
  break;
@@ -298,13 +307,12 @@ static int write_element(VALUE key, VALUE value, VALUE extra, int allow_id) {
298
307
  }
299
308
 
300
309
  items = RARRAY_LEN(value);
301
- values = RARRAY_PTR(value);
302
310
  for(i = 0; i < items; i++) {
303
311
  char* name;
304
312
  VALUE key;
305
313
  INT2STRING(&name, i);
306
314
  key = rb_str_new2(name);
307
- write_element_with_id(key, values[i], pack_extra(buffer, check_keys));
315
+ write_element_with_id(key, rb_ary_entry(value, i), pack_extra(buffer, check_keys));
308
316
  free(name);
309
317
  }
310
318
 
@@ -385,7 +393,7 @@ static int write_element(VALUE key, VALUE value, VALUE extra, int allow_id) {
385
393
  int i;
386
394
  write_name_and_type(buffer, key, 0x07);
387
395
  for (i = 0; i < 12; i++) {
388
- char byte = (char)FIX2INT(RARRAY_PTR(as_array)[i]);
396
+ char byte = (char)FIX2INT(rb_ary_entry(as_array, i));
389
397
  SAFE_WRITE(buffer, &byte, 1);
390
398
  }
391
399
  break;
@@ -558,7 +566,7 @@ static void write_doc(buffer_t buffer, VALUE hash, VALUE check_keys, VALUE move_
558
566
  VALUE keys = rb_funcall(hash, rb_intern("keys"), 0);
559
567
  int i;
560
568
  for(i = 0; i < RARRAY_LEN(keys); i++) {
561
- VALUE key = RARRAY_PTR(keys)[i];
569
+ VALUE key = rb_ary_entry(keys, i);
562
570
  VALUE value = rb_hash_aref(hash, key);
563
571
 
564
572
  write_function(key, value, pack_extra(buffer, check_keys));
@@ -696,7 +704,7 @@ static VALUE get_value(const char* buffer, int* position, int type) {
696
704
  case 7:
697
705
  {
698
706
  VALUE str = rb_str_new(buffer + *position, 12);
699
- VALUE oid = rb_funcall(str, rb_intern("unpack"), 1, rb_str_new2("C*"));
707
+ VALUE oid = rb_funcall(str, unpack_method, 1, rb_str_new2("C*"));
700
708
  value = rb_class_new_instance(1, &oid, ObjectId);
701
709
  *position += 12;
702
710
  break;
@@ -712,7 +720,7 @@ static VALUE get_value(const char* buffer, int* position, int type) {
712
720
  memcpy(&millis, buffer + *position, 8);
713
721
 
714
722
  value = rb_time_new(millis / 1000, (millis % 1000) * 1000);
715
- value = rb_funcall(value, rb_intern("utc"), 0);
723
+ value = rb_funcall(value, utc_method, 0);
716
724
  *position += 8;
717
725
  break;
718
726
  }
@@ -758,7 +766,7 @@ static VALUE get_value(const char* buffer, int* position, int type) {
758
766
  *position += collection_length + 1;
759
767
 
760
768
  str = rb_str_new(buffer + *position, 12);
761
- oid = rb_funcall(str, rb_intern("unpack"), 1, rb_str_new2("C*"));
769
+ oid = rb_funcall(str, unpack_method, 1, rb_str_new2("C*"));
762
770
  id = rb_class_new_instance(1, &oid, ObjectId);
763
771
  *position += 12;
764
772
 
@@ -844,7 +852,7 @@ static VALUE elements_to_hash(const char* buffer, int max) {
844
852
  VALUE value;
845
853
  position += name_length + 1;
846
854
  value = get_value(buffer, &position, type);
847
- rb_funcall(hash, rb_intern("[]="), 2, name, value);
855
+ rb_funcall(hash, element_assignment_method, 2, name, value);
848
856
  }
849
857
  return hash;
850
858
  }
@@ -860,28 +868,9 @@ static VALUE method_deserialize(VALUE self, VALUE bson) {
860
868
  return elements_to_hash(buffer, remaining);
861
869
  }
862
870
 
863
-
864
- static VALUE fast_pack(VALUE self)
865
- {
866
- VALUE res;
867
- long i;
868
- char c;
869
-
870
- res = rb_str_buf_new(0);
871
-
872
- for (i = 0; i < RARRAY_LEN(self); i++) {
873
- c = FIX2LONG(RARRAY_PTR(self)[i]);
874
- rb_str_buf_cat(res, &c, sizeof(char));
875
- }
876
-
877
- return res;
878
- }
879
-
880
-
881
871
  static VALUE objectid_generate(VALUE self)
882
872
  {
883
- VALUE oid, digest;
884
- char hostname[MAX_HOSTNAME_LENGTH];
873
+ VALUE oid;
885
874
  unsigned char oid_bytes[12];
886
875
  unsigned long t, inc;
887
876
  unsigned short pid;
@@ -890,16 +879,22 @@ static VALUE objectid_generate(VALUE self)
890
879
  t = htonl(time(NULL));
891
880
  MEMCPY(&oid_bytes, &t, unsigned char, 4);
892
881
 
893
- if (gethostname(hostname, MAX_HOSTNAME_LENGTH) != 0) {
894
- rb_raise(rb_eRuntimeError, "failed to get hostname");
895
- }
896
- digest = rb_funcall(DigestMD5, rb_intern("digest"), 1, rb_str_new2(hostname));
897
- MEMCPY(&oid_bytes[4], RSTRING_PTR(digest), unsigned char, 3);
882
+ MEMCPY(&oid_bytes[4], hostname_digest, unsigned char, 3);
898
883
 
899
884
  pid = htons(getpid());
900
885
  MEMCPY(&oid_bytes[7], &pid, unsigned char, 2);
901
886
 
902
- inc = htonl(FIX2ULONG(rb_funcall(self, rb_intern("get_inc"), 0)));
887
+ /* No need to synchronize modification of this counter between threads;
888
+ * MRI global interpreter lock guarantees serializaility.
889
+ *
890
+ * Compiler should optimize out impossible branch.
891
+ */
892
+ if (sizeof(unsigned int) == 4) {
893
+ object_id_inc++;
894
+ } else {
895
+ object_id_inc = (object_id_inc + 1) % 0xFFFFFF;
896
+ }
897
+ inc = htonl(object_id_inc);
903
898
  MEMCPY(&oid_bytes[9], ((unsigned char*)&inc + 1), unsigned char, 3);
904
899
 
905
900
  oid = rb_ary_new2(12);
@@ -911,7 +906,14 @@ static VALUE objectid_generate(VALUE self)
911
906
 
912
907
 
913
908
  void Init_cbson() {
914
- VALUE bson, CBson, Digest, ext_version;
909
+ VALUE bson, CBson, Digest, ext_version, digest;
910
+ static char hostname[MAX_HOSTNAME_LENGTH];
911
+
912
+ element_assignment_method = rb_intern("[]=");
913
+ unpack_method = rb_intern("unpack");
914
+ utc_method = rb_intern("utc");
915
+ lt_operator = rb_intern("<");
916
+ gt_operator = rb_intern(">");
915
917
 
916
918
  bson = rb_const_get(rb_cObject, rb_intern("BSON"));
917
919
  rb_require("bson/types/binary");
@@ -949,5 +951,11 @@ void Init_cbson() {
949
951
  rb_define_method(ObjectID, "generate", objectid_generate, 0);
950
952
  rb_define_method(ObjectId, "generate", objectid_generate, 0);
951
953
 
952
- rb_define_method(rb_cArray, "fast_pack", fast_pack, 0);
954
+ if (gethostname(hostname, MAX_HOSTNAME_LENGTH) != 0) {
955
+ rb_raise(rb_eRuntimeError, "failed to get hostname");
956
+ }
957
+ digest = rb_funcall(DigestMD5, rb_intern("digest"), 1,
958
+ rb_str_new2(hostname));
959
+ memcpy(hostname_digest, RSTRING_PTR(digest), 16);
960
+ hostname_digest[16] = '\0';
953
961
  }
data/ext/cbson/version.h CHANGED
@@ -14,4 +14,4 @@
14
14
  * limitations under the License.
15
15
  */
16
16
 
17
- #define VERSION "1.0.7"
17
+ #define VERSION "1.0.9"
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bson_ext
3
3
  version: !ruby/object:Gem::Version
4
- hash: 25
4
+ hash: 5
5
5
  prerelease: false
6
6
  segments:
7
7
  - 1
8
8
  - 0
9
- - 7
10
- version: 1.0.7
9
+ - 9
10
+ version: 1.0.9
11
11
  platform: ruby
12
12
  authors:
13
13
  - Mike Dirolf
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2010-08-28 00:00:00 -04:00
18
+ date: 2010-09-20 00:00:00 -04:00
19
19
  default_executable:
20
20
  dependencies: []
21
21