repertoire-faceting 0.5.5 → 0.6.0

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 (64) hide show
  1. checksums.yaml +4 -4
  2. data/FAQ +23 -17
  3. data/INSTALL +52 -84
  4. data/LICENSE +1 -1
  5. data/README +213 -34
  6. data/TODO +20 -7
  7. data/ext/Makefile +24 -14
  8. data/ext/README.faceting +51 -0
  9. data/ext/bytea/bytea.sql +173 -0
  10. data/ext/bytea/faceting_bytea.control +6 -0
  11. data/ext/common/util.sql +35 -0
  12. data/ext/faceting--0.6.0.sql +251 -0
  13. data/ext/faceting_bytea--0.6.0.sql +207 -0
  14. data/ext/faceting_varbit--0.6.0.sql +198 -0
  15. data/ext/signature/faceting.control +6 -0
  16. data/ext/signature/signature.c +740 -0
  17. data/ext/{signature.o → signature/signature.o} +0 -0
  18. data/ext/{signature.so → signature/signature.so} +0 -0
  19. data/ext/signature/signature.sql +217 -0
  20. data/ext/varbit/faceting_varbit.control +7 -0
  21. data/ext/varbit/varbit.sql +164 -0
  22. data/{public → lib/assets}/images/repertoire-faceting/proportional_symbol.png +0 -0
  23. data/{public → lib/assets}/images/repertoire-faceting/spinner_sm.gif +0 -0
  24. data/{public → lib/assets}/javascripts/rep.faceting/context.js +2 -2
  25. data/{public → lib/assets}/javascripts/rep.faceting/ext/earth_facet.js +2 -4
  26. data/{public → lib/assets}/javascripts/rep.faceting/facet.js +1 -1
  27. data/{public → lib/assets}/javascripts/rep.faceting/facet_widget.js +3 -8
  28. data/{public → lib/assets}/javascripts/rep.faceting/nested_facet.js +1 -1
  29. data/{public → lib/assets}/javascripts/rep.faceting/results.js +1 -1
  30. data/{public → lib/assets}/javascripts/rep.faceting.js +5 -1
  31. data/{public → lib/assets}/javascripts/rep.protovis-facets.js +3 -3
  32. data/lib/assets/javascripts/rep.widgets/events.js +51 -0
  33. data/lib/assets/javascripts/rep.widgets/global.js +50 -0
  34. data/lib/assets/javascripts/rep.widgets/model.js +159 -0
  35. data/lib/assets/javascripts/rep.widgets/widget.js +213 -0
  36. data/lib/assets/javascripts/rep.widgets.js +14 -0
  37. data/{public → lib/assets}/stylesheets/rep.faceting.css +1 -1
  38. data/lib/repertoire-faceting/adapters/postgresql_adapter.rb +107 -48
  39. data/lib/repertoire-faceting/facets/abstract_facet.rb +43 -27
  40. data/lib/repertoire-faceting/facets/basic_facet.rb +23 -22
  41. data/lib/repertoire-faceting/facets/nested_facet.rb +50 -27
  42. data/lib/repertoire-faceting/model.rb +101 -65
  43. data/lib/repertoire-faceting/rails/engine.rb +8 -0
  44. data/lib/repertoire-faceting/rails/postgresql_adapter.rb +0 -1
  45. data/lib/repertoire-faceting/rails/relation.rb +0 -1
  46. data/lib/repertoire-faceting/railtie.rb +0 -1
  47. data/lib/repertoire-faceting/relation/calculations.rb +7 -2
  48. data/lib/repertoire-faceting/relation/query_methods.rb +17 -4
  49. data/lib/repertoire-faceting/routing.rb +2 -5
  50. data/lib/repertoire-faceting/tasks/all.rake +5 -4
  51. data/lib/repertoire-faceting/tasks/client.rake +2 -5
  52. data/lib/repertoire-faceting/version.rb +1 -1
  53. data/lib/repertoire-faceting.rb +2 -4
  54. data/{public → vendor/assets}/javascripts/google-earth-extensions.js +0 -0
  55. data/{public → vendor/assets}/javascripts/protovis.js +0 -0
  56. metadata +78 -78
  57. data/ext/README.signature +0 -33
  58. data/ext/signature.c +0 -740
  59. data/ext/signature.sql +0 -342
  60. data/ext/signature.sql.IN +0 -342
  61. data/ext/uninstall_signature.sql +0 -4
  62. data/ext/uninstall_signature.sql.IN +0 -4
  63. data/lib/repertoire-faceting/adapters/abstract_adapter.rb +0 -18
  64. data/lib/repertoire-faceting/relation/spawn_methods.rb +0 -26
@@ -0,0 +1,740 @@
1
+ #include "postgres.h"
2
+ #include "fmgr.h"
3
+ #include "funcapi.h"
4
+
5
+ PG_MODULE_MAGIC;
6
+
7
+ typedef struct
8
+ {
9
+ int32 vl_len_;
10
+ uint32 len;
11
+ uint8 data[1];
12
+ } Signature;
13
+
14
+ #define MIN(X,Y) ((X) < (Y) ? (X) : (Y))
15
+ #define MAX(X,Y) ((X) > (Y) ? (X) : (Y))
16
+
17
+ #define IN_AGGR (fcinfo->context && IsA(fcinfo->context, AggState))
18
+ #define AGGR_GROW_SIZE 8192
19
+
20
+ /*
21
+ * fmgr interface macros
22
+ */
23
+ #define DatumGetSignatureP(X) ((Signature *) PG_DETOAST_DATUM(X))
24
+ #define DatumGetSignaturePCopy(X) ((Signature *) PG_DETOAST_DATUM_COPY(X))
25
+ #define SignaturePGetDatum(X) PointerGetDatum(X)
26
+ #define PG_GETARG_SIGNATURE_P(n) DatumGetSignatureP(PG_GETARG_DATUM(n))
27
+ #define PG_GETARG_SIGNATURE_P_COPY(n) DatumGetSignaturePCopy(PG_GETARG_DATUM(n))
28
+ #define PG_RETURN_SIGNATURE_P(x) return SignaturePGetDatum(x)
29
+
30
+ /* Header overhead *in addition to* VARHDRSZ */
31
+ #define SIGNATUREHDRSZ sizeof(uint32)
32
+
33
+
34
+ Datum sig_in( PG_FUNCTION_ARGS );
35
+ Datum sig_out( PG_FUNCTION_ARGS );
36
+ Datum sig_resize( PG_FUNCTION_ARGS );
37
+ Datum sig_set( PG_FUNCTION_ARGS );
38
+ Datum sig_get( PG_FUNCTION_ARGS );
39
+ Datum sig_length( PG_FUNCTION_ARGS );
40
+ Datum sig_min( PG_FUNCTION_ARGS );
41
+ Datum sig_and( PG_FUNCTION_ARGS );
42
+ Datum sig_or( PG_FUNCTION_ARGS );
43
+ Datum sig_xor( PG_FUNCTION_ARGS );
44
+ Datum sig_on( PG_FUNCTION_ARGS );
45
+
46
+ Datum contains( PG_FUNCTION_ARGS );
47
+ Datum members( PG_FUNCTION_ARGS );
48
+ Datum count( PG_FUNCTION_ARGS );
49
+
50
+ Datum sig_cmp( PG_FUNCTION_ARGS );
51
+ Datum sig_lt( PG_FUNCTION_ARGS );
52
+ Datum sig_lte( PG_FUNCTION_ARGS );
53
+ Datum sig_eq( PG_FUNCTION_ARGS );
54
+ Datum sig_gt( PG_FUNCTION_ARGS );
55
+ Datum sig_gte( PG_FUNCTION_ARGS );
56
+
57
+ Datum sig_hash( PG_FUNCTION_ARGS );
58
+
59
+ int COUNT_TABLE[] = {
60
+ 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4,
61
+ 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
62
+ 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
63
+ 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
64
+ 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
65
+ 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
66
+ 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
67
+ 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
68
+ 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
69
+ 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
70
+ 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
71
+ 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
72
+ 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
73
+ 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
74
+ 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
75
+ 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8,
76
+ };
77
+
78
+
79
+ PG_FUNCTION_INFO_V1( sig_in );
80
+
81
+ Datum
82
+ sig_in( PG_FUNCTION_ARGS )
83
+ {
84
+ char *arg = PG_GETARG_CSTRING(0);
85
+ int32 len,
86
+ bytes;
87
+ Signature *result;
88
+
89
+ char *sptr;
90
+ uint8 *bptr;
91
+ uint8 x;
92
+
93
+ len = strlen(arg);
94
+ bytes = (len + 7) / 8 + VARHDRSZ + SIGNATUREHDRSZ;
95
+
96
+ result = (Signature *) palloc0(bytes);
97
+ SET_VARSIZE(result, bytes);
98
+ result->len = len;
99
+
100
+ bptr = result->data;
101
+ x = 0x80;
102
+ for (sptr = arg; *sptr; sptr++) {
103
+ if (*sptr == '1') {
104
+ *bptr |= x;
105
+ }
106
+ x >>= 1;
107
+ if (x == 0) {
108
+ x = 0x80;
109
+ bptr++;
110
+ }
111
+ }
112
+
113
+ PG_RETURN_SIGNATURE_P(result);
114
+ }
115
+
116
+
117
+ PG_FUNCTION_INFO_V1( sig_out );
118
+
119
+ Datum
120
+ sig_out( PG_FUNCTION_ARGS )
121
+ {
122
+ Signature *s = PG_GETARG_SIGNATURE_P(0);
123
+ char *result;
124
+ uint8 *bptr,
125
+ x;
126
+ char *sptr;
127
+ int32 len,
128
+ i, j, k;
129
+
130
+ len = s->len;
131
+ result = (char *) palloc(len + 1);
132
+ bptr = s->data;
133
+ sptr = result;
134
+
135
+ for (i = 0; i <= len - 8; i += 8, bptr++) {
136
+ x = *bptr;
137
+ for (j = 0; j < 8; j++) {
138
+ *sptr++ = (x & 0x80) ? '1' : '0';
139
+ x <<= 1;
140
+ }
141
+ }
142
+ if (i < len) {
143
+ x = *bptr;
144
+ for (k = i; k < len; k++) {
145
+ *sptr++ = (x & 0x80) ? '1' : '0';
146
+ x <<= 1;
147
+ }
148
+ }
149
+ *sptr = '\0';
150
+
151
+ PG_RETURN_CSTRING(result);
152
+ }
153
+
154
+
155
+ PG_FUNCTION_INFO_V1( sig_resize );
156
+
157
+ Datum
158
+ sig_resize( PG_FUNCTION_ARGS )
159
+ {
160
+ Signature *sig,
161
+ *res;
162
+ int32 sigbytes,
163
+ resbytes,
164
+ reslen;
165
+
166
+ sig = PG_GETARG_SIGNATURE_P(0);
167
+ sigbytes = VARSIZE(sig) - VARHDRSZ - SIGNATUREHDRSZ;
168
+
169
+ reslen = PG_GETARG_INT32(1);
170
+ resbytes = (reslen + 7) / 8;
171
+
172
+ res = (Signature *) palloc0( resbytes + VARHDRSZ + SIGNATUREHDRSZ );
173
+ SET_VARSIZE(res, resbytes + VARHDRSZ + SIGNATUREHDRSZ);
174
+ res->len = reslen;
175
+
176
+ memcpy(res->data, sig->data, MIN(sigbytes, resbytes));
177
+
178
+ PG_FREE_IF_COPY(sig, 0);
179
+
180
+ PG_RETURN_SIGNATURE_P( res );
181
+ }
182
+
183
+
184
+ PG_FUNCTION_INFO_V1( sig_set );
185
+
186
+ Datum
187
+ sig_set( PG_FUNCTION_ARGS )
188
+ {
189
+ Signature *sig,
190
+ *res;
191
+ int32 sigbytes,
192
+ resbytes,
193
+ index,
194
+ bit,
195
+ byte_offset,
196
+ bit_offset;
197
+ uint8 c;
198
+
199
+ sig = PG_GETARG_SIGNATURE_P(0);
200
+ sigbytes = VARSIZE(sig) - VARHDRSZ - SIGNATUREHDRSZ;
201
+
202
+ index = PG_GETARG_INT32(1);
203
+ if (PG_NARGS() == 3) {
204
+ bit = PG_GETARG_INT32(2);
205
+ } else {
206
+ bit = 1;
207
+ }
208
+
209
+ byte_offset = index / 8;
210
+ bit_offset = index % 8;
211
+
212
+ if (byte_offset >= sigbytes) {
213
+ resbytes = byte_offset + (IN_AGGR ? AGGR_GROW_SIZE : 1);
214
+ } else {
215
+ resbytes = sigbytes;
216
+ }
217
+
218
+ res = (Signature *) palloc0( resbytes + VARHDRSZ + SIGNATUREHDRSZ );
219
+ SET_VARSIZE(res, resbytes + VARHDRSZ + SIGNATUREHDRSZ );
220
+ memcpy(res->data, sig->data, MIN(sigbytes, resbytes));
221
+
222
+ res->len = MAX(sig->len, index+1);
223
+
224
+ c = res->data[byte_offset];
225
+ if (bit) {
226
+ c |= (0x80 >> bit_offset);
227
+ } else {
228
+ c &= ~(0x80 >> bit_offset);
229
+ }
230
+ res->data[byte_offset] = c;
231
+
232
+ PG_FREE_IF_COPY(sig, 0);
233
+
234
+ PG_RETURN_SIGNATURE_P( res );
235
+ }
236
+
237
+
238
+ PG_FUNCTION_INFO_V1( sig_get );
239
+
240
+ Datum
241
+ sig_get( PG_FUNCTION_ARGS )
242
+ {
243
+ Signature *sig;
244
+ int32 index,
245
+ byte_offset,
246
+ bit_offset,
247
+ c,
248
+ bit;
249
+
250
+ sig = PG_GETARG_SIGNATURE_P(0);
251
+ index = PG_GETARG_INT32(1);
252
+
253
+ if (index > sig->len) {
254
+ bit = 0;
255
+ } else {
256
+ byte_offset = index / 8;
257
+ bit_offset = index % 8;
258
+
259
+ c = sig->data[byte_offset];
260
+ if (c & (0x80 >> bit_offset)) {
261
+ bit = 1;
262
+ } else {
263
+ bit = 0;
264
+ }
265
+ }
266
+
267
+ PG_FREE_IF_COPY(sig, 0);
268
+
269
+ PG_RETURN_INT32( bit );
270
+ }
271
+
272
+
273
+ PG_FUNCTION_INFO_V1( contains );
274
+
275
+ Datum
276
+ contains( PG_FUNCTION_ARGS )
277
+ {
278
+ Signature *sig;
279
+ int32 sigbytes,
280
+ index,
281
+ byte_offset,
282
+ bit_offset,
283
+ c,
284
+ bit;
285
+
286
+ sig = PG_GETARG_SIGNATURE_P(0);
287
+ sigbytes = VARSIZE(sig) - VARHDRSZ - SIGNATUREHDRSZ;
288
+
289
+ index = PG_GETARG_INT32(1);
290
+
291
+ if (index > sig->len) {
292
+ bit = 0;
293
+ } else {
294
+ byte_offset = index / 8;
295
+ bit_offset = index % 8;
296
+
297
+ c = sig->data[byte_offset];
298
+ if (c & (0x80 >> bit_offset)) {
299
+ bit = 1;
300
+ } else {
301
+ bit = 0;
302
+ }
303
+ }
304
+
305
+ PG_FREE_IF_COPY(sig, 0);
306
+
307
+ PG_RETURN_BOOL( bit == 1 );
308
+ }
309
+
310
+
311
+ PG_FUNCTION_INFO_V1( members );
312
+
313
+ typedef struct
314
+ {
315
+ Signature *sig;
316
+ int32 index;
317
+ } members_fctx;
318
+
319
+ Datum
320
+ members( PG_FUNCTION_ARGS )
321
+ {
322
+ FuncCallContext *funcctx;
323
+ members_fctx *fctx;
324
+ MemoryContext oldcontext;
325
+
326
+ int32 result;
327
+
328
+ // based on set-returning examples in postgresql source's contrib/tablefunc directory
329
+
330
+ // executed on first entry to function
331
+ if ( SRF_IS_FIRSTCALL() ) {
332
+ Signature *sig;
333
+
334
+ funcctx = SRF_FIRSTCALL_INIT();
335
+ oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
336
+ funcctx->max_calls = PG_GETARG_UINT32(0);
337
+
338
+ // save signature, position state across calls
339
+ sig = PG_GETARG_SIGNATURE_P(0);
340
+ fctx = (members_fctx *) palloc(sizeof(members_fctx));
341
+ fctx->sig = sig;
342
+ fctx->index = 0;
343
+
344
+ funcctx->user_fctx = fctx;
345
+ MemoryContextSwitchTo(oldcontext);
346
+ }
347
+
348
+ // executed every entry to function
349
+ funcctx = SRF_PERCALL_SETUP();
350
+ fctx = funcctx->user_fctx;
351
+
352
+ // return position of next non-zero bit
353
+ result = -1;
354
+ while( result < 0 && (fctx->index < fctx->sig->len) ) {
355
+ int32 byte_offset,
356
+ bit_offset,
357
+ c;
358
+
359
+ byte_offset = fctx->index / 8;
360
+ bit_offset = fctx->index % 8;
361
+
362
+ c = fctx->sig->data[byte_offset];
363
+ if (c & (0x80 >> bit_offset)) {
364
+ result = fctx->index;
365
+ }
366
+
367
+ fctx->index++;
368
+ }
369
+
370
+ // return result
371
+ if( result >= 0 )
372
+ SRF_RETURN_NEXT(funcctx, Int32GetDatum(result));
373
+ else
374
+ SRF_RETURN_DONE(funcctx); // pgsql documentation claims no palloc mgmt necessary
375
+ }
376
+
377
+
378
+ PG_FUNCTION_INFO_V1( sig_length );
379
+
380
+ Datum
381
+ sig_length( PG_FUNCTION_ARGS )
382
+ {
383
+ Signature *sig;
384
+ int32 length;
385
+
386
+ sig = PG_GETARG_SIGNATURE_P(0);
387
+ length = sig->len;
388
+
389
+ PG_FREE_IF_COPY( sig, 0 );
390
+
391
+ PG_RETURN_INT32( length );
392
+ }
393
+
394
+
395
+ PG_FUNCTION_INFO_V1( sig_min );
396
+
397
+ Datum
398
+ sig_min( PG_FUNCTION_ARGS )
399
+ {
400
+ Signature *sig;
401
+ int32 sigbytes,
402
+ min,
403
+ i;
404
+ uint8 ch, x;
405
+
406
+ sig = PG_GETARG_SIGNATURE_P(0);
407
+ sigbytes = VARSIZE(sig) - VARHDRSZ - SIGNATUREHDRSZ;
408
+
409
+ min = - 1;
410
+ i = 0;
411
+ while (i < sigbytes && min < 0) {
412
+ ch = sig->data[i];
413
+ if (ch > 0) {
414
+ min = i * 8;
415
+ x = 0x80;
416
+ while ((ch & x) == 0) {
417
+ x >>= 1;
418
+ min++;
419
+ }
420
+ }
421
+ i++;
422
+ }
423
+
424
+ PG_FREE_IF_COPY( sig, 0 );
425
+
426
+ if (min < 0) {
427
+ PG_RETURN_NULL();
428
+ } else {
429
+ PG_RETURN_INT32( min );
430
+ }
431
+ }
432
+
433
+
434
+ PG_FUNCTION_INFO_V1( sig_and );
435
+
436
+ Datum
437
+ sig_and( PG_FUNCTION_ARGS )
438
+ {
439
+ Signature *sig1,
440
+ *sig2,
441
+ *res;
442
+ int32 sig1bytes,
443
+ sig2bytes,
444
+ resbytes,
445
+ i;
446
+ uint8 byte1,
447
+ byte2;
448
+
449
+ sig1 = PG_GETARG_SIGNATURE_P(0);
450
+ sig1bytes = VARSIZE(sig1) - VARHDRSZ - SIGNATUREHDRSZ;
451
+
452
+ sig2 = PG_GETARG_SIGNATURE_P(1);
453
+ sig2bytes = VARSIZE(sig2) - VARHDRSZ - SIGNATUREHDRSZ;
454
+
455
+ resbytes = MAX(sig1bytes, sig2bytes);
456
+
457
+ res = (Signature *) palloc0( resbytes + VARHDRSZ + SIGNATUREHDRSZ );
458
+ SET_VARSIZE(res, resbytes + VARHDRSZ + SIGNATUREHDRSZ );
459
+
460
+ res->len = MAX(sig1->len, sig2->len);
461
+
462
+ for(i=0; i<resbytes; i++) {
463
+ byte1 = byte2 = 0;
464
+ if (i < sig1bytes)
465
+ byte1 = sig1->data[i];
466
+ if (i < sig2bytes)
467
+ byte2 = sig2->data[i];
468
+
469
+ res->data[i] = byte1 & byte2;
470
+ }
471
+
472
+ PG_FREE_IF_COPY(sig1, 0);
473
+ PG_FREE_IF_COPY(sig2, 1);
474
+
475
+ PG_RETURN_SIGNATURE_P( res );
476
+ }
477
+
478
+
479
+ PG_FUNCTION_INFO_V1( sig_or );
480
+
481
+ Datum
482
+ sig_or( PG_FUNCTION_ARGS )
483
+ {
484
+ Signature *sig1,
485
+ *sig2,
486
+ *res;
487
+ int32 sig1bytes,
488
+ sig2bytes,
489
+ resbytes,
490
+ i;
491
+ uint8 byte1,
492
+ byte2;
493
+
494
+ sig1 = PG_GETARG_SIGNATURE_P(0);
495
+ sig1bytes = VARSIZE(sig1) - VARHDRSZ - SIGNATUREHDRSZ;
496
+
497
+ sig2 = PG_GETARG_SIGNATURE_P(1);
498
+ sig2bytes = VARSIZE(sig2) - VARHDRSZ - SIGNATUREHDRSZ;
499
+
500
+ resbytes = MAX(sig1bytes, sig2bytes);
501
+
502
+ res = (Signature *) palloc0( resbytes + VARHDRSZ + SIGNATUREHDRSZ );
503
+ SET_VARSIZE(res, resbytes + VARHDRSZ + SIGNATUREHDRSZ );
504
+
505
+ res->len = MAX(sig1->len, sig2->len);
506
+
507
+ for(i=0; i<resbytes; i++) {
508
+ byte1 = byte2 = 0;
509
+ if (i < sig1bytes)
510
+ byte1 = sig1->data[i];
511
+ if (i < sig2bytes)
512
+ byte2 = sig2->data[i];
513
+
514
+ res->data[i] = byte1 | byte2;
515
+ }
516
+
517
+ PG_FREE_IF_COPY(sig1, 0);
518
+ PG_FREE_IF_COPY(sig2, 1);
519
+
520
+ PG_RETURN_SIGNATURE_P( res );
521
+ }
522
+
523
+
524
+ PG_FUNCTION_INFO_V1( sig_xor );
525
+
526
+ Datum
527
+ sig_xor( PG_FUNCTION_ARGS )
528
+ {
529
+ Signature *sig,
530
+ *res;
531
+ int32 bytes,
532
+ bits,
533
+ i;
534
+ uint8 x;
535
+
536
+ sig = PG_GETARG_SIGNATURE_P(0);
537
+ bytes = sig->len / 8;
538
+ bits = sig->len % 8;
539
+
540
+ res = (Signature *) palloc0( bytes + 1 + VARHDRSZ + SIGNATUREHDRSZ );
541
+ SET_VARSIZE(res, bytes + 1 + VARHDRSZ + SIGNATUREHDRSZ );
542
+ res->len = sig->len;
543
+
544
+ for(i=0; i<=bytes; i++) {
545
+ res->data[i] = ~(sig->data[i]);
546
+ }
547
+
548
+ if (bits > 0) {
549
+ x = 0xFF >> bits;
550
+ res->data[bytes] &= ~x;
551
+ }
552
+
553
+ PG_FREE_IF_COPY(sig, 0);
554
+
555
+ PG_RETURN_SIGNATURE_P( res );
556
+ }
557
+
558
+
559
+ PG_FUNCTION_INFO_V1( count );
560
+
561
+ Datum
562
+ count( PG_FUNCTION_ARGS )
563
+ {
564
+ Signature *sig;
565
+ int32 sigbytes,
566
+ count,
567
+ i;
568
+ uint8 ch;
569
+
570
+ sig = PG_GETARG_SIGNATURE_P(0);
571
+ sigbytes = VARSIZE(sig) - VARHDRSZ - SIGNATUREHDRSZ;
572
+
573
+ count = 0;
574
+ for(i=0; i < sigbytes; i++) {
575
+ ch = sig->data[i];
576
+ count += COUNT_TABLE[ch];
577
+ }
578
+
579
+ PG_FREE_IF_COPY( sig, 0 );
580
+
581
+ PG_RETURN_INT32( count );
582
+ }
583
+
584
+
585
+ static int32
586
+ signature_cmp_internal(Signature *sig1, Signature *sig2)
587
+ {
588
+ int32 sig1bytes,
589
+ sig2bytes,
590
+ sig1bits,
591
+ sig2bits,
592
+ result,
593
+ i,
594
+ maxbytes;
595
+ uint8 ch1, ch2,
596
+ x;
597
+
598
+ sig1bytes = sig1->len / 8;
599
+ sig1bits = sig1->len % 8;
600
+
601
+ sig2bytes = sig2->len / 8;
602
+ sig2bits = sig2->len % 8;
603
+
604
+ maxbytes = MAX(sig1bytes, sig2bytes);
605
+
606
+ result = i = 0;
607
+ while(result == 0 && i <= maxbytes) {
608
+ ch1 = ch2 = 0;
609
+ if(i <= sig1bytes) {
610
+ ch1 = sig1->data[i];
611
+ if(i == sig1bytes && sig1bits > 0) {
612
+ x = 0xFF >> sig1bits;
613
+ ch1 &= ~x;
614
+ }
615
+ }
616
+ if(i <= sig2bytes) {
617
+ ch2 = sig2->data[i];
618
+ if(i == sig2bytes && sig2bits > 0) {
619
+ x = 0xFF >> sig2bits;
620
+ ch2 &= ~x;
621
+ }
622
+ }
623
+ if (ch1 > ch2) {
624
+ result = 1;
625
+ } else if (ch1 < ch2) {
626
+ result = -1;
627
+ }
628
+ i++;
629
+ }
630
+
631
+ return result;
632
+ }
633
+
634
+
635
+ PG_FUNCTION_INFO_V1(sig_cmp);
636
+
637
+ Datum
638
+ sig_cmp(PG_FUNCTION_ARGS)
639
+ {
640
+ Signature *sig1 = (Signature *) PG_GETARG_POINTER(0);
641
+ Signature *sig2 = (Signature *) PG_GETARG_POINTER(1);
642
+ int32 result;
643
+
644
+ result = signature_cmp_internal(sig1, sig2);
645
+
646
+ PG_FREE_IF_COPY(sig1, 0);
647
+ PG_FREE_IF_COPY(sig2, 1);
648
+
649
+ PG_RETURN_INT32(result);
650
+ }
651
+
652
+
653
+ PG_FUNCTION_INFO_V1(sig_lt);
654
+
655
+ Datum
656
+ sig_lt(PG_FUNCTION_ARGS)
657
+ {
658
+ Signature *sig1 = (Signature *) PG_GETARG_POINTER(0);
659
+ Signature *sig2 = (Signature *) PG_GETARG_POINTER(1);
660
+ bool result;
661
+
662
+ result = signature_cmp_internal(sig1, sig2) < 0;
663
+
664
+ PG_FREE_IF_COPY(sig1, 0);
665
+ PG_FREE_IF_COPY(sig2, 1);
666
+
667
+ PG_RETURN_BOOL(result);
668
+ }
669
+
670
+
671
+ PG_FUNCTION_INFO_V1(sig_lte);
672
+
673
+ Datum
674
+ sig_lte(PG_FUNCTION_ARGS)
675
+ {
676
+ Signature *sig1 = (Signature *) PG_GETARG_POINTER(0);
677
+ Signature *sig2 = (Signature *) PG_GETARG_POINTER(1);
678
+ bool result;
679
+
680
+ result = signature_cmp_internal(sig1, sig2) <= 0;
681
+
682
+ PG_FREE_IF_COPY(sig1, 0);
683
+ PG_FREE_IF_COPY(sig2, 1);
684
+
685
+ PG_RETURN_BOOL(result);
686
+ }
687
+
688
+
689
+ PG_FUNCTION_INFO_V1(sig_eq);
690
+
691
+ Datum
692
+ sig_eq(PG_FUNCTION_ARGS)
693
+ {
694
+ Signature *sig1 = (Signature *) PG_GETARG_POINTER(0);
695
+ Signature *sig2 = (Signature *) PG_GETARG_POINTER(1);
696
+ bool result;
697
+
698
+ result = signature_cmp_internal(sig1, sig2) == 0;
699
+
700
+ PG_FREE_IF_COPY(sig1, 0);
701
+ PG_FREE_IF_COPY(sig2, 1);
702
+
703
+ PG_RETURN_BOOL(result);
704
+ }
705
+
706
+
707
+ PG_FUNCTION_INFO_V1(sig_gte);
708
+
709
+ Datum
710
+ sig_gte(PG_FUNCTION_ARGS)
711
+ {
712
+ Signature *sig1 = (Signature *) PG_GETARG_POINTER(0);
713
+ Signature *sig2 = (Signature *) PG_GETARG_POINTER(1);
714
+ bool result;
715
+
716
+ result = signature_cmp_internal(sig1, sig2) >= 0;
717
+
718
+ PG_FREE_IF_COPY(sig1, 0);
719
+ PG_FREE_IF_COPY(sig2, 1);
720
+
721
+ PG_RETURN_BOOL(result);
722
+ }
723
+
724
+
725
+ PG_FUNCTION_INFO_V1(sig_gt);
726
+
727
+ Datum
728
+ sig_gt(PG_FUNCTION_ARGS)
729
+ {
730
+ Signature *sig1 = (Signature *) PG_GETARG_POINTER(0);
731
+ Signature *sig2 = (Signature *) PG_GETARG_POINTER(1);
732
+ bool result;
733
+
734
+ result = signature_cmp_internal(sig1, sig2) > 0;
735
+
736
+ PG_FREE_IF_COPY(sig1, 0);
737
+ PG_FREE_IF_COPY(sig2, 1);
738
+
739
+ PG_RETURN_BOOL(result);
740
+ }
File without changes
File without changes