bson_ext 1.0.7 → 1.0.9

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 (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