isomorfeus-ferret 0.17.1 → 0.17.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (130) hide show
  1. checksums.yaml +4 -4
  2. data/ext/isomorfeus_ferret_ext/benchmark.c +9 -20
  3. data/ext/isomorfeus_ferret_ext/benchmarks_all.h +1 -2
  4. data/ext/isomorfeus_ferret_ext/bm_hash.c +1 -2
  5. data/ext/isomorfeus_ferret_ext/bm_store.c +2 -0
  6. data/ext/isomorfeus_ferret_ext/brotli_dec_decode.c +4 -2
  7. data/ext/isomorfeus_ferret_ext/brotli_enc_encode.c +3 -2
  8. data/ext/isomorfeus_ferret_ext/frb_analysis.c +4 -5
  9. data/ext/isomorfeus_ferret_ext/frb_field_info.c +3 -4
  10. data/ext/isomorfeus_ferret_ext/frb_index.c +118 -160
  11. data/ext/isomorfeus_ferret_ext/frb_lazy_doc.c +14 -16
  12. data/ext/isomorfeus_ferret_ext/frb_search.c +31 -23
  13. data/ext/isomorfeus_ferret_ext/frb_store.c +27 -13
  14. data/ext/isomorfeus_ferret_ext/frb_utils.c +3 -6
  15. data/ext/isomorfeus_ferret_ext/frt_analysis.c +39 -46
  16. data/ext/isomorfeus_ferret_ext/frt_analysis.h +9 -9
  17. data/ext/isomorfeus_ferret_ext/frt_array.c +11 -22
  18. data/ext/isomorfeus_ferret_ext/frt_bitvector.h +3 -6
  19. data/ext/isomorfeus_ferret_ext/frt_doc_field.c +87 -0
  20. data/ext/isomorfeus_ferret_ext/frt_doc_field.h +26 -0
  21. data/ext/isomorfeus_ferret_ext/frt_document.c +4 -97
  22. data/ext/isomorfeus_ferret_ext/frt_document.h +2 -27
  23. data/ext/isomorfeus_ferret_ext/frt_except.c +50 -6
  24. data/ext/isomorfeus_ferret_ext/frt_except.h +3 -2
  25. data/ext/isomorfeus_ferret_ext/frt_field_index.c +13 -32
  26. data/ext/isomorfeus_ferret_ext/frt_field_index.h +0 -6
  27. data/ext/isomorfeus_ferret_ext/frt_field_info.c +69 -0
  28. data/ext/isomorfeus_ferret_ext/frt_field_info.h +49 -0
  29. data/ext/isomorfeus_ferret_ext/frt_field_infos.c +196 -0
  30. data/ext/isomorfeus_ferret_ext/frt_field_infos.h +35 -0
  31. data/ext/isomorfeus_ferret_ext/frt_global.c +10 -4
  32. data/ext/isomorfeus_ferret_ext/frt_global.h +11 -15
  33. data/ext/isomorfeus_ferret_ext/frt_hash.c +8 -8
  34. data/ext/isomorfeus_ferret_ext/frt_hash.h +1 -2
  35. data/ext/isomorfeus_ferret_ext/frt_hashset.c +20 -40
  36. data/ext/isomorfeus_ferret_ext/frt_hashset.h +1 -2
  37. data/ext/isomorfeus_ferret_ext/frt_helper.c +7 -15
  38. data/ext/isomorfeus_ferret_ext/frt_in_stream.c +482 -0
  39. data/ext/isomorfeus_ferret_ext/frt_in_stream.h +241 -0
  40. data/ext/isomorfeus_ferret_ext/frt_ind.c +20 -49
  41. data/ext/isomorfeus_ferret_ext/frt_ind.h +0 -1
  42. data/ext/isomorfeus_ferret_ext/frt_index.c +296 -1857
  43. data/ext/isomorfeus_ferret_ext/frt_index.h +2 -145
  44. data/ext/isomorfeus_ferret_ext/frt_lang.c +5 -10
  45. data/ext/isomorfeus_ferret_ext/frt_lazy_doc.c +29 -0
  46. data/ext/isomorfeus_ferret_ext/frt_lazy_doc.h +19 -0
  47. data/ext/isomorfeus_ferret_ext/frt_lazy_doc_field.c +93 -0
  48. data/ext/isomorfeus_ferret_ext/frt_lazy_doc_field.h +33 -0
  49. data/ext/isomorfeus_ferret_ext/frt_mdbx_store.c +102 -70
  50. data/ext/isomorfeus_ferret_ext/frt_mempool.c +8 -16
  51. data/ext/isomorfeus_ferret_ext/frt_multimapper.c +23 -46
  52. data/ext/isomorfeus_ferret_ext/frt_multimapper.h +4 -8
  53. data/ext/isomorfeus_ferret_ext/frt_out_stream.c +334 -0
  54. data/ext/isomorfeus_ferret_ext/frt_out_stream.h +198 -0
  55. data/ext/isomorfeus_ferret_ext/frt_posh.c +6 -819
  56. data/ext/isomorfeus_ferret_ext/frt_posh.h +0 -57
  57. data/ext/isomorfeus_ferret_ext/frt_priorityqueue.c +11 -22
  58. data/ext/isomorfeus_ferret_ext/frt_priorityqueue.h +1 -2
  59. data/ext/isomorfeus_ferret_ext/frt_q_boolean.c +85 -171
  60. data/ext/isomorfeus_ferret_ext/frt_q_match_all.c +8 -16
  61. data/ext/isomorfeus_ferret_ext/frt_q_multi_term.c +1 -2
  62. data/ext/isomorfeus_ferret_ext/frt_q_parser.c +49 -98
  63. data/ext/isomorfeus_ferret_ext/frt_q_phrase.c +52 -104
  64. data/ext/isomorfeus_ferret_ext/frt_q_range.c +6 -12
  65. data/ext/isomorfeus_ferret_ext/frt_q_span.c +113 -226
  66. data/ext/isomorfeus_ferret_ext/frt_q_wildcard.c +1 -2
  67. data/ext/isomorfeus_ferret_ext/frt_ram_store.c +134 -85
  68. data/ext/isomorfeus_ferret_ext/frt_ram_store.h +12 -0
  69. data/ext/isomorfeus_ferret_ext/frt_search.c +82 -164
  70. data/ext/isomorfeus_ferret_ext/frt_similarity.c +11 -22
  71. data/ext/isomorfeus_ferret_ext/frt_similarity.h +1 -2
  72. data/ext/isomorfeus_ferret_ext/frt_store.c +13 -536
  73. data/ext/isomorfeus_ferret_ext/frt_store.h +90 -495
  74. data/ext/isomorfeus_ferret_ext/frt_stream.h +18 -0
  75. data/ext/isomorfeus_ferret_ext/frt_term_vectors.c +8 -16
  76. data/ext/isomorfeus_ferret_ext/frt_win32.h +5 -10
  77. data/ext/isomorfeus_ferret_ext/isomorfeus_ferret.c +12 -11
  78. data/ext/isomorfeus_ferret_ext/isomorfeus_ferret.h +11 -13
  79. data/ext/isomorfeus_ferret_ext/lz4.c +422 -195
  80. data/ext/isomorfeus_ferret_ext/lz4.h +114 -46
  81. data/ext/isomorfeus_ferret_ext/lz4frame.c +421 -242
  82. data/ext/isomorfeus_ferret_ext/lz4frame.h +122 -53
  83. data/ext/isomorfeus_ferret_ext/lz4hc.c +127 -111
  84. data/ext/isomorfeus_ferret_ext/lz4hc.h +14 -14
  85. data/ext/isomorfeus_ferret_ext/lz4xxhash.h +1 -1
  86. data/ext/isomorfeus_ferret_ext/mdbx.c +3762 -2526
  87. data/ext/isomorfeus_ferret_ext/mdbx.h +115 -70
  88. data/ext/isomorfeus_ferret_ext/test.c +40 -87
  89. data/ext/isomorfeus_ferret_ext/test.h +3 -6
  90. data/ext/isomorfeus_ferret_ext/test_1710.c +11 -13
  91. data/ext/isomorfeus_ferret_ext/test_analysis.c +32 -64
  92. data/ext/isomorfeus_ferret_ext/test_array.c +6 -12
  93. data/ext/isomorfeus_ferret_ext/test_bitvector.c +12 -24
  94. data/ext/isomorfeus_ferret_ext/test_document.c +23 -33
  95. data/ext/isomorfeus_ferret_ext/test_except.c +10 -21
  96. data/ext/isomorfeus_ferret_ext/test_fields.c +62 -68
  97. data/ext/isomorfeus_ferret_ext/test_file_deleter.c +15 -24
  98. data/ext/isomorfeus_ferret_ext/test_filter.c +17 -27
  99. data/ext/isomorfeus_ferret_ext/test_global.c +14 -29
  100. data/ext/isomorfeus_ferret_ext/test_hash.c +19 -38
  101. data/ext/isomorfeus_ferret_ext/test_hashset.c +8 -16
  102. data/ext/isomorfeus_ferret_ext/test_helper.c +4 -8
  103. data/ext/isomorfeus_ferret_ext/test_highlighter.c +16 -28
  104. data/ext/isomorfeus_ferret_ext/test_index.c +277 -495
  105. data/ext/isomorfeus_ferret_ext/test_lang.c +7 -14
  106. data/ext/isomorfeus_ferret_ext/test_mdbx_store.c +2 -5
  107. data/ext/isomorfeus_ferret_ext/test_mempool.c +5 -10
  108. data/ext/isomorfeus_ferret_ext/test_multimapper.c +3 -6
  109. data/ext/isomorfeus_ferret_ext/test_priorityqueue.c +9 -18
  110. data/ext/isomorfeus_ferret_ext/test_q_const_score.c +4 -6
  111. data/ext/isomorfeus_ferret_ext/test_q_filtered.c +3 -4
  112. data/ext/isomorfeus_ferret_ext/test_q_fuzzy.c +9 -15
  113. data/ext/isomorfeus_ferret_ext/test_q_parser.c +8 -16
  114. data/ext/isomorfeus_ferret_ext/test_q_span.c +19 -35
  115. data/ext/isomorfeus_ferret_ext/test_ram_store.c +14 -13
  116. data/ext/isomorfeus_ferret_ext/test_search.c +60 -109
  117. data/ext/isomorfeus_ferret_ext/test_segments.c +8 -13
  118. data/ext/isomorfeus_ferret_ext/test_similarity.c +2 -4
  119. data/ext/isomorfeus_ferret_ext/test_sort.c +14 -24
  120. data/ext/isomorfeus_ferret_ext/test_store.c +96 -115
  121. data/ext/isomorfeus_ferret_ext/test_term.c +9 -15
  122. data/ext/isomorfeus_ferret_ext/test_term_vectors.c +9 -14
  123. data/ext/isomorfeus_ferret_ext/test_test.c +4 -8
  124. data/ext/isomorfeus_ferret_ext/test_threading.c +15 -30
  125. data/ext/isomorfeus_ferret_ext/testhelper.c +11 -21
  126. data/ext/isomorfeus_ferret_ext/testhelper.h +1 -1
  127. data/ext/isomorfeus_ferret_ext/tests_all.h +1 -2
  128. data/lib/isomorfeus/ferret/index/index.rb +1 -12
  129. data/lib/isomorfeus/ferret/version.rb +1 -1
  130. metadata +43 -4
@@ -6,13 +6,11 @@
6
6
  #define St(state) ((FrtState *)(state))
7
7
  #define UCtoI(val) ((int)(unsigned char)(val))
8
8
 
9
- static void state_destroy(FrtState *state)
10
- {
9
+ static void state_destroy(FrtState *state) {
11
10
  state->destroy_i(state);
12
11
  }
13
12
 
14
- typedef struct LetterState
15
- {
13
+ typedef struct LetterState {
16
14
  FrtState super;
17
15
  int c;
18
16
  int val;
@@ -21,30 +19,25 @@ typedef struct LetterState
21
19
 
22
20
  #define LSt(state) ((LetterState *)(state))
23
21
 
24
- static int lstate_next(LetterState *self, int c, int *states)
25
- {
22
+ static int lstate_next(LetterState *self, int c, int *states) {
26
23
  if (c == self->c) {
27
24
  states[0] = self->val;
28
25
  return 1;
29
- }
30
- else {
26
+ } else {
31
27
  return 0;
32
28
  }
33
29
  }
34
30
 
35
- static int lstate_is_match(LetterState *self, char **mapping)
36
- {
31
+ static int lstate_is_match(LetterState *self, char **mapping) {
37
32
  if (self->val < 0) {
38
33
  *mapping = self->mapping;
39
34
  return self->val;
40
- }
41
- else {
35
+ } else {
42
36
  return 0;
43
37
  }
44
38
  }
45
39
 
46
- static LetterState *lstate_new(int c, int val)
47
- {
40
+ static LetterState *lstate_new(int c, int val) {
48
41
  LetterState *self = FRT_ALLOC(LetterState);
49
42
  self->c = c;
50
43
  self->val = val;
@@ -55,28 +48,24 @@ static LetterState *lstate_new(int c, int val)
55
48
  return self;
56
49
  }
57
50
 
58
- typedef struct NonDeterministicState
59
- {
51
+ typedef struct NonDeterministicState {
60
52
  FrtState super;
61
53
  int *states[256];
62
54
  int size[256];
63
55
  int capa[256];
64
56
  } NonDeterministicState;
65
57
 
66
- static int ndstate_next(NonDeterministicState *self, int c, int *states)
67
- {
58
+ static int ndstate_next(NonDeterministicState *self, int c, int *states) {
68
59
  int size = self->size[c];
69
60
  memcpy(states, self->states[c], size * sizeof(int));
70
61
  return size;
71
62
  }
72
63
 
73
- static void ndstate_add(NonDeterministicState *self, int c, int state)
74
- {
64
+ static void ndstate_add(NonDeterministicState *self, int c, int state) {
75
65
  if (self->capa[c] <= self->size[c]) {
76
66
  if (self->capa[c] == 0) {
77
67
  self->capa[c] = 4;
78
- }
79
- else {
68
+ } else {
80
69
  self->capa[c] <<= 1;
81
70
  }
82
71
  FRT_REALLOC_N(self->states[c], int, self->capa[c]);
@@ -92,8 +81,7 @@ static void ndstate_destroy_i(NonDeterministicState *self) {
92
81
  free(self);
93
82
  }
94
83
 
95
- static int ndstate_is_match(FrtState *self, char **mapping)
96
- {
84
+ static int ndstate_is_match(FrtState *self, char **mapping) {
97
85
  (void)self; (void)mapping;
98
86
  return 0;
99
87
  }
@@ -118,8 +106,7 @@ FrtMultiMapper *frt_mulmap_new(void) {
118
106
  return self;
119
107
  }
120
108
 
121
- static void mulmap_free_dstates(FrtMultiMapper *self)
122
- {
109
+ static void mulmap_free_dstates(FrtMultiMapper *self) {
123
110
  if (self->d_size > 0) {
124
111
  int i;
125
112
  for (i = self->d_size - 1; i >= 0; i--) {
@@ -129,8 +116,7 @@ static void mulmap_free_dstates(FrtMultiMapper *self)
129
116
  }
130
117
  }
131
118
 
132
- void frt_mulmap_add_mapping(FrtMultiMapper *self, const char *pattern, const char *rep)
133
- {
119
+ void frt_mulmap_add_mapping(FrtMultiMapper *self, const char *pattern, const char *rep) {
134
120
  if (pattern == NULL || pattern[0] == '\0') {
135
121
  FRT_RAISE(FRT_ARG_ERROR, "Tried to add empty pattern to multi_mapper");
136
122
  } else {
@@ -147,16 +133,14 @@ void frt_mulmap_add_mapping(FrtMultiMapper *self, const char *pattern, const cha
147
133
  }
148
134
 
149
135
 
150
- static void mulmap_bv_set_states(FrtBitVector *bv, int *states, int cnt)
151
- {
136
+ static void mulmap_bv_set_states(FrtBitVector *bv, int *states, int cnt) {
152
137
  int i;
153
138
  for (i = cnt - 1; i >= 0; i--) {
154
139
  frt_bv_set(bv, states[i]);
155
140
  }
156
141
  }
157
142
 
158
- static FrtDeterministicState *mulmap_process_state(FrtMultiMapper *self, FrtBitVector *bv)
159
- {
143
+ static FrtDeterministicState *mulmap_process_state(FrtMultiMapper *self, FrtBitVector *bv) {
160
144
  FrtDeterministicState *current_state
161
145
  = (FrtDeterministicState *)frt_h_get(self->dstates_map, bv);
162
146
  if (current_state == NULL) {
@@ -197,15 +181,13 @@ static FrtDeterministicState *mulmap_process_state(FrtMultiMapper *self, FrtBitV
197
181
  }
198
182
  current_state->next[(int)c] = mulmap_process_state(self, nxt_bv);
199
183
  }
200
- }
201
- else {
184
+ } else {
202
185
  frt_bv_destroy(bv);
203
186
  }
204
187
  return current_state;
205
188
  }
206
189
 
207
- void frt_mulmap_compile(FrtMultiMapper *self)
208
- {
190
+ void frt_mulmap_compile(FrtMultiMapper *self) {
209
191
  NonDeterministicState *start = ndstate_new();
210
192
  int i, j;
211
193
  int size = 1;
@@ -254,8 +236,7 @@ void frt_mulmap_compile(FrtMultiMapper *self)
254
236
  free(nstates);
255
237
  }
256
238
 
257
- int frt_mulmap_map_len(FrtMultiMapper *self, char *to, char *from, int capa)
258
- {
239
+ int frt_mulmap_map_len(FrtMultiMapper *self, char *to, char *from, int capa) {
259
240
  FrtDeterministicState *start = self->dstates[0];
260
241
  FrtDeterministicState *state = start;
261
242
  char *s = from, *d = to, *end = to + capa - 1;
@@ -273,8 +254,7 @@ int frt_mulmap_map_len(FrtMultiMapper *self, char *to, char *from, int capa)
273
254
  memcpy(d, state->mapping, len);
274
255
  d += len;
275
256
  state = start;
276
- }
277
- else {
257
+ } else {
278
258
  *(d++) = *s;
279
259
  }
280
260
  s++;
@@ -283,15 +263,13 @@ int frt_mulmap_map_len(FrtMultiMapper *self, char *to, char *from, int capa)
283
263
  return d - to;
284
264
  }
285
265
 
286
- char *frt_mulmap_map(FrtMultiMapper *self, char *to, char *from, int capa)
287
- {
266
+ char *frt_mulmap_map(FrtMultiMapper *self, char *to, char *from, int capa) {
288
267
  frt_mulmap_map_len(self, to, from, capa);
289
268
  return to;
290
269
  }
291
270
 
292
271
  /* Maps a string to a dynamically allocated string */
293
- char *frt_mulmap_dynamic_map(FrtMultiMapper *self, char *from)
294
- {
272
+ char *frt_mulmap_dynamic_map(FrtMultiMapper *self, char *from) {
295
273
  FrtDeterministicState *start = self->dstates[0];
296
274
  FrtDeterministicState *state = start;
297
275
  int capa = strlen(from);
@@ -312,8 +290,7 @@ char *frt_mulmap_dynamic_map(FrtMultiMapper *self, char *from)
312
290
  memcpy(d, state->mapping, len);
313
291
  d += len;
314
292
  state = start;
315
- }
316
- else {
293
+ } else {
317
294
  *(d++) = *s;
318
295
  }
319
296
  s++;
@@ -3,29 +3,25 @@
3
3
 
4
4
  #include "frt_hash.h"
5
5
 
6
- typedef struct FrtState
7
- {
6
+ typedef struct FrtState {
8
7
  int (*next)(struct FrtState *self, int c, int *states);
9
8
  void (*destroy_i)(struct FrtState *self);
10
9
  int (*is_match)(struct FrtState *self, char **mapping);
11
10
  } FrtState;
12
11
 
13
- typedef struct FrtDeterministicState
14
- {
12
+ typedef struct FrtDeterministicState {
15
13
  struct FrtDeterministicState *next[256];
16
14
  int longest_match;
17
15
  char *mapping;
18
16
  int mapping_len;
19
17
  } FrtDeterministicState;
20
18
 
21
- typedef struct FrtMapping
22
- {
19
+ typedef struct FrtMapping {
23
20
  char *pattern;
24
21
  char *replacement;
25
22
  } FrtMapping;
26
23
 
27
- typedef struct FrtMultiMapper
28
- {
24
+ typedef struct FrtMultiMapper {
29
25
  FrtMapping **mappings;
30
26
  int size;
31
27
  int capa;
@@ -0,0 +1,334 @@
1
+ /* prevent warning: #warning Please include winsock2.h before windows.h [-Wcpp] */
2
+ #ifdef _WIN32
3
+ # include <winsock2.h>
4
+ #endif
5
+
6
+ #include "brotli_decode.h"
7
+ #include "brotli_encode.h"
8
+ #include "bzlib.h"
9
+ #include "lz4frame.h"
10
+ #include "frt_except.h"
11
+ #include "frt_stream.h"
12
+ #include "frt_out_stream.h"
13
+
14
+ #define FRT_BROTLI_COMPRESSION_LEVEL 4
15
+ #define FRT_BZIP_COMPRESSION_LEVEL 9
16
+
17
+ /**
18
+ * Create a newly allocated and initialized OutStream object
19
+ *
20
+ * @return a newly allocated and initialized OutStream object
21
+ */
22
+ FrtOutStream *frt_os_new(void) {
23
+ FrtOutStream *os = FRT_ALLOC(FrtOutStream);
24
+ os->folder_name = NULL;
25
+ os->buf.start = 0;
26
+ os->buf.pos = 0;
27
+ os->buf.len = 0;
28
+ return os;
29
+ }
30
+
31
+ /**
32
+ * Flush the countents of the FrtOutStream's buffers
33
+ *
34
+ * @param the OutStream to flush
35
+ */
36
+ void frt_os_flush(FrtOutStream *os) {
37
+ os->m->flush_i(os, os->buf.buf, os->buf.pos);
38
+ os->buf.start += os->buf.pos;
39
+ os->buf.pos = 0;
40
+ }
41
+
42
+ void frt_os_close(FrtOutStream *os) {
43
+ frt_os_flush(os);
44
+ os->m->close_i(os);
45
+ if (os->folder_name) {
46
+ free((void *)os->folder_name);
47
+ }
48
+ free(os);
49
+ }
50
+
51
+ off_t frt_os_pos(FrtOutStream *os) {
52
+ return os->buf.start + os->buf.pos;
53
+ }
54
+
55
+ void frt_os_seek(FrtOutStream *os, frt_off_t new_pos) {
56
+ frt_os_flush(os);
57
+ os->buf.start = new_pos;
58
+ os->m->seek_i(os, new_pos);
59
+ }
60
+
61
+ /**
62
+ * Unsafe alternative to os_write_byte. Only use this method if you know there
63
+ * is no chance of buffer overflow.
64
+ */
65
+ #define write_byte(os, b) os->buf.buf[os->buf.pos++] = (frt_uchar)b
66
+
67
+ /**
68
+ * Write a single byte +b+ to the OutStream +os+
69
+ *
70
+ * @param os the OutStream to write to
71
+ * @param b the byte to write
72
+ * @raise FRT_IO_ERROR if there is an IO error writing to the filesystem
73
+ */
74
+ void frt_os_write_byte(FrtOutStream *os, frt_uchar b) {
75
+ if (os->buf.pos >= (FRT_BUFFER_SIZE - 1)) {
76
+ frt_os_flush(os);
77
+ }
78
+ write_byte(os, b);
79
+ }
80
+
81
+ void frt_os_write_bytes(FrtOutStream *os, const frt_uchar *buf, int len) {
82
+ if (len < (FRT_BUFFER_SIZE - os->buf.pos)) {
83
+ memcpy(os->buf.buf + os->buf.pos, buf, len);
84
+ os->buf.pos += len;
85
+ } else {
86
+ frt_os_flush(os);
87
+ int pos = 0;
88
+ int size;
89
+ while (pos < len) {
90
+ if (len - pos < FRT_BUFFER_SIZE) {
91
+ size = len - pos;
92
+ } else {
93
+ size = FRT_BUFFER_SIZE;
94
+ }
95
+ os->m->flush_i(os, buf + pos, size);
96
+ pos += size;
97
+ os->buf.start += size;
98
+ }
99
+ }
100
+ }
101
+
102
+ void frt_os_write_i32(FrtOutStream *os, frt_i32 num) {
103
+ frt_os_write_byte(os, (frt_uchar)((num >> 24) & 0xFF));
104
+ frt_os_write_byte(os, (frt_uchar)((num >> 16) & 0xFF));
105
+ frt_os_write_byte(os, (frt_uchar)((num >> 8) & 0xFF));
106
+ frt_os_write_byte(os, (frt_uchar)(num & 0xFF));
107
+ }
108
+
109
+ void frt_os_write_i64(FrtOutStream *os, frt_i64 num) {
110
+ frt_os_write_byte(os, (frt_uchar)((num >> 56) & 0xFF));
111
+ frt_os_write_byte(os, (frt_uchar)((num >> 48) & 0xFF));
112
+ frt_os_write_byte(os, (frt_uchar)((num >> 40) & 0xFF));
113
+ frt_os_write_byte(os, (frt_uchar)((num >> 32) & 0xFF));
114
+ frt_os_write_byte(os, (frt_uchar)((num >> 24) & 0xFF));
115
+ frt_os_write_byte(os, (frt_uchar)((num >> 16) & 0xFF));
116
+ frt_os_write_byte(os, (frt_uchar)((num >> 8) & 0xFF));
117
+ frt_os_write_byte(os, (frt_uchar)(num & 0xFF));
118
+ }
119
+
120
+ void frt_os_write_u32(FrtOutStream *os, frt_u32 num) {
121
+ frt_os_write_byte(os, (frt_uchar)((num >> 24) & 0xFF));
122
+ frt_os_write_byte(os, (frt_uchar)((num >> 16) & 0xFF));
123
+ frt_os_write_byte(os, (frt_uchar)((num >> 8) & 0xFF));
124
+ frt_os_write_byte(os, (frt_uchar)(num & 0xFF));
125
+ }
126
+
127
+ void frt_os_write_u64(FrtOutStream *os, frt_u64 num) {
128
+ frt_os_write_byte(os, (frt_uchar)((num >> 56) & 0xFF));
129
+ frt_os_write_byte(os, (frt_uchar)((num >> 48) & 0xFF));
130
+ frt_os_write_byte(os, (frt_uchar)((num >> 40) & 0xFF));
131
+ frt_os_write_byte(os, (frt_uchar)((num >> 32) & 0xFF));
132
+ frt_os_write_byte(os, (frt_uchar)((num >> 24) & 0xFF));
133
+ frt_os_write_byte(os, (frt_uchar)((num >> 16) & 0xFF));
134
+ frt_os_write_byte(os, (frt_uchar)((num >> 8) & 0xFF));
135
+ frt_os_write_byte(os, (frt_uchar)(num & 0xFF));
136
+ }
137
+
138
+ /* optimized to use an unchecked write if there is space */
139
+ void frt_os_write_vint(FrtOutStream *os, register unsigned int num) {
140
+ if (os->buf.pos > VINT_END) {
141
+ while (num > 127) {
142
+ frt_os_write_byte(os, (frt_uchar)((num & 0x7f) | 0x80));
143
+ num >>= 7;
144
+ }
145
+ frt_os_write_byte(os, (frt_uchar)(num));
146
+ } else {
147
+ while (num > 127) {
148
+ write_byte(os, (frt_uchar)((num & 0x7f) | 0x80));
149
+ num >>= 7;
150
+ }
151
+ write_byte(os, (frt_uchar)(num));
152
+ }
153
+ }
154
+
155
+ /* optimized to use an unchecked write if there is space */
156
+ void frt_os_write_voff_t(FrtOutStream *os, register frt_off_t num) {
157
+ if (os->buf.pos > VINT_END) {
158
+ while (num > 127) {
159
+ frt_os_write_byte(os, (frt_uchar)((num & 0x7f) | 0x80));
160
+ num >>= 7;
161
+ }
162
+ frt_os_write_byte(os, (frt_uchar)num);
163
+ } else {
164
+ while (num > 127) {
165
+ write_byte(os, (frt_uchar)((num & 0x7f) | 0x80));
166
+ num >>= 7;
167
+ }
168
+ write_byte(os, (frt_uchar)num);
169
+ }
170
+ }
171
+
172
+ /* optimized to use an unchecked write if there is space */
173
+ void frt_os_write_vll(FrtOutStream *os, register frt_u64 num) {
174
+ if (os->buf.pos > VINT_END) {
175
+ while (num > 127) {
176
+ frt_os_write_byte(os, (frt_uchar)((num & 0x7f) | 0x80));
177
+ num >>= 7;
178
+ }
179
+ frt_os_write_byte(os, (frt_uchar)num);
180
+ } else {
181
+ while (num > 127) {
182
+ write_byte(os, (frt_uchar)((num & 0x7f) | 0x80));
183
+ num >>= 7;
184
+ }
185
+ write_byte(os, (frt_uchar)num);
186
+ }
187
+ }
188
+
189
+ void frt_os_write_string_len(FrtOutStream *os, const char *str, int len) {
190
+ frt_os_write_vint(os, len);
191
+ frt_os_write_bytes(os, (frt_uchar *)str, len);
192
+ }
193
+
194
+ void frt_os_write_string(FrtOutStream *os, const char *str) {
195
+ frt_os_write_string_len(os, str, (int)strlen(str));
196
+ }
197
+
198
+ static int frt_os_write_brotli_compressed_bytes(FrtOutStream* out_stream, frt_uchar *data, int length) {
199
+ size_t compressed_length = 0;
200
+ const frt_uchar *next_in = data;
201
+ size_t available_in = length;
202
+ size_t available_out;
203
+ frt_uchar compression_buffer[FRT_COMPRESSION_BUFFER_SIZE];
204
+ frt_uchar *next_out;
205
+ BrotliEncoderState *b_state = BrotliEncoderCreateInstance(NULL, NULL, NULL);
206
+ if (!b_state) { frt_comp_raise(); return -1; }
207
+
208
+ BrotliEncoderSetParameter(b_state, BROTLI_PARAM_QUALITY, FRT_BROTLI_COMPRESSION_LEVEL);
209
+
210
+ do {
211
+ available_out = FRT_COMPRESSION_BUFFER_SIZE;
212
+ next_out = compression_buffer;
213
+ if (!BrotliEncoderCompressStream(b_state, BROTLI_OPERATION_FINISH,
214
+ &available_in, &next_in,
215
+ &available_out, &next_out, &compressed_length)) {
216
+ BrotliEncoderDestroyInstance(b_state);
217
+ frt_comp_raise();
218
+ return -1;
219
+ }
220
+ frt_os_write_bytes(out_stream, compression_buffer, FRT_COMPRESSION_BUFFER_SIZE - available_out);
221
+ } while (!BrotliEncoderIsFinished(b_state));
222
+
223
+ BrotliEncoderDestroyInstance(b_state);
224
+
225
+ return (int)compressed_length;
226
+ }
227
+
228
+ static int frt_os_write_bz2_compressed_bytes(FrtOutStream* out_stream, frt_uchar *data, int length) {
229
+ int ret, buf_size, compressed_len = 0;
230
+ char out_buffer[FRT_COMPRESSION_BUFFER_SIZE];
231
+ bz_stream zstrm;
232
+ zstrm.bzalloc = NULL;
233
+ zstrm.bzfree = NULL;
234
+ zstrm.opaque = NULL;
235
+ if ((ret = BZ2_bzCompressInit(&zstrm, FRT_BZIP_COMPRESSION_LEVEL, 0, 0)) != BZ_OK) frt_zraise(ret);
236
+
237
+ zstrm.avail_in = length;
238
+ zstrm.next_in = (char *)data;
239
+ zstrm.avail_out = FRT_COMPRESSION_BUFFER_SIZE;
240
+ zstrm.next_out = out_buffer;
241
+
242
+ do {
243
+ ret = BZ2_bzCompress(&zstrm, BZ_FINISH); /* no bad return value */
244
+ assert(ret != BZ_SEQUENCE_ERROR); /* state not clobbered */
245
+ compressed_len += buf_size = FRT_COMPRESSION_BUFFER_SIZE - zstrm.avail_out;
246
+ frt_os_write_bytes(out_stream, (frt_uchar *)out_buffer, buf_size);
247
+ } while (zstrm.avail_out == 0);
248
+ assert(zstrm.avail_in == 0); /* all input will be used */
249
+
250
+ (void)BZ2_bzCompressEnd(&zstrm);
251
+ return compressed_len;
252
+ }
253
+
254
+ static const LZ4F_preferences_t lz4_prefs = {
255
+ {
256
+ LZ4F_default,
257
+ LZ4F_blockLinked,
258
+ LZ4F_noContentChecksum,
259
+ LZ4F_frame,
260
+ 0, /* unknown content size */
261
+ 0, /* no dictID */
262
+ LZ4F_noBlockChecksum
263
+ },
264
+ 0,
265
+ 1,
266
+ 1,
267
+ {0,0,0}
268
+ };
269
+
270
+ static int frt_os_write_lz4_compressed_bytes(FrtOutStream* out_stream, frt_uchar *data, int length) {
271
+ int compressed_length = 0;
272
+ int remaining_length = length;
273
+ size_t ccmp_length = 0;
274
+ LZ4F_compressionContext_t ctx;
275
+ size_t out_buf_length = LZ4F_compressBound(FRT_COMPRESSION_BUFFER_SIZE, &lz4_prefs);
276
+ frt_uchar *out_buf = frt_ecalloc(out_buf_length);
277
+
278
+ size_t ctx_creation = LZ4F_createCompressionContext(&ctx, LZ4F_VERSION);
279
+ if (LZ4F_isError(ctx_creation)) {
280
+ compressed_length = -1;
281
+ goto finish;
282
+ }
283
+
284
+ /* create header */
285
+ ccmp_length = LZ4F_compressBegin(ctx, out_buf, out_buf_length, &lz4_prefs);
286
+ if (LZ4F_isError(ccmp_length)) {
287
+ compressed_length = -1;
288
+ goto finish;
289
+ }
290
+ compressed_length = ccmp_length;
291
+ frt_os_write_bytes(out_stream, out_buf, ccmp_length);
292
+
293
+ /* compress data */
294
+ do {
295
+ int read_length = (FRT_COMPRESSION_BUFFER_SIZE > remaining_length) ? remaining_length : FRT_COMPRESSION_BUFFER_SIZE;
296
+ ccmp_length = LZ4F_compressUpdate(ctx, out_buf, out_buf_length, data + (length - remaining_length), read_length, NULL);
297
+ if (LZ4F_isError(ccmp_length)) {
298
+ compressed_length = -1;
299
+ goto finish;
300
+ }
301
+ frt_os_write_bytes(out_stream, out_buf, ccmp_length);
302
+ compressed_length += ccmp_length;
303
+ remaining_length -= read_length;
304
+ } while (remaining_length > 0);
305
+
306
+ /* finish up */
307
+ ccmp_length = LZ4F_compressEnd(ctx, out_buf, out_buf_length, NULL);
308
+ if (LZ4F_isError(ccmp_length)) {
309
+ compressed_length = -1;
310
+ goto finish;
311
+ }
312
+
313
+ frt_os_write_bytes(out_stream, out_buf, ccmp_length);
314
+ compressed_length += ccmp_length;
315
+
316
+ finish:
317
+ LZ4F_freeCompressionContext(ctx);
318
+ free(out_buf);
319
+
320
+ return compressed_length;
321
+ }
322
+
323
+ int frt_os_write_compressed_bytes(FrtOutStream* out_stream, frt_uchar *data, int length, FrtCompressionType compression_type) {
324
+ switch (compression_type) {
325
+ case FRT_COMPRESSION_BROTLI:
326
+ return frt_os_write_brotli_compressed_bytes(out_stream, data, length);
327
+ case FRT_COMPRESSION_BZ2:
328
+ return frt_os_write_bz2_compressed_bytes(out_stream, data, length);
329
+ case FRT_COMPRESSION_LZ4:
330
+ return frt_os_write_lz4_compressed_bytes(out_stream, data, length);
331
+ default:
332
+ return -1;
333
+ }
334
+ }