sereal 0.0.8 → 0.0.9

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 06153f3bc1df8650c81eff2d5ef44f260920830c
4
- data.tar.gz: e6e3e806787c10d2511ff7ea63256f922a45b0f3
3
+ metadata.gz: 8247824a3c96a8a8a0ef7a190fed6d8517ba85dc
4
+ data.tar.gz: 6e8edec6c3143ecd94fb22d6c96bb33664fd706b
5
5
  SHA512:
6
- metadata.gz: 278c31a6754bd905858874e88d3cd87ed88986dbec21e3d7a5544d8b3fd7fab2d011ac3f7e22aff808a412e5b900e8f8d12427e8c1b3d05823cba271075b7379
7
- data.tar.gz: a10efcc28da1409da425e6e6c222712fdaa7d62bee525728d9ea9b1edfc2a34ea0b14cb358fd98540063b4af1623f5e3b5995d0f17c251f044e67243513bea21
6
+ metadata.gz: a09768f1a182fa25eaae541c8af2e8396910eaccd1e9e08d313d7b5b98fe6aa098cd95de0c4dd88061683135b91a9c273f32489f8ab941cac2b74f4e0e1763cf
7
+ data.tar.gz: 611c0cb5a659adf051a0478bd9c621d2cc325d404db686e989217f6a9a755e2495e3697ff6b4f0999e6b38f9b8a5642f83842b6d456609647422ef48a53b15bc
data/bin/rsrl CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env ruby
2
2
  begin
3
- require File.join(File.dirname(__FILE__),'..','lib','sereal')
3
+ require File.join(".",File.dirname(__FILE__),'..','lib','sereal')
4
4
  rescue LoadError
5
5
  require 'sereal'
6
6
  end
@@ -10,16 +10,22 @@ static inline void s_free_data_if_not_mine(sereal_t *s) {
10
10
  }
11
11
  }
12
12
 
13
+ static inline void s_init_tracker(sereal_t *s) {
14
+ if (s->tracked == Qnil) {
15
+ s->tracked = rb_hash_new();
16
+ rb_gc_mark(s->tracked);
17
+ }
18
+ }
19
+
13
20
  static inline void s_reset_tracker(sereal_t *s) {
14
- if (s->tracked != Qnil)
15
- rb_gc_unregister_address(&s->tracked);
16
- s->tracked = Qnil;
21
+ if (s->tracked != Qnil) {
22
+ rb_hash_clear(s->tracked);
23
+ }
17
24
  }
18
25
 
19
26
  static inline void s_destroy(sereal_t *s) {
20
27
  if (!s)
21
28
  return;
22
-
23
29
  s_reset_tracker(s);
24
30
  s_free_data_if_not_mine(s);
25
31
  free(s);
@@ -31,6 +37,7 @@ static inline void *s_realloc_or_raise(sereal_t *s, void *p, u32 n) {
31
37
  s_raise(s,rb_eNoMemError,"memory allocation failure for %d bytes",n);
32
38
  return buf;
33
39
  }
40
+
34
41
  static inline void *s_alloc_or_raise(sereal_t *s,u32 n) {
35
42
  return s_realloc_or_raise(s,NULL,n);
36
43
  }
@@ -205,10 +205,7 @@ VALUE sereal_to_rb_object(sereal_t *s) {
205
205
 
206
206
  VALUE decoded = (*READERS[t])(s,t);
207
207
  if (tracked) {
208
- if (s->tracked == Qnil) {
209
- s->tracked = rb_hash_new();
210
- rb_gc_register_address(&s->tracked);
211
- }
208
+ s_init_tracker(s);
212
209
  rb_hash_aset(s->tracked,INT2FIX(pos),decoded);
213
210
  }
214
211
  return decoded;
@@ -225,6 +222,7 @@ VALUE method_sereal_decode(VALUE self, VALUE args) {
225
222
  u8 have_block = rb_block_given_p();
226
223
  sereal_t *s = s_create();
227
224
  u64 offset = 0;
225
+
228
226
  if (TYPE(payload) == T_FILE) {
229
227
  if (!have_block)
230
228
  s_raise(s,rb_eTypeError,"block is required when reading from a stream")
@@ -216,10 +216,38 @@ static void s_append_nil(sereal_t *s, VALUE object) {
216
216
  s_append_u8(s,SRL_HDR_UNDEF);
217
217
  }
218
218
 
219
+ static void s_append_refp(sereal_t *s, VALUE object) {
220
+ u32 pos = FIX2LONG(object);
221
+ s_append_hdr_with_varint(s,SRL_HDR_REFP,pos - s->hdr_end + 1);
222
+ u8 *reference = s_get_p_at_pos(s,pos,0);
223
+ *reference |= SRL_HDR_TRACK_FLAG;
224
+ }
225
+
219
226
  /* writer function pointers */
220
227
  static void rb_object_to_sereal(sereal_t *s, VALUE object) {
221
228
  S_RECURSE_INC(s);
229
+ u32 pos = s->pos;
230
+
231
+ if (s->tracked != Qnil &&
232
+ TYPE(object) == T_ARRAY ||
233
+ TYPE(object) == T_HASH ||
234
+ TYPE(object) == T_SYMBOL ||
235
+ TYPE(object) == T_STRING) {
236
+
237
+ if (s->tracked != Qnil) {
238
+ VALUE id = rb_obj_id(object);
239
+ VALUE stored_position = rb_hash_aref(s->tracked,id);
240
+ if (stored_position != Qnil) {
241
+ s_append_refp(s,stored_position);
242
+ goto out;
243
+ } else {
244
+ rb_hash_aset(s->tracked,id,INT2FIX(pos));
245
+ }
246
+ }
247
+ }
248
+
222
249
  (*WRITER[TYPE(object)])(s,object);
250
+ out:
223
251
  S_RECURSE_DEC(s);
224
252
  }
225
253
 
@@ -249,6 +277,7 @@ VALUE method_sereal_encode(VALUE self, VALUE args) {
249
277
  VALUE compress = Qfalse;
250
278
  if (argc == 2)
251
279
  compress = rb_ary_shift(args);
280
+
252
281
  u8 do_compress;
253
282
  u8 version = SRL_PROTOCOL_VERSION;
254
283
 
@@ -257,7 +286,10 @@ VALUE method_sereal_encode(VALUE self, VALUE args) {
257
286
  } else {
258
287
  do_compress = (compress == Qtrue ? 1 : 0);
259
288
  }
260
-
289
+ if (do_compress & __REF) {
290
+ do_compress &= ~__REF;
291
+ s_init_tracker(s);
292
+ }
261
293
  switch(do_compress) {
262
294
  case __SNAPPY:
263
295
  version |= SRL_PROTOCOL_ENCODING_SNAPPY;
@@ -269,6 +301,7 @@ VALUE method_sereal_encode(VALUE self, VALUE args) {
269
301
  default:
270
302
  version |= SRL_PROTOCOL_ENCODING_RAW;
271
303
  }
304
+
272
305
  // setup header
273
306
  s_append_u32(s,SRL_MAGIC_STRING_LILIPUTIAN);
274
307
  s_append_u8(s,version);
@@ -276,6 +309,7 @@ VALUE method_sereal_encode(VALUE self, VALUE args) {
276
309
  u32 s_header_len = s->pos;
277
310
 
278
311
  // serialize
312
+ s->hdr_end = s->pos;
279
313
  rb_object_to_sereal(s,payload);
280
314
 
281
315
  // compress
@@ -311,7 +345,7 @@ VALUE method_sereal_encode(VALUE self, VALUE args) {
311
345
  compressed + s_header_len + un_compressed_len_varint,
312
346
  compressed_len_varint);
313
347
 
314
- u8 *start = s_get_p_at_pos(s,s_header_len,1);
348
+ u8 *start = s_get_p_at_pos(s,s_header_len,0);
315
349
  u8 *working_buf = s_alloc_or_raise(s,CSNAPPY_WORKMEM_BYTES);
316
350
  csnappy_compress(start,
317
351
  s_body_len,
@@ -15,6 +15,20 @@ void Init_sereal();
15
15
  * SNAPPY_INCR encoded objects can be appended into one output and then the
16
16
  * decoder will know what to do.
17
17
  *
18
+ * Sereal.encode(object,Sereal::REF)
19
+ * or Sereal::REF|Sereal::SNAPPY_INC, or Sereal::REF|Sereal::SNAPPY
20
+ *
21
+ * when encoding will try to use Sereal's REFP tag to transmit only the
22
+ * the original object's offset in the packet.
23
+ * So:
24
+ * one = [ 1,2,3,4,5 ]
25
+ * two = [ one, one ]
26
+ * Sereal.encode(two,Sereal::REF)
27
+ * will send 'one' only once, and one REFP that points to the first one
28
+ * it uses one.object_id as a hash key in a local tracker hash
29
+ * and if it sees this object_id again it just sends the offset.
30
+ *
31
+ *
18
32
  * Sereal.decode(blob) - returns the decoded object
19
33
  *
20
34
  * If the blob contains multiple compressed
@@ -41,7 +55,6 @@ void Init_sereal();
41
55
  * end
42
56
  *
43
57
  */
44
-
45
58
  void Init_sereal() {
46
59
  Sereal = rb_define_class("Sereal", rb_cObject);
47
60
  rb_define_singleton_method(Sereal, "encode", method_sereal_encode, -2);
@@ -49,6 +62,7 @@ void Init_sereal() {
49
62
  rb_define_const(Sereal, "SNAPPY",INT2NUM(__SNAPPY));
50
63
  rb_define_const(Sereal, "SNAPPY_INCR",INT2NUM(__SNAPPY_INCR));
51
64
  rb_define_const(Sereal, "RAW",INT2NUM(__RAW));
65
+ rb_define_const(Sereal, "REF",INT2NUM(__REF));
52
66
  s_init_writers();
53
67
  }
54
68
 
@@ -53,6 +53,7 @@ do { \
53
53
 
54
54
  #define FLAG_NOT_MINE 1
55
55
  #define FLAG_STREAM 2
56
+ #define FLAG_REF 4
56
57
  struct _sereal {
57
58
  u8 *data;
58
59
  u32 size;
@@ -92,5 +93,6 @@ VALUE method_sereal_decode(VALUE self, VALUE payload);
92
93
  #define __RAW 0
93
94
  #define __SNAPPY 1
94
95
  #define __SNAPPY_INCR 2
96
+ #define __REF 4
95
97
  #define __MIN_SIZE 6
96
98
  #endif
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sereal
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.8
4
+ version: 0.0.9
5
5
  platform: ruby
6
6
  authors:
7
7
  - Borislav Nikolov
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-01-02 00:00:00.000000000 Z
11
+ date: 2014-01-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake-compiler