ferret 0.11.6 → 0.11.8.4

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 (185) hide show
  1. data/README +10 -22
  2. data/RELEASE_CHANGES +137 -0
  3. data/RELEASE_NOTES +60 -0
  4. data/Rakefile +379 -274
  5. data/TODO +100 -8
  6. data/bin/ferret-browser +0 -0
  7. data/ext/BZLIB_blocksort.c +1094 -0
  8. data/ext/BZLIB_bzlib.c +1578 -0
  9. data/ext/BZLIB_compress.c +672 -0
  10. data/ext/BZLIB_crctable.c +104 -0
  11. data/ext/BZLIB_decompress.c +626 -0
  12. data/ext/BZLIB_huffman.c +205 -0
  13. data/ext/BZLIB_randtable.c +84 -0
  14. data/ext/{api.c → STEMMER_api.c} +7 -10
  15. data/ext/{libstemmer.c → STEMMER_libstemmer.c} +3 -2
  16. data/ext/{stem_ISO_8859_1_danish.c → STEMMER_stem_ISO_8859_1_danish.c} +123 -124
  17. data/ext/{stem_ISO_8859_1_dutch.c → STEMMER_stem_ISO_8859_1_dutch.c} +177 -188
  18. data/ext/STEMMER_stem_ISO_8859_1_english.c +1117 -0
  19. data/ext/{stem_ISO_8859_1_finnish.c → STEMMER_stem_ISO_8859_1_finnish.c} +276 -306
  20. data/ext/STEMMER_stem_ISO_8859_1_french.c +1246 -0
  21. data/ext/{stem_ISO_8859_1_german.c → STEMMER_stem_ISO_8859_1_german.c} +161 -170
  22. data/ext/STEMMER_stem_ISO_8859_1_hungarian.c +1230 -0
  23. data/ext/STEMMER_stem_ISO_8859_1_italian.c +1065 -0
  24. data/ext/STEMMER_stem_ISO_8859_1_norwegian.c +297 -0
  25. data/ext/{stem_ISO_8859_1_porter.c → STEMMER_stem_ISO_8859_1_porter.c} +263 -290
  26. data/ext/{stem_ISO_8859_1_portuguese.c → STEMMER_stem_ISO_8859_1_portuguese.c} +362 -380
  27. data/ext/STEMMER_stem_ISO_8859_1_spanish.c +1093 -0
  28. data/ext/STEMMER_stem_ISO_8859_1_swedish.c +307 -0
  29. data/ext/STEMMER_stem_ISO_8859_2_romanian.c +998 -0
  30. data/ext/{stem_KOI8_R_russian.c → STEMMER_stem_KOI8_R_russian.c} +244 -245
  31. data/ext/STEMMER_stem_UTF_8_danish.c +339 -0
  32. data/ext/{stem_UTF_8_dutch.c → STEMMER_stem_UTF_8_dutch.c} +192 -211
  33. data/ext/STEMMER_stem_UTF_8_english.c +1125 -0
  34. data/ext/{stem_UTF_8_finnish.c → STEMMER_stem_UTF_8_finnish.c} +284 -324
  35. data/ext/STEMMER_stem_UTF_8_french.c +1256 -0
  36. data/ext/{stem_UTF_8_german.c → STEMMER_stem_UTF_8_german.c} +170 -187
  37. data/ext/STEMMER_stem_UTF_8_hungarian.c +1234 -0
  38. data/ext/STEMMER_stem_UTF_8_italian.c +1073 -0
  39. data/ext/STEMMER_stem_UTF_8_norwegian.c +299 -0
  40. data/ext/{stem_UTF_8_porter.c → STEMMER_stem_UTF_8_porter.c} +271 -310
  41. data/ext/STEMMER_stem_UTF_8_portuguese.c +1023 -0
  42. data/ext/STEMMER_stem_UTF_8_romanian.c +1004 -0
  43. data/ext/STEMMER_stem_UTF_8_russian.c +694 -0
  44. data/ext/STEMMER_stem_UTF_8_spanish.c +1097 -0
  45. data/ext/STEMMER_stem_UTF_8_swedish.c +309 -0
  46. data/ext/STEMMER_stem_UTF_8_turkish.c +2205 -0
  47. data/ext/{utilities.c → STEMMER_utilities.c} +100 -68
  48. data/ext/analysis.c +276 -121
  49. data/ext/analysis.h +190 -143
  50. data/ext/api.h +3 -4
  51. data/ext/array.c +5 -3
  52. data/ext/array.h +52 -43
  53. data/ext/bitvector.c +38 -482
  54. data/ext/bitvector.h +446 -124
  55. data/ext/bzlib.h +282 -0
  56. data/ext/bzlib_private.h +503 -0
  57. data/ext/compound_io.c +23 -22
  58. data/ext/config.h +21 -11
  59. data/ext/document.c +43 -40
  60. data/ext/document.h +31 -21
  61. data/ext/except.c +20 -38
  62. data/ext/except.h +89 -76
  63. data/ext/extconf.rb +3 -2
  64. data/ext/ferret.c +49 -35
  65. data/ext/ferret.h +14 -11
  66. data/ext/field_index.c +262 -0
  67. data/ext/field_index.h +52 -0
  68. data/ext/filter.c +11 -10
  69. data/ext/fs_store.c +65 -47
  70. data/ext/global.c +245 -165
  71. data/ext/global.h +252 -54
  72. data/ext/hash.c +200 -243
  73. data/ext/hash.h +205 -163
  74. data/ext/hashset.c +118 -96
  75. data/ext/hashset.h +110 -82
  76. data/ext/header.h +19 -19
  77. data/ext/helper.c +11 -10
  78. data/ext/helper.h +14 -6
  79. data/ext/index.c +745 -366
  80. data/ext/index.h +503 -529
  81. data/ext/internal.h +1020 -0
  82. data/ext/lang.c +10 -0
  83. data/ext/lang.h +35 -15
  84. data/ext/mempool.c +5 -4
  85. data/ext/mempool.h +30 -22
  86. data/ext/modules.h +35 -7
  87. data/ext/multimapper.c +43 -2
  88. data/ext/multimapper.h +32 -23
  89. data/ext/posh.c +0 -0
  90. data/ext/posh.h +4 -38
  91. data/ext/priorityqueue.c +10 -12
  92. data/ext/priorityqueue.h +33 -21
  93. data/ext/q_boolean.c +22 -9
  94. data/ext/q_const_score.c +3 -2
  95. data/ext/q_filtered_query.c +15 -12
  96. data/ext/q_fuzzy.c +147 -135
  97. data/ext/q_match_all.c +3 -2
  98. data/ext/q_multi_term.c +28 -32
  99. data/ext/q_parser.c +451 -173
  100. data/ext/q_phrase.c +158 -79
  101. data/ext/q_prefix.c +16 -18
  102. data/ext/q_range.c +363 -31
  103. data/ext/q_span.c +130 -141
  104. data/ext/q_term.c +21 -21
  105. data/ext/q_wildcard.c +19 -23
  106. data/ext/r_analysis.c +369 -242
  107. data/ext/r_index.c +421 -434
  108. data/ext/r_qparser.c +142 -92
  109. data/ext/r_search.c +790 -407
  110. data/ext/r_store.c +44 -44
  111. data/ext/r_utils.c +264 -96
  112. data/ext/ram_store.c +29 -23
  113. data/ext/scanner.c +895 -0
  114. data/ext/scanner.h +36 -0
  115. data/ext/scanner_mb.c +6701 -0
  116. data/ext/scanner_utf8.c +4415 -0
  117. data/ext/search.c +210 -87
  118. data/ext/search.h +556 -488
  119. data/ext/similarity.c +17 -16
  120. data/ext/similarity.h +51 -44
  121. data/ext/sort.c +157 -354
  122. data/ext/stem_ISO_8859_1_hungarian.h +16 -0
  123. data/ext/stem_ISO_8859_2_romanian.h +16 -0
  124. data/ext/stem_UTF_8_hungarian.h +16 -0
  125. data/ext/stem_UTF_8_romanian.h +16 -0
  126. data/ext/stem_UTF_8_turkish.h +16 -0
  127. data/ext/stopwords.c +287 -278
  128. data/ext/store.c +57 -51
  129. data/ext/store.h +308 -286
  130. data/ext/symbol.c +10 -0
  131. data/ext/symbol.h +23 -0
  132. data/ext/term_vectors.c +14 -293
  133. data/ext/threading.h +22 -22
  134. data/ext/win32.h +12 -4
  135. data/lib/ferret.rb +2 -1
  136. data/lib/ferret/browser.rb +1 -1
  137. data/lib/ferret/field_symbol.rb +94 -0
  138. data/lib/ferret/index.rb +221 -34
  139. data/lib/ferret/number_tools.rb +6 -6
  140. data/lib/ferret/version.rb +3 -0
  141. data/test/{unit → long_running}/largefile/tc_largefile.rb +1 -1
  142. data/test/test_helper.rb +7 -2
  143. data/test/test_installed.rb +1 -0
  144. data/test/threading/thread_safety_index_test.rb +10 -1
  145. data/test/threading/thread_safety_read_write_test.rb +4 -7
  146. data/test/threading/thread_safety_test.rb +0 -0
  147. data/test/unit/analysis/tc_analyzer.rb +29 -27
  148. data/test/unit/analysis/tc_token_stream.rb +23 -16
  149. data/test/unit/index/tc_index.rb +116 -11
  150. data/test/unit/index/tc_index_reader.rb +27 -27
  151. data/test/unit/index/tc_index_writer.rb +10 -0
  152. data/test/unit/index/th_doc.rb +38 -21
  153. data/test/unit/search/tc_filter.rb +31 -10
  154. data/test/unit/search/tc_index_searcher.rb +6 -0
  155. data/test/unit/search/tm_searcher.rb +53 -1
  156. data/test/unit/store/tc_fs_store.rb +40 -2
  157. data/test/unit/store/tc_ram_store.rb +0 -0
  158. data/test/unit/store/tm_store.rb +0 -0
  159. data/test/unit/store/tm_store_lock.rb +7 -6
  160. data/test/unit/tc_field_symbol.rb +26 -0
  161. data/test/unit/ts_analysis.rb +0 -0
  162. data/test/unit/ts_index.rb +0 -0
  163. data/test/unit/ts_store.rb +0 -0
  164. data/test/unit/ts_utils.rb +0 -0
  165. data/test/unit/utils/tc_number_tools.rb +0 -0
  166. data/test/utils/content_generator.rb +226 -0
  167. metadata +262 -221
  168. data/ext/inc/lang.h +0 -48
  169. data/ext/inc/threading.h +0 -31
  170. data/ext/stem_ISO_8859_1_english.c +0 -1156
  171. data/ext/stem_ISO_8859_1_french.c +0 -1276
  172. data/ext/stem_ISO_8859_1_italian.c +0 -1091
  173. data/ext/stem_ISO_8859_1_norwegian.c +0 -296
  174. data/ext/stem_ISO_8859_1_spanish.c +0 -1119
  175. data/ext/stem_ISO_8859_1_swedish.c +0 -307
  176. data/ext/stem_UTF_8_danish.c +0 -344
  177. data/ext/stem_UTF_8_english.c +0 -1176
  178. data/ext/stem_UTF_8_french.c +0 -1296
  179. data/ext/stem_UTF_8_italian.c +0 -1113
  180. data/ext/stem_UTF_8_norwegian.c +0 -302
  181. data/ext/stem_UTF_8_portuguese.c +0 -1055
  182. data/ext/stem_UTF_8_russian.c +0 -709
  183. data/ext/stem_UTF_8_spanish.c +0 -1137
  184. data/ext/stem_UTF_8_swedish.c +0 -313
  185. data/lib/ferret_version.rb +0 -3
@@ -2,6 +2,8 @@
2
2
  #include <limits.h>
3
3
  #include "search.h"
4
4
  #include "hashset.h"
5
+ #include "symbol.h"
6
+ #include "internal.h"
5
7
 
6
8
  #define CLAUSE_INIT_CAPA 4
7
9
 
@@ -19,12 +21,12 @@
19
21
 
20
22
  static unsigned long spanq_hash(Query *self)
21
23
  {
22
- return str_hash(SpQ(self)->field);
24
+ return SpQ(self)->field ? sym_hash(SpQ(self)->field) : 0;
23
25
  }
24
26
 
25
27
  static int spanq_eq(Query *self, Query *o)
26
28
  {
27
- return strcmp(SpQ(self)->field, SpQ(o)->field) == 0;
29
+ return SpQ(self)->field == SpQ(o)->field;
28
30
  }
29
31
 
30
32
  static void spanq_destroy_i(Query *self)
@@ -35,15 +37,14 @@ static void spanq_destroy_i(Query *self)
35
37
  static MatchVector *mv_to_term_mv(MatchVector *term_mv, MatchVector *full_mv,
36
38
  HashSet *terms, TermVector *tv)
37
39
  {
38
- int i;
39
- for (i = 0; i < terms->size; i++) {
40
- char *term = (char *)terms->elems[i];
40
+ HashSetEntry *hse;
41
+ for (hse = terms->first; hse; hse = hse->next) {
42
+ char *term = (char *)hse->elem;
41
43
  TVTerm *tv_term = tv_get_tv_term(tv, term);
42
44
  if (tv_term) {
43
- int j;
44
- int m_idx = 0;
45
- for (j = 0; j < tv_term->freq; j++) {
46
- int pos = tv_term->positions[j];
45
+ int i, m_idx = 0;
46
+ for (i = 0; i < tv_term->freq; i++) {
47
+ int pos = tv_term->positions[i];
47
48
  for (; m_idx < full_mv->size; m_idx++) {
48
49
  if (pos <= full_mv->matches[m_idx].end) {
49
50
  if (pos >= full_mv->matches[m_idx].start) {
@@ -134,29 +135,31 @@ static int tv_tde_doc_num(TermDocEnum *tde)
134
135
  static TermDocEnum *spanq_ir_term_positions(IndexReader *ir)
135
136
  {
136
137
  TVTermDocEnum *tv_tde = ALLOC(TVTermDocEnum);
137
- TermDocEnum *tde = (TermDocEnum *)tv_tde;
138
- tv_tde->tv = (TermVector *)ir->store;
139
- tde->seek = &tv_tde_seek;
140
- tde->doc_num = &tv_tde_doc_num;
141
- tde->freq = &tv_tde_freq;
142
- tde->next = &tv_tde_next;
143
- tde->skip_to = &tv_tde_skip_to;
144
- tde->next_position = &tv_tde_next_position;
145
- tde->close = (void (*)(TermDocEnum *tde))&free;
146
-
138
+ TermDocEnum *tde = (TermDocEnum *)tv_tde;
139
+ tv_tde->tv = (TermVector *)ir->store;
140
+ tde->seek = &tv_tde_seek;
141
+ tde->doc_num = &tv_tde_doc_num;
142
+ tde->freq = &tv_tde_freq;
143
+ tde->next = &tv_tde_next;
144
+ tde->skip_to = &tv_tde_skip_to;
145
+ tde->next_position = &tv_tde_next_position;
146
+ tde->close = (void (*)(TermDocEnum *tde))&free;
147
+
147
148
  return tde;
148
149
  }
149
150
 
150
151
  static MatchVector *spanq_get_matchv_i(Query *self, MatchVector *mv,
151
152
  TermVector *tv)
152
153
  {
153
- if (strcmp(SpQ(self)->field, tv->field) == 0) {
154
+ if (SpQ(self)->field == tv->field) {
154
155
  SpanEnum *sp_enum;
155
156
  IndexReader *ir = ALLOC(IndexReader);
156
157
  MatchVector *full_mv = matchv_new();
157
158
  HashSet *terms = SpQ(self)->get_terms(self);
158
- ir->fis = fis_new(0, 0, 0);
159
- fis_add_field(ir->fis, fi_new(tv->field, 0, 0, 0));
159
+ /* FIXME What is going on here? Need to document this! */
160
+ ir->fis = fis_new(STORE_NO, INDEX_NO, TERM_VECTOR_NO);
161
+ fis_add_field(ir->fis,
162
+ fi_new(tv->field, STORE_NO, INDEX_NO, TERM_VECTOR_NO));
160
163
  ir->store = (Store *)tv;
161
164
  ir->term_positions = &spanq_ir_term_positions;
162
165
  sp_enum = SpQ(self)->get_spans(self, ir);
@@ -166,7 +169,7 @@ static MatchVector *spanq_get_matchv_i(Query *self, MatchVector *mv,
166
169
  sp_enum->end(sp_enum) - 1);
167
170
  }
168
171
  sp_enum->destroy(sp_enum);
169
-
172
+
170
173
  fis_deref(ir->fis);
171
174
  free(ir);
172
175
 
@@ -226,11 +229,11 @@ static bool spansc_next(Scorer *self)
226
229
  spansc->freq = 0.0;
227
230
  self->doc = se->doc(se);
228
231
 
229
- while (spansc->more && (self->doc == se->doc(se))) {
232
+ do {
230
233
  match_length = se->end(se) - se->start(se);
231
234
  spansc->freq += sim_sloppy_freq(spansc->sim, match_length);
232
235
  spansc->more = se->next(se);
233
- }
236
+ } while (spansc->more && (self->doc == se->doc(se)));
234
237
 
235
238
  return (spansc->more || (spansc->freq != 0.0));
236
239
  }
@@ -241,7 +244,6 @@ static bool spansc_skip_to(Scorer *self, int target)
241
244
  SpanEnum *se = spansc->spans;
242
245
 
243
246
  spansc->more = se->skip_to(se, target);
244
-
245
247
  if (!spansc->more) {
246
248
  return false;
247
249
  }
@@ -252,6 +254,9 @@ static bool spansc_skip_to(Scorer *self, int target)
252
254
  while (spansc->more && (se->doc(se) == target)) {
253
255
  spansc->freq += sim_sloppy_freq(spansc->sim, se->end(se) - se->start(se));
254
256
  spansc->more = se->next(se);
257
+ if (spansc->first_time) {
258
+ spansc->first_time = false;
259
+ }
255
260
  }
256
261
 
257
262
  return (spansc->more || (spansc->freq != 0.0));
@@ -280,7 +285,7 @@ static void spansc_destroy(Scorer *self)
280
285
  scorer_destroy_i(self);
281
286
  }
282
287
 
283
- Scorer *spansc_new(Weight *weight, IndexReader *ir)
288
+ static Scorer *spansc_new(Weight *weight, IndexReader *ir)
284
289
  {
285
290
  Scorer *self = NULL;
286
291
  const int field_num = fis_get_field_num(ir->fis, SpQ(weight->query)->field);
@@ -349,9 +354,12 @@ static bool spante_skip_to(SpanEnum *self, int target)
349
354
  TermDocEnum *tde = ste->positions;
350
355
 
351
356
  /* are we already at the correct position? */
357
+ /* FIXME: perhaps this the the better solution but currently it ->skip_to
358
+ * does a ->next not matter what
352
359
  if (ste->doc >= target) {
353
360
  return true;
354
361
  }
362
+ */
355
363
 
356
364
  if (! tde->skip_to(tde, target)) {
357
365
  ste->doc = INT_MAX;
@@ -382,10 +390,9 @@ static int spante_end(SpanEnum *self)
382
390
  return SpTEn(self)->position + 1;
383
391
  }
384
392
 
385
- static char *spante_to_s(SpanEnum *self)
393
+ static char *spante_to_s(SpanEnum *self)
386
394
  {
387
- char *field = SpQ(self->query)->field;
388
- char *query_str = self->query->to_s(self->query, field);
395
+ char *query_str = self->query->to_s(self->query, NULL);
389
396
  char pos_str[20];
390
397
  size_t len = strlen(query_str);
391
398
  int pos;
@@ -403,7 +410,7 @@ static char *spante_to_s(SpanEnum *self)
403
410
  sprintf(pos_str, "%d", self->doc(self) - pos);
404
411
  }
405
412
  }
406
- sprintf("SpanTermEnum(%s)@%s", query_str, pos_str);
413
+ sprintf(str, "SpanTermEnum(%s)@%s", query_str, pos_str);
407
414
  free(query_str);
408
415
  return str;
409
416
  }
@@ -418,10 +425,10 @@ static void spante_destroy(SpanEnum *self)
418
425
  static SpanEnum *spante_new(Query *query, IndexReader *ir)
419
426
  {
420
427
  char *term = SpTQ(query)->term;
421
- char *field = SpQ(query)->field;
422
- SpanEnum *self = (SpanEnum *)emalloc(sizeof(SpanTermEnum));
428
+ SpanEnum *self = (SpanEnum *)ALLOC(SpanTermEnum);
423
429
 
424
- SpTEn(self)->positions = ir_term_positions_for(ir, field, term);
430
+ SpTEn(self)->positions = ir_term_positions_for(ir, SpQ(query)->field,
431
+ term);
425
432
  SpTEn(self)->position = -1;
426
433
  SpTEn(self)->doc = -1;
427
434
  SpTEn(self)->count = 0;
@@ -531,7 +538,7 @@ static bool spanmte_next(SpanEnum *self)
531
538
  }
532
539
  mte->tpew_pq = tpew_pq;
533
540
  }
534
-
541
+
535
542
  tpew = (TermPosEnumWrapper *)pq_top(tpew_pq);
536
543
  if (tpew == NULL) {
537
544
  return false;
@@ -612,8 +619,7 @@ static void spanmte_destroy(SpanEnum *self)
612
619
 
613
620
  static SpanEnum *spanmte_new(Query *query, IndexReader *ir)
614
621
  {
615
- char *field = SpQ(query)->field;
616
- SpanEnum *self = (SpanEnum *)emalloc(sizeof(SpanMultiTermEnum));
622
+ SpanEnum *self = (SpanEnum *)ALLOC(SpanMultiTermEnum);
617
623
  SpanMultiTermEnum *smte = SpMTEn(self);
618
624
  SpanMultiTermQuery *smtq = SpMTQ(query);
619
625
  int i;
@@ -622,7 +628,8 @@ static SpanEnum *spanmte_new(Query *query, IndexReader *ir)
622
628
  smte->tpews = ALLOC_N(TermPosEnumWrapper *, smtq->term_cnt);
623
629
  for (i = 0; i < smtq->term_cnt; i++) {
624
630
  char *term = smtq->terms[i];
625
- smte->tpews[i] = tpew_new(term, ir_term_positions_for(ir, field, term));
631
+ smte->tpews[i] = tpew_new(term,
632
+ ir_term_positions_for(ir, SpQ(query)->field, term));
626
633
  }
627
634
  smte->tpew_cnt = smtq->term_cnt;
628
635
  smte->tpew_pq = NULL;
@@ -681,7 +688,7 @@ static bool spanfe_skip_to(SpanEnum *self, int target)
681
688
  return true;
682
689
  }
683
690
 
684
- return sub_enum->next(sub_enum); /* scan to next match */
691
+ return spanfe_next(self); /* scan to next match */
685
692
  }
686
693
 
687
694
  static int spanfe_doc(SpanEnum *self)
@@ -702,10 +709,9 @@ static int spanfe_end(SpanEnum *self)
702
709
  return sub_enum->end(sub_enum);
703
710
  }
704
711
 
705
- static char *spanfe_to_s(SpanEnum *self)
712
+ static char *spanfe_to_s(SpanEnum *self)
706
713
  {
707
- char *field = SpQ(self->query)->field;
708
- char *query_str = self->query->to_s(self->query, field);
714
+ char *query_str = self->query->to_s(self->query, NULL);
709
715
  char *res = strfmt("SpanFirstEnum(%s)", query_str);
710
716
  free(query_str);
711
717
  return res;
@@ -720,7 +726,7 @@ static void spanfe_destroy(SpanEnum *self)
720
726
 
721
727
  static SpanEnum *spanfe_new(Query *query, IndexReader *ir)
722
728
  {
723
- SpanEnum *self = (SpanEnum *)emalloc(sizeof(SpanFirstEnum));
729
+ SpanEnum *self = (SpanEnum *)ALLOC(SpanFirstEnum);
724
730
  SpanFirstQuery *sfq = SpFQ(query);
725
731
 
726
732
  SpFEn(self)->sub_enum = SpQ(sfq->match)->get_spans(sfq->match, ir);
@@ -822,7 +828,8 @@ static bool spanoe_skip_to(SpanEnum *self, int target)
822
828
  }
823
829
  else {
824
830
  while ((soe->queue->size != 0) &&
825
- ((se = (SpanEnum *)pq_top(soe->queue))->doc(se) < target)) {
831
+ ((se = (SpanEnum *)pq_top(soe->queue)) != NULL) &&
832
+ (se->doc(se) < target)) {
826
833
  if (se->skip_to(se, target)) {
827
834
  pq_down(soe->queue);
828
835
  }
@@ -855,11 +862,10 @@ static int spanoe_end(SpanEnum *self)
855
862
  return se->end(se);
856
863
  }
857
864
 
858
- static char *spanoe_to_s(SpanEnum *self)
865
+ static char *spanoe_to_s(SpanEnum *self)
859
866
  {
860
867
  SpanOrEnum *soe = SpOEn(self);
861
- char *field = SpQ(self->query)->field;
862
- char *query_str = self->query->to_s(self->query, field);
868
+ char *query_str = self->query->to_s(self->query, NULL);
863
869
  char doc_str[62];
864
870
  size_t len = strlen(query_str);
865
871
  char *str = ALLOC_N(char, len + 80);
@@ -876,7 +882,7 @@ static char *spanoe_to_s(SpanEnum *self)
876
882
  self->start(self), self->end(self));
877
883
  }
878
884
  }
879
- sprintf("SpanOrEnum(%s)@%s", query_str, doc_str);
885
+ sprintf(str, "SpanOrEnum(%s)@%s", query_str, doc_str);
880
886
  free(query_str);
881
887
  return str;
882
888
  }
@@ -895,10 +901,10 @@ static void spanoe_destroy(SpanEnum *self)
895
901
  free(self);
896
902
  }
897
903
 
898
- SpanEnum *spanoe_new(Query *query, IndexReader *ir)
904
+ static SpanEnum *spanoe_new(Query *query, IndexReader *ir)
899
905
  {
900
906
  Query *clause;
901
- SpanEnum *self = (SpanEnum *)emalloc(sizeof(SpanOrEnum));
907
+ SpanEnum *self = (SpanEnum *)ALLOC(SpanOrEnum);
902
908
  SpanOrQuery *soq = SpOQ(query);
903
909
  int i;
904
910
 
@@ -1168,11 +1174,10 @@ static int spanne_end(SpanEnum *self)
1168
1174
  return SpNEn(self)->end;
1169
1175
  }
1170
1176
 
1171
- static char *spanne_to_s(SpanEnum *self)
1177
+ static char *spanne_to_s(SpanEnum *self)
1172
1178
  {
1173
1179
  SpanNearEnum *sne = SpNEn(self);
1174
- char *field = SpQ(self->query)->field;
1175
- char *query_str = self->query->to_s(self->query, field);
1180
+ char *query_str = self->query->to_s(self->query, NULL);
1176
1181
  char doc_str[62];
1177
1182
  size_t len = strlen(query_str);
1178
1183
  char *str = ALLOC_N(char, len + 80);
@@ -1184,7 +1189,7 @@ static char *spanne_to_s(SpanEnum *self)
1184
1189
  sprintf(doc_str, "%d:%d-%d", self->doc(self),
1185
1190
  self->start(self), self->end(self));
1186
1191
  }
1187
- sprintf("SpanNearEnum(%s)@%s", query_str, doc_str);
1192
+ sprintf(str, "SpanNearEnum(%s)@%s", query_str, doc_str);
1188
1193
  free(query_str);
1189
1194
  return str;
1190
1195
  }
@@ -1206,7 +1211,7 @@ static SpanEnum *spanne_new(Query *query, IndexReader *ir)
1206
1211
  {
1207
1212
  int i;
1208
1213
  Query *clause;
1209
- SpanEnum *self = (SpanEnum *)emalloc(sizeof(SpanNearEnum));
1214
+ SpanEnum *self = (SpanEnum *)ALLOC(SpanNearEnum);
1210
1215
  SpanNearQuery *snq = SpNQ(query);
1211
1216
 
1212
1217
  SpNEn(self)->first_time = true;
@@ -1333,10 +1338,9 @@ static int spanxe_end(SpanEnum *self)
1333
1338
  return inc->end(inc);
1334
1339
  }
1335
1340
 
1336
- static char *spanxe_to_s(SpanEnum *self)
1341
+ static char *spanxe_to_s(SpanEnum *self)
1337
1342
  {
1338
- char *field = SpQ(self->query)->field;
1339
- char *query_str = self->query->to_s(self->query, field);
1343
+ char *query_str = self->query->to_s(self->query, NULL);
1340
1344
  char *res = strfmt("SpanNotEnum(%s)", query_str);
1341
1345
  free(query_str);
1342
1346
  return res;
@@ -1352,7 +1356,7 @@ static void spanxe_destroy(SpanEnum *self)
1352
1356
 
1353
1357
  static SpanEnum *spanxe_new(Query *query, IndexReader *ir)
1354
1358
  {
1355
- SpanEnum *self = (SpanEnum *)emalloc(sizeof(SpanNotEnum));
1359
+ SpanEnum *self = (SpanEnum *)ALLOC(SpanNotEnum);
1356
1360
  SpanNotEnum *sxe = SpXEn(self);
1357
1361
  SpanNotQuery *sxq = SpXQ(query);
1358
1362
 
@@ -1399,27 +1403,26 @@ static Explanation *spanw_explain(Weight *self, IndexReader *ir, int target)
1399
1403
  uchar *field_norms;
1400
1404
  float field_norm;
1401
1405
  Explanation *field_norm_expl;
1406
+ const char *field = S(SpQ(self->query)->field);
1402
1407
 
1403
1408
  char *query_str;
1404
1409
  HashSet *terms = SpW(self)->terms;
1405
- char *field = SpQ(self->query)->field;
1406
- const int field_num = fis_get_field_num(ir->fis, field);
1410
+ const int field_num = fis_get_field_num(ir->fis, SpQ(self->query)->field);
1407
1411
  char *doc_freqs = NULL;
1408
1412
  size_t df_i = 0;
1409
- int i;
1413
+ HashSetEntry *hse;
1410
1414
 
1411
1415
  if (field_num < 0) {
1412
1416
  return expl_new(0.0, "field \"%s\" does not exist in the index", field);
1413
1417
  }
1414
1418
 
1415
- query_str = self->query->to_s(self->query, "");
1419
+ query_str = self->query->to_s(self->query, NULL);
1416
1420
 
1417
- for (i = 0; i < terms->size; i++) {
1418
- char *term = (char *)terms->elems[i];
1421
+ for (hse = terms->first; hse; hse = hse->next) {
1422
+ char *term = (char *)hse->elem;
1419
1423
  REALLOC_N(doc_freqs, char, df_i + strlen(term) + 23);
1420
- sprintf(doc_freqs + df_i, "%s=%d, ", term,
1421
- ir->doc_freq(ir, field_num, term));
1422
- df_i = strlen(doc_freqs);
1424
+ df_i += sprintf(doc_freqs + df_i, "%s=%d, ", term,
1425
+ ir->doc_freq(ir, field_num, term));
1423
1426
  }
1424
1427
  /* remove the ',' at the end of the string if it exists */
1425
1428
  if (terms->size > 0) {
@@ -1468,8 +1471,8 @@ static Explanation *spanw_explain(Weight *self, IndexReader *ir, int target)
1468
1471
  expl_add_detail(field_expl, idf_expl2);
1469
1472
 
1470
1473
  field_norms = ir->get_norms(ir, field_num);
1471
- field_norm = (field_norms
1472
- ? sim_decode_norm(self->similarity, field_norms[target])
1474
+ field_norm = (field_norms
1475
+ ? sim_decode_norm(self->similarity, field_norms[target])
1473
1476
  : (float)0.0);
1474
1477
  field_norm_expl = expl_new(field_norm, "field_norm(field=%s, doc=%d)",
1475
1478
  field, target);
@@ -1502,7 +1505,7 @@ static void spanw_destroy(Weight *self)
1502
1505
 
1503
1506
  static Weight *spanw_new(Query *query, Searcher *searcher)
1504
1507
  {
1505
- int i;
1508
+ HashSetEntry *hse;
1506
1509
  Weight *self = w_new(SpanWeight, query);
1507
1510
  HashSet *terms = SpQ(query)->get_terms(query);
1508
1511
 
@@ -1515,10 +1518,10 @@ static Weight *spanw_new(Query *query, Searcher *searcher)
1515
1518
  self->similarity = query->get_similarity(query, searcher);
1516
1519
 
1517
1520
  self->idf = 0.0;
1518
-
1519
- for (i = terms->size - 1; i >= 0; i--) {
1520
- self->idf += sim_idf_term(self->similarity, SpQ(query)->field,
1521
- (char *)terms->elems[i], searcher);
1521
+
1522
+ for (hse = terms->first; hse; hse = hse->next) {
1523
+ self->idf += sim_idf_term(self->similarity, SpQ(query)->field,
1524
+ (char *)hse->elem, searcher);
1522
1525
  }
1523
1526
 
1524
1527
  return self;
@@ -1528,20 +1531,19 @@ static Weight *spanw_new(Query *query, Searcher *searcher)
1528
1531
  * SpanTermQuery
1529
1532
  *****************************************************************************/
1530
1533
 
1531
- static char *spantq_to_s(Query *self, const char *field)
1534
+ static char *spantq_to_s(Query *self, Symbol default_field)
1532
1535
  {
1533
- if (field == SpQ(self)->field) {
1536
+ if (default_field && default_field == SpQ(self)->field) {
1534
1537
  return strfmt("span_terms(%s)", SpTQ(self)->term);
1535
1538
  }
1536
1539
  else {
1537
- return strfmt("span_terms(%s:%s)", SpQ(self)->field, SpTQ(self)->term);
1540
+ return strfmt("span_terms(%s:%s)", S(SpQ(self)->field), SpTQ(self)->term);
1538
1541
  }
1539
1542
  }
1540
1543
 
1541
1544
  static void spantq_destroy_i(Query *self)
1542
1545
  {
1543
1546
  free(SpTQ(self)->term);
1544
- free(SpQ(self)->field);
1545
1547
  spanq_destroy_i(self);
1546
1548
  }
1547
1549
 
@@ -1567,12 +1569,12 @@ static int spantq_eq(Query *self, Query *o)
1567
1569
  return spanq_eq(self, o) && strcmp(SpTQ(self)->term, SpTQ(o)->term) == 0;
1568
1570
  }
1569
1571
 
1570
- Query *spantq_new(const char *field, const char *term)
1572
+ Query *spantq_new(Symbol field, const char *term)
1571
1573
  {
1572
1574
  Query *self = q_new(SpanTermQuery);
1573
1575
 
1574
1576
  SpTQ(self)->term = estrdup(term);
1575
- SpQ(self)->field = estrdup(field);
1577
+ SpQ(self)->field = field;
1576
1578
  SpQ(self)->get_spans = &spante_new;
1577
1579
  SpQ(self)->get_terms = &spantq_get_terms;
1578
1580
 
@@ -1591,10 +1593,10 @@ Query *spantq_new(const char *field, const char *term)
1591
1593
  * SpanMultiTermQuery
1592
1594
  *****************************************************************************/
1593
1595
 
1594
- static char *spanmtq_to_s(Query *self, const char *field)
1596
+ static char *spanmtq_to_s(Query *self, Symbol field)
1595
1597
  {
1596
1598
  char *terms = NULL, *p;
1597
- int len = 2, i;
1599
+ int len = 3, i;
1598
1600
  SpanMultiTermQuery *smtq = SpMTQ(self);
1599
1601
  for (i = 0; i < smtq->term_cnt; i++) {
1600
1602
  len += strlen(smtq->terms[i]) + 2;
@@ -1602,11 +1604,10 @@ static char *spanmtq_to_s(Query *self, const char *field)
1602
1604
  p = terms = ALLOC_N(char, len);
1603
1605
  *(p++) = '[';
1604
1606
  for (i = 0; i < smtq->term_cnt; i++) {
1607
+ if (i != 0) *(p++) = ',';
1605
1608
  strcpy(p, smtq->terms[i]);
1606
1609
  p += strlen(smtq->terms[i]);
1607
- *(p++) = ',';
1608
1610
  }
1609
- if (p > terms) p--;
1610
1611
  *(p++) = ']';
1611
1612
  *p = '\0';
1612
1613
 
@@ -1614,7 +1615,7 @@ static char *spanmtq_to_s(Query *self, const char *field)
1614
1615
  p = strfmt("span_terms(%s)", terms);
1615
1616
  }
1616
1617
  else {
1617
- p = strfmt("span_terms(%s:%s)", SpQ(self)->field, terms);
1618
+ p = strfmt("span_terms(%s:%s)", S(SpQ(self)->field), terms);
1618
1619
  }
1619
1620
  free(terms);
1620
1621
  return p;
@@ -1628,7 +1629,6 @@ static void spanmtq_destroy_i(Query *self)
1628
1629
  free(smtq->terms[i]);
1629
1630
  }
1630
1631
  free(smtq->terms);
1631
- free(SpQ(self)->field);
1632
1632
  spanq_destroy_i(self);
1633
1633
  }
1634
1634
 
@@ -1676,7 +1676,7 @@ static int spanmtq_eq(Query *self, Query *o)
1676
1676
  return true;;
1677
1677
  }
1678
1678
 
1679
- Query *spanmtq_new_conf(const char *field, int max_terms)
1679
+ Query *spanmtq_new_conf(Symbol field, int max_terms)
1680
1680
  {
1681
1681
  Query *self = q_new(SpanMultiTermQuery);
1682
1682
 
@@ -1684,7 +1684,7 @@ Query *spanmtq_new_conf(const char *field, int max_terms)
1684
1684
  SpMTQ(self)->term_cnt = 0;
1685
1685
  SpMTQ(self)->term_capa = max_terms;
1686
1686
 
1687
- SpQ(self)->field = estrdup(field);
1687
+ SpQ(self)->field = field;
1688
1688
  SpQ(self)->get_spans = &spanmte_new;
1689
1689
  SpQ(self)->get_terms = &spanmtq_get_terms;
1690
1690
 
@@ -1700,7 +1700,7 @@ Query *spanmtq_new_conf(const char *field, int max_terms)
1700
1700
  return self;
1701
1701
  }
1702
1702
 
1703
- Query *spanmtq_new(const char *field)
1703
+ Query *spanmtq_new(Symbol field)
1704
1704
  {
1705
1705
  return spanmtq_new_conf(field, SPAN_MULTI_TERM_QUERY_CAPA);
1706
1706
  }
@@ -1719,7 +1719,7 @@ void spanmtq_add_term(Query *self, const char *term)
1719
1719
  *
1720
1720
  *****************************************************************************/
1721
1721
 
1722
- static char *spanfq_to_s(Query *self, const char *field)
1722
+ static char *spanfq_to_s(Query *self, Symbol field)
1723
1723
  {
1724
1724
  Query *match = SpFQ(self)->match;
1725
1725
  char *q_str = match->to_s(match, field);
@@ -1755,7 +1755,6 @@ static Query *spanfq_rewrite(Query *self, IndexReader *ir)
1755
1755
  static void spanfq_destroy_i(Query *self)
1756
1756
  {
1757
1757
  q_deref(SpFQ(self)->match);
1758
- free(SpQ(self)->field);
1759
1758
  spanq_destroy_i(self);
1760
1759
  }
1761
1760
 
@@ -1780,7 +1779,7 @@ Query *spanfq_new_nr(Query *match, int end)
1780
1779
  SpFQ(self)->match = match;
1781
1780
  SpFQ(self)->end = end;
1782
1781
 
1783
- SpQ(self)->field = estrdup(SpQ(match)->field);
1782
+ SpQ(self)->field = SpQ(match)->field;
1784
1783
  SpQ(self)->get_spans = &spanfe_new;
1785
1784
  SpQ(self)->get_terms = &spanfq_get_terms;
1786
1785
 
@@ -1809,7 +1808,7 @@ Query *spanfq_new(Query *match, int end)
1809
1808
  *
1810
1809
  *****************************************************************************/
1811
1810
 
1812
- static char *spanoq_to_s(Query *self, const char *field)
1811
+ static char *spanoq_to_s(Query *self, Symbol field)
1813
1812
  {
1814
1813
  int i;
1815
1814
  SpanOrQuery *soq = SpOQ(self);
@@ -1823,16 +1822,16 @@ static char *spanoq_to_s(Query *self, const char *field)
1823
1822
  }
1824
1823
 
1825
1824
  res_p = res = ALLOC_N(char, len);
1826
- sprintf(res_p, "span_or[ ");
1827
- res_p += strlen(res_p);
1825
+ res_p += sprintf(res_p, "span_or[");
1828
1826
  for (i = 0; i < soq->c_cnt; i++) {
1829
- sprintf(res_p, "%s, ", q_strs[i]);
1827
+ if (i != 0) *(res_p++) = ',';
1828
+ res_p += sprintf(res_p, "%s", q_strs[i]);
1830
1829
  free(q_strs[i]);
1831
- res_p += strlen(res_p);
1832
1830
  }
1833
1831
  free(q_strs);
1834
1832
 
1835
- sprintf(res_p - 2, " ]");
1833
+ *(res_p)++ = ']';
1834
+ *res_p = 0;
1836
1835
  return res;
1837
1836
  }
1838
1837
 
@@ -1898,7 +1897,6 @@ static void spanoq_destroy_i(Query *self)
1898
1897
  q_deref(clause);
1899
1898
  }
1900
1899
  free(soq->clauses);
1901
- free(SpQ(self)->field);
1902
1900
 
1903
1901
  spanq_destroy_i(self);
1904
1902
  }
@@ -1942,7 +1940,7 @@ Query *spanoq_new()
1942
1940
  SpOQ(self)->clauses = ALLOC_N(Query *, CLAUSE_INIT_CAPA);
1943
1941
  SpOQ(self)->c_capa = CLAUSE_INIT_CAPA;
1944
1942
 
1945
- SpQ(self)->field = estrdup((char *)EMPTY_STRING);
1943
+ SpQ(self)->field = NULL;
1946
1944
  SpQ(self)->get_spans = &spanoq_get_spans;
1947
1945
  SpQ(self)->get_terms = &spanoq_get_terms;
1948
1946
 
@@ -1967,13 +1965,12 @@ Query *spanoq_add_clause_nr(Query *self, Query *clause)
1967
1965
  "SpanQuery.", q_get_query_name(clause->type));
1968
1966
  }
1969
1967
  if (curr_index == 0) {
1970
- free(SpQ(self)->field);
1971
- SpQ(self)->field = estrdup(SpQ(clause)->field);
1968
+ SpQ(self)->field = SpQ(clause)->field;
1972
1969
  }
1973
- else if (strcmp(SpQ(self)->field, SpQ(clause)->field) != 0) {
1970
+ else if (SpQ(self)->field != SpQ(clause)->field) {
1974
1971
  RAISE(ARG_ERROR, "All clauses in a SpanQuery must have the same field. "
1975
1972
  "Attempted to add a SpanQuery with field \"%s\" to a SpanOrQuery "
1976
- "with field \"%s\"", SpQ(clause)->field, SpQ(self)->field);
1973
+ "with field \"%s\"", S(SpQ(clause)->field), S(SpQ(self)->field));
1977
1974
  }
1978
1975
  if (curr_index >= SpOQ(self)->c_capa) {
1979
1976
  SpOQ(self)->c_capa <<= 1;
@@ -1995,7 +1992,7 @@ Query *spanoq_add_clause(Query *self, Query *clause)
1995
1992
  *
1996
1993
  *****************************************************************************/
1997
1994
 
1998
- static char *spannq_to_s(Query *self, const char *field)
1995
+ static char *spannq_to_s(Query *self, Symbol field)
1999
1996
  {
2000
1997
  int i;
2001
1998
  SpanNearQuery *snq = SpNQ(self);
@@ -2009,16 +2006,16 @@ static char *spannq_to_s(Query *self, const char *field)
2009
2006
  }
2010
2007
 
2011
2008
  res_p = res = ALLOC_N(char, len);
2012
- sprintf(res_p, "span_near[ ");
2013
- res_p += strlen(res_p);
2009
+ res_p += sprintf(res_p, "span_near[");
2014
2010
  for (i = 0; i < snq->c_cnt; i++) {
2015
- sprintf(res_p, "%s, ", q_strs[i]);
2011
+ if (i != 0) *(res_p)++ = ',';
2012
+ res_p += sprintf(res_p, "%s", q_strs[i]);
2016
2013
  free(q_strs[i]);
2017
- res_p += strlen(res_p);
2018
2014
  }
2019
2015
  free(q_strs);
2020
2016
 
2021
- sprintf(res_p - 2, " ]");
2017
+ *(res_p++) = ']';
2018
+ *res_p = 0;
2022
2019
  return res;
2023
2020
  }
2024
2021
 
@@ -2083,7 +2080,6 @@ static void spannq_destroy(Query *self)
2083
2080
  q_deref(clause);
2084
2081
  }
2085
2082
  free(snq->clauses);
2086
- free(SpQ(self)->field);
2087
2083
 
2088
2084
  spanq_destroy_i(self);
2089
2085
  }
@@ -2136,7 +2132,7 @@ Query *spannq_new(int slop, bool in_order)
2136
2132
 
2137
2133
  SpQ(self)->get_spans = &spannq_get_spans;
2138
2134
  SpQ(self)->get_terms = &spannq_get_terms;
2139
- SpQ(self)->field = estrdup((char *)EMPTY_STRING);
2135
+ SpQ(self)->field = NULL;
2140
2136
 
2141
2137
  self->type = SPAN_NEAR_QUERY;
2142
2138
  self->rewrite = &spannq_rewrite;
@@ -2159,13 +2155,12 @@ Query *spannq_add_clause_nr(Query *self, Query *clause)
2159
2155
  "SpanQuery.", q_get_query_name(clause->type));
2160
2156
  }
2161
2157
  if (curr_index == 0) {
2162
- free(SpQ(self)->field);
2163
- SpQ(self)->field = estrdup(SpQ(clause)->field);
2158
+ SpQ(self)->field = SpQ(clause)->field;
2164
2159
  }
2165
- else if (strcmp(SpQ(self)->field, SpQ(clause)->field) != 0) {
2160
+ else if (SpQ(self)->field != SpQ(clause)->field) {
2166
2161
  RAISE(ARG_ERROR, "All clauses in a SpanQuery must have the same field. "
2167
2162
  "Attempted to add a SpanQuery with field \"%s\" to SpanNearQuery "
2168
- "with field \"%s\"", SpQ(clause)->field, SpQ(self)->field);
2163
+ "with field \"%s\"", S(SpQ(clause)->field), S(SpQ(self)->field));
2169
2164
  }
2170
2165
  if (curr_index >= SpNQ(self)->c_capa) {
2171
2166
  SpNQ(self)->c_capa <<= 1;
@@ -2187,7 +2182,7 @@ Query *spannq_add_clause(Query *self, Query *clause)
2187
2182
  *
2188
2183
  *****************************************************************************/
2189
2184
 
2190
- static char *spanxq_to_s(Query *self, const char *field)
2185
+ static char *spanxq_to_s(Query *self, Symbol field)
2191
2186
  {
2192
2187
  SpanNotQuery *sxq = SpXQ(self);
2193
2188
  char *inc_s = sxq->inc->to_s(sxq->inc, field);
@@ -2237,8 +2232,6 @@ static void spanxq_destroy(Query *self)
2237
2232
  q_deref(sxq->inc);
2238
2233
  q_deref(sxq->exc);
2239
2234
 
2240
- free(SpQ(self)->field);
2241
-
2242
2235
  spanq_destroy_i(self);
2243
2236
  }
2244
2237
 
@@ -2261,18 +2254,18 @@ static int spanxq_eq(Query *self, Query *o)
2261
2254
  Query *spanxq_new_nr(Query *inc, Query *exc)
2262
2255
  {
2263
2256
  Query *self;
2264
- if (strcmp(SpQ(inc)->field, SpQ(inc)->field) != 0) {
2257
+ if (SpQ(inc)->field != SpQ(inc)->field) {
2265
2258
  RAISE(ARG_ERROR, "All clauses in a SpanQuery must have the same field. "
2266
2259
  "Attempted to add a SpanQuery with field \"%s\" along with a "
2267
2260
  "SpanQuery with field \"%s\" to an SpanNotQuery",
2268
- SpQ(inc)->field, SpQ(exc)->field);
2261
+ S(SpQ(inc)->field), S(SpQ(exc)->field));
2269
2262
  }
2270
2263
  self = q_new(SpanNotQuery);
2271
2264
 
2272
2265
  SpXQ(self)->inc = inc;
2273
2266
  SpXQ(self)->exc = exc;
2274
2267
 
2275
- SpQ(self)->field = estrdup(SpQ(inc)->field);
2268
+ SpQ(self)->field = SpQ(inc)->field;
2276
2269
  SpQ(self)->get_spans = &spanxe_new;
2277
2270
  SpQ(self)->get_terms = &spanxq_get_terms;
2278
2271
 
@@ -2311,23 +2304,21 @@ Query *spanxq_new(Query *inc, Query *exc)
2311
2304
 
2312
2305
  #define SpPfxQ(query) ((SpanPrefixQuery *)(query))
2313
2306
 
2314
- static char *spanprq_to_s(Query *self, const char *current_field)
2307
+ static char *spanprq_to_s(Query *self, Symbol default_field)
2315
2308
  {
2316
2309
  char *buffer, *bptr;
2317
2310
  const char *prefix = SpPfxQ(self)->prefix;
2318
- const char *field = SpQ(self)->field;
2311
+ Symbol field = SpQ(self)->field;
2319
2312
  size_t plen = strlen(prefix);
2320
- size_t flen = strlen(field);
2313
+ size_t flen = sym_len(field);
2321
2314
 
2322
2315
  bptr = buffer = ALLOC_N(char, plen + flen + 35);
2323
2316
 
2324
- if (strcmp(field, current_field) != 0) {
2325
- sprintf(bptr, "%s:", field);
2326
- bptr += flen + 1;
2317
+ if (default_field == NULL || (field != default_field)) {
2318
+ bptr += sprintf(bptr, "%s:", S(field));
2327
2319
  }
2328
2320
 
2329
- sprintf(bptr, "%s*", prefix);
2330
- bptr += plen + 1;
2321
+ bptr += sprintf(bptr, "%s*", prefix);
2331
2322
  if (self->boost != 1.0) {
2332
2323
  *bptr = '^';
2333
2324
  dbl_to_s(++bptr, self->boost);
@@ -2338,9 +2329,8 @@ static char *spanprq_to_s(Query *self, const char *current_field)
2338
2329
 
2339
2330
  static Query *spanprq_rewrite(Query *self, IndexReader *ir)
2340
2331
  {
2341
- const char *field = SpQ(self)->field;
2342
- const int field_num = fis_get_field_num(ir->fis, field);
2343
- Query *volatile q = spanmtq_new_conf(field, SpPfxQ(self)->max_terms);
2332
+ const int field_num = fis_get_field_num(ir->fis, SpQ(self)->field);
2333
+ Query *volatile q = spanmtq_new_conf(SpQ(self)->field, SpPfxQ(self)->max_terms);
2344
2334
  q->boost = self->boost; /* set the boost */
2345
2335
 
2346
2336
  if (field_num >= 0) {
@@ -2350,7 +2340,7 @@ static Query *spanprq_rewrite(Query *self, IndexReader *ir)
2350
2340
  size_t prefix_len = strlen(prefix);
2351
2341
 
2352
2342
  TRY
2353
- do {
2343
+ do {
2354
2344
  if (strncmp(term, prefix, prefix_len) != 0) {
2355
2345
  break;
2356
2346
  }
@@ -2366,27 +2356,26 @@ static Query *spanprq_rewrite(Query *self, IndexReader *ir)
2366
2356
 
2367
2357
  static void spanprq_destroy(Query *self)
2368
2358
  {
2369
- free(SpQ(self)->field);
2370
2359
  free(SpPfxQ(self)->prefix);
2371
2360
  spanq_destroy_i(self);
2372
2361
  }
2373
2362
 
2374
2363
  static unsigned long spanprq_hash(Query *self)
2375
2364
  {
2376
- return str_hash(SpQ(self)->field) ^ str_hash(SpPfxQ(self)->prefix);
2365
+ return sym_hash(SpQ(self)->field) ^ str_hash(SpPfxQ(self)->prefix);
2377
2366
  }
2378
2367
 
2379
2368
  static int spanprq_eq(Query *self, Query *o)
2380
2369
  {
2381
- return (strcmp(SpPfxQ(self)->prefix, SpPfxQ(o)->prefix) == 0)
2382
- && (strcmp(SpQ(self)->field, SpQ(o)->field) == 0);
2370
+ return (strcmp(SpPfxQ(self)->prefix, SpPfxQ(o)->prefix) == 0)
2371
+ && (SpQ(self)->field == SpQ(o)->field);
2383
2372
  }
2384
2373
 
2385
- Query *spanprq_new(const char *field, const char *prefix)
2374
+ Query *spanprq_new(Symbol field, const char *prefix)
2386
2375
  {
2387
2376
  Query *self = q_new(SpanPrefixQuery);
2388
2377
 
2389
- SpQ(self)->field = estrdup(field);
2378
+ SpQ(self)->field = field;
2390
2379
  SpPfxQ(self)->prefix = estrdup(prefix);
2391
2380
  SpPfxQ(self)->max_terms = SPAN_PREFIX_QUERY_MAX_TERMS;
2392
2381