IDZEBRA  2.2.7
retrieve.c
Go to the documentation of this file.
1 /* This file is part of the Zebra server.
2  Copyright (C) Index Data
3 
4 Zebra is free software; you can redistribute it and/or modify it under
5 the terms of the GNU General Public License as published by the Free
6 Software Foundation; either version 2, or (at your option) any later
7 version.
8 
9 Zebra is distributed in the hope that it will be useful, but WITHOUT ANY
10 WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 for more details.
13 
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 
18 */
19 
20 #if HAVE_CONFIG_H
21 #include <config.h>
22 #endif
23 #include <stdio.h>
24 #include <assert.h>
25 
26 #include <fcntl.h>
27 #ifdef WIN32
28 #include <io.h>
29 #include <process.h>
30 #endif
31 #if HAVE_UNISTD_H
32 #include <unistd.h>
33 #endif
34 
35 #include "index.h"
36 #include <yaz/diagbib1.h>
37 #include <yaz/snprintf.h>
38 #include <direntz.h>
39 #include <yaz/oid_db.h>
40 #include <zebra_strmap.h>
41 
42 #define MAX_SYSNOS_PER_RECORD 40
43 
44 #define ZEBRA_XML_HEADER_STR "<record xmlns=\"http://www.indexdata.com/zebra/\""
45 
48  const char *setname;
50  int score;
51  NMEM nmem;
52 };
53 
54 static int log_level_mod = 0;
55 static int log_level_set = 0;
56 
58  Record *rec,
59  struct ZebraRecStream *stream)
60 {
61  RecordAttr *recordAttr = rec_init_attr(zh->reg->zei, *rec);
62 
63  if ((*rec)->size[recInfo_storeData] > 0
64  || (*rec)->info[recInfo_filename] == 0)
65  zebra_create_stream_mem(stream, (*rec)->info[recInfo_storeData],
66  (*rec)->size[recInfo_storeData]);
67  else
68  {
69  char full_rep[1024];
70  int fd;
71 
72  if (zh->path_reg && !yaz_is_abspath((*rec)->info[recInfo_filename])){
73  strcpy(full_rep, zh->path_reg);
74  strcat(full_rep, "/");
75  strcat(full_rep, (*rec)->info[recInfo_filename]);
76  }
77  else
78  strcpy(full_rep, (*rec)->info[recInfo_filename]);
79 
80  if ((fd = open(full_rep, O_BINARY|O_RDONLY)) == -1){
81  yaz_log(YLOG_WARN|YLOG_ERRNO, "Retrieve fail; missing file: %s",
82  full_rep);
83  rec_free(rec);
84  return YAZ_BIB1_SYSTEM_ERROR_IN_PRESENTING_RECORDS;
85  }
86  zebra_create_stream_fd(stream, fd, recordAttr->recordOffset);
87  }
88  return 0;
89 }
90 
91 
92 struct index_spec {
93  const char *index_name;
94  const char *index_type;
95  const char *extra;
96  struct index_spec *next;
97 };
98 
99 
100 struct index_spec *parse_index_spec(const char *elem, NMEM nmem,
101  int *error)
102 {
103  struct index_spec *first = 0;
104  struct index_spec **last = &first;
105  const char *cp = elem;
106 
107  *error = 0;
108  if (cp[0] == ':' && cp[1] == ':')
109  {
110 
111  cp++; /* skip first ':' */
112 
113  for (;;)
114  {
115  const char *cp0;
116  struct index_spec *spec = nmem_malloc(nmem, sizeof(*spec));
117  spec->index_type = 0;
118  spec->next = 0;
119  spec->extra = 0;
120 
121  if (!first)
122  first = spec;
123  *last = spec;
124  last = &spec->next;
125 
126  cp++; /* skip ',' or second ':' */
127  cp0 = cp;
128  while (*cp != ':' && *cp != '\0' && *cp != ',')
129  cp++;
130  spec->index_name = nmem_strdupn(nmem, cp0, cp - cp0);
131  if (*cp == ':') /* type as well */
132  {
133  cp++;
134  cp0 = cp;
135 
136  while (*cp != '\0' && *cp != ',' && *cp != ':')
137  cp++;
138  spec->index_type = nmem_strdupn(nmem, cp0, cp - cp0);
139  }
140  if (*cp == ':') /* extra arguments */
141  {
142  cp++;
143  cp0 = cp;
144 
145  while (*cp != '\0' && *cp != ',' && *cp != ':')
146  cp++;
147  spec->extra = nmem_strdupn(nmem, cp0, cp - cp0);
148  }
149  if (*cp != ',')
150  break;
151  }
152  }
153  if (*cp != '\0')
154  *error = 1;
155  return first;
156 }
157 
158 static int sort_fetch(
159  struct special_fetch_s *fi, const char *elemsetname,
160  const Odr_oid *input_format,
161  const Odr_oid **output_format,
162  WRBUF result, WRBUF addinfo)
163 {
164  int ord;
165  ZebraHandle zh = fi->zh;
166  int error;
167  struct index_spec *spec;
168 
169  spec = parse_index_spec(elemsetname, fi->nmem, &error);
170  if (error)
171  return YAZ_BIB1_SPECIFIED_ELEMENT_SET_NAME_NOT_VALID_FOR_SPECIFIED_;
172 
173  /* for sort fetches.. We allow only one index and type must be given */
174  if (!spec || spec->next || !spec->index_type)
175  return -1;
178  spec->index_type,
179  spec->index_name);
180  if (ord == -1)
181  return -1; /* is not a sort index */
182  else
183  {
184  WRBUF wrbuf_str = wrbuf_alloc();
185  const char *index_type;
186  const char *db = 0;
187  const char *string_index = 0;
188  WRBUF wrbuf_result = result;
189  int off = 0;
190 
191  zebraExplain_lookup_ord(zh->reg->zei, ord, &index_type, &db,
192  &string_index);
193  if (!oid_oidcmp(input_format, yaz_oid_recsyn_xml))
194  {
195  *output_format = yaz_oid_recsyn_xml;
196  wrbuf_printf(wrbuf_result, ZEBRA_XML_HEADER_STR
197  " sysno=\"" ZINT_FORMAT "\""
198  " set=\"zebra::index%s\">\n",
199  fi->sysno, elemsetname);
200  }
201  else if (!oid_oidcmp(input_format, yaz_oid_recsyn_sutrs))
202  {
203  *output_format = yaz_oid_recsyn_sutrs;
204  }
205  else
206  {
207  yaz_log(YLOG_WARN, "unsupported format for element set zebra::%s",
208  elemsetname);
209  *output_format = 0;
210  wrbuf_destroy(wrbuf_str);
211  return YAZ_BIB1_NO_SYNTAXES_AVAILABLE_FOR_THIS_REQUEST;
212  }
213  zebra_sort_type(zh->reg->sort_index, ord);
215  zebra_sort_read(zh->reg->sort_index, 0, wrbuf_str);
216 
217  while (off != wrbuf_len(wrbuf_str))
218  {
219  char dst_buf[IT_MAX_WORD];
220  assert(off < wrbuf_len(wrbuf_str));
221  zebra_term_untrans(zh, index_type, dst_buf,
222  wrbuf_buf(wrbuf_str)+off);
223 
224  if (!oid_oidcmp(input_format, yaz_oid_recsyn_xml))
225  {
226  wrbuf_printf(wrbuf_result, " <index name=\"%s\"",
227  string_index);
228  wrbuf_printf(wrbuf_result, " type=\"%s\">", index_type);
229  wrbuf_xmlputs(wrbuf_result, dst_buf);
230  wrbuf_printf(wrbuf_result, "</index>\n");
231  }
232  else if (!oid_oidcmp(input_format, yaz_oid_recsyn_sutrs))
233  {
234  wrbuf_printf(wrbuf_result, "%s %s %s\n", string_index, index_type,
235  dst_buf);
236  }
237  off += strlen(wrbuf_buf(wrbuf_str)+off) + 1;
238  }
239  if (!oid_oidcmp(input_format, yaz_oid_recsyn_xml))
240  {
241  wrbuf_printf(wrbuf_result, "</record>\n");
242  }
243  wrbuf_destroy(wrbuf_str);
244  return 0;
245  }
246 }
247 
248 static void special_index_xml_record(ZebraHandle zh, WRBUF wrbuf,
249  zebra_snippets *doc, zint sysno,
250  struct index_spec *spec_list,
251  const char *elemsetname, int use_xml)
252 {
253  const zebra_snippet_word *doc_w;
254  if (use_xml)
255  wrbuf_printf(wrbuf, "%s sysno=\"" ZINT_FORMAT
256  "\" set=\"zebra::index%s\">\n",
257  ZEBRA_XML_HEADER_STR, sysno, elemsetname);
258  for (doc_w = zebra_snippets_constlist(doc); doc_w; doc_w = doc_w->next)
259  {
260  const char *index_type;
261  const char *db = 0;
262  const char *string_index = 0;
263 
264  zebraExplain_lookup_ord(zh->reg->zei, doc_w->ord,
265  &index_type, &db, &string_index);
266  int match = 1;
267  if (spec_list)
268  {
269  match = 0;
270  struct index_spec *spec;
271  for (spec = spec_list; spec; spec = spec->next)
272  {
273  if ((!spec->index_type ||
274  !yaz_matchstr(spec->index_type, index_type))
275  &&
276  !yaz_matchstr(spec->index_name, string_index))
277  match = 1;
278  }
279  }
280  if (match)
281  {
282  if (use_xml)
283  {
284  wrbuf_printf(wrbuf, " <index name=\"%s\"", string_index);
285  wrbuf_printf(wrbuf, " type=\"%s\"", index_type);
286  wrbuf_printf(wrbuf, " seq=\"" ZINT_FORMAT "\">",
287  doc_w->seqno);
288  wrbuf_xmlputs(wrbuf, doc_w->term);
289  wrbuf_printf(wrbuf, "</index>\n");
290  }
291  else
292  {
293  wrbuf_printf(wrbuf, "%s %s %s\n", string_index,
294  index_type, doc_w->term);
295  }
296  }
297  }
298  if (use_xml)
299  wrbuf_printf(wrbuf, "</record>\n");
300 }
301 
302 
304  struct special_fetch_s *fi, const char *elemsetname,
305  const Odr_oid *input_format,
306  const Odr_oid **output_format,
307  WRBUF result, WRBUF addinfo,
308  Record rec)
309 {
310  ZebraHandle zh = fi->zh;
311  struct index_spec *spec, *spec_list;
312  int error;
313 
314  /* set output variables before processing possible error states */
315  /* *rec_lenp = 0; */
316 
317  /* only accept XML and SUTRS requests */
318  if (oid_oidcmp(input_format, yaz_oid_recsyn_xml)
319  && oid_oidcmp(input_format, yaz_oid_recsyn_sutrs))
320  {
321  yaz_log(YLOG_WARN, "unsupported format for element set zebra::%s",
322  elemsetname);
323  *output_format = 0;
324  return YAZ_BIB1_NO_SYNTAXES_AVAILABLE_FOR_THIS_REQUEST;
325  }
326 
327  spec_list = parse_index_spec(elemsetname, fi->nmem, &error);
328  if (error)
329  {
330  return YAZ_BIB1_SPECIFIED_ELEMENT_SET_NAME_NOT_VALID_FOR_SPECIFIED_;
331  }
332 
333  for (spec = spec_list; spec; spec = spec->next)
334  {
337  spec->index_type,
338  spec->index_name) == -1)
339  return YAZ_BIB1_SPECIFIED_ELEMENT_SET_NAME_NOT_VALID_FOR_SPECIFIED_;
340  }
341  zebra_snippets *rec_snippets = zebra_snippets_create();
342  int return_code = zebra_get_rec_snippets(zh, fi->sysno, rec_snippets);
343  if (return_code == 0)
344  {
345  special_index_xml_record(zh, result, rec_snippets, fi->sysno, spec_list,
346  elemsetname, !oid_oidcmp(input_format, yaz_oid_recsyn_xml));
347  *output_format = input_format;
348  }
349  zebra_snippets_destroy(rec_snippets);
350  return return_code;
351 }
352 
353 
354 static void retrieve_puts_attr(WRBUF wrbuf, const char *name,
355  const char *value)
356 {
357  if (value)
358  {
359  wrbuf_printf(wrbuf, " %s=\"", name);
360  wrbuf_xmlputs(wrbuf, value);
361  wrbuf_printf(wrbuf, "\"");
362  }
363 }
364 
365 static void retrieve_puts_attr_int(WRBUF wrbuf, const char *name,
366  const int value)
367 {
368  wrbuf_printf(wrbuf, " %s=\"%i\"", name, value);
369 }
370 
371 static void retrieve_puts_str(WRBUF wrbuf, const char *name,
372  const char *value)
373 {
374  if (value)
375  wrbuf_printf(wrbuf, "%s %s\n", name, value);
376 }
377 
378 static void retrieve_puts_int(WRBUF wrbuf, const char *name,
379  const int value)
380 {
381  wrbuf_printf(wrbuf, "%s %i\n", name, value);
382 }
383 
384 
385 static void snippet_check_fields(ZebraHandle zh, WRBUF wrbuf,
386  zebra_snippets *doc,
387  const zebra_snippet_word *doc_w,
388  const char *w_index_type)
389 {
390  /* beginning of snippet. See which fields the snippet also
391  occur */
392  const zebra_snippet_word *w;
393  int no = 0;
394  for (w = zebra_snippets_constlist(doc); w; w = w->next)
395  {
396  /* same sequence but other field? */
397  if (w->seqno == doc_w->seqno && w->ord != doc_w->ord)
398  {
399  const char *index_type;
400  const char *db = 0;
401  const char *string_index = 0;
402 
404  &index_type, &db, &string_index);
405  /* only report for same index type */
406  if (!strcmp(w_index_type, index_type))
407  {
408  if (no == 0)
409  wrbuf_printf(wrbuf, " fields=\"%s", string_index);
410  else
411  wrbuf_printf(wrbuf, " %s", string_index);
412  no++;
413  }
414  }
415  }
416  if (no)
417  wrbuf_printf(wrbuf, "\"");
418 }
419 
420 static void snippet_xml_record(ZebraHandle zh, WRBUF wrbuf, zebra_snippets *doc)
421 {
422  const zebra_snippet_word *doc_w;
423  int mark_state = 0;
424 
425  wrbuf_printf(wrbuf, "%s>\n", ZEBRA_XML_HEADER_STR);
426  for (doc_w = zebra_snippets_constlist(doc); doc_w; doc_w = doc_w->next)
427  {
428  if (doc_w->mark)
429  {
430  const char *index_type;
431  const char *db = 0;
432  const char *string_index = 0;
433 
434  zebraExplain_lookup_ord(zh->reg->zei, doc_w->ord,
435  &index_type, &db, &string_index);
436 
437  if (mark_state == 0)
438  {
439  wrbuf_printf(wrbuf, " <snippet name=\"%s\"", string_index);
440  wrbuf_printf(wrbuf, " type=\"%s\"", index_type);
441  snippet_check_fields(zh, wrbuf, doc, doc_w, index_type);
442  wrbuf_printf(wrbuf, ">");
443  }
444  if (doc_w->match)
445  wrbuf_puts(wrbuf, "<s>");
446  /* not printing leading ws */
447  if (mark_state || !doc_w->ws || doc_w->match)
448  wrbuf_xmlputs(wrbuf, doc_w->term);
449  if (doc_w->match)
450  wrbuf_puts(wrbuf, "</s>");
451  }
452  else if (mark_state == 1)
453  {
454  wrbuf_puts(wrbuf, "</snippet>\n");
455  }
456  mark_state = doc_w->mark;
457  }
458  if (mark_state == 1)
459  {
460  wrbuf_puts(wrbuf, "</snippet>\n");
461  }
462  wrbuf_printf(wrbuf, "</record>");
463 }
464 
466  zebra_snippets *snippets)
467 {
468  int return_code = 0;
469  Record rec;
470 
471  if (!log_level_set)
472  {
473  log_level_mod = yaz_log_module_level("retrieve");
474  log_level_set = 1;
475  }
476  rec = rec_get(zh->reg->records, sysno);
477  if (!rec)
478  {
479  yaz_log(YLOG_WARN, "rec_get fail on sysno=" ZINT_FORMAT, sysno);
480  return_code = YAZ_BIB1_SYSTEM_ERROR_IN_PRESENTING_RECORDS;
481  }
482  else
483  {
484  const char *file_type = rec->info[recInfo_fileType];
485  void *recTypeClientData;
486  RecType rt = recType_byName(zh->reg->recTypes, zh->res,
487  file_type, &recTypeClientData);
488 
489  if (!rt)
490  return_code = YAZ_BIB1_SYSTEM_ERROR_IN_PRESENTING_RECORDS;
491  else
492  {
493  struct ZebraRecStream stream;
494  return_code = zebra_create_record_stream(zh, &rec, &stream);
495  if (return_code == 0)
496  {
497  extract_snippet(zh, snippets, &stream,
498  rt, recTypeClientData);
499 
500  stream.destroy(&stream);
501  }
502  }
503  rec_free(&rec);
504  }
505  return return_code;
506 }
507 
508 static int snippet_fetch(
509  struct special_fetch_s *fi, const char *elemsetname,
510  const Odr_oid *input_format,
511  const Odr_oid **output_format,
512  WRBUF result, WRBUF addinfo)
513 {
514  ZebraHandle zh = fi->zh;
515  zebra_snippets *rec_snippets = zebra_snippets_create();
516  int return_code = zebra_get_rec_snippets(zh, fi->sysno, rec_snippets);
517 
518  if (!return_code)
519  {
520  WRBUF wrbuf = result;
521  zebra_snippets *hit_snippet = zebra_snippets_create();
522 
523  zebra_snippets_hit_vector(zh, fi->setname, fi->sysno, hit_snippet);
524 
525  if (log_level_mod)
526  {
527  /* for debugging purposes */
528  yaz_log(log_level_mod, "---------------------------");
529  yaz_log(log_level_mod, "REC SNIPPET:");
530  zebra_snippets_log(rec_snippets, log_level_mod, 1);
531  yaz_log(log_level_mod, "---------------------------");
532  yaz_log(log_level_mod, "HIT SNIPPET:");
533  zebra_snippets_log(hit_snippet, log_level_mod, 1);
534  }
535 
536  zebra_snippets_ring(rec_snippets, hit_snippet, 5, 5);
537 
538  if (log_level_mod)
539  {
540  yaz_log(log_level_mod, "---------------------------");
541  yaz_log(log_level_mod, "RING SNIPPET:");
542  zebra_snippets_log(rec_snippets, log_level_mod, 1);
543  }
544  snippet_xml_record(zh, wrbuf, rec_snippets);
545 
546  *output_format = yaz_oid_recsyn_xml;
547 
548  zebra_snippets_destroy(hit_snippet);
549  }
550  zebra_snippets_destroy(rec_snippets);
551  return return_code;
552 }
553 
554 struct term_collect {
555  const char *term;
556  int oc;
560 };
561 
562 static zint freq_term(ZebraHandle zh, int ord, const char *term, RSET rset_set,
563  zint *first_sysno, zint *first_seq)
564 {
566  char ord_buf[IT_MAX_WORD];
567  int ord_len = key_SU_encode(ord, ord_buf);
568  char *info;
569  zint hits = 0;
570  NMEM nmem = nmem_create();
571 
572  strcpy(ord_buf + ord_len, term);
573 
574  info = dict_lookup(zh->reg->dict, ord_buf);
575  if (info)
576  {
577  ISAM_P isam_p;
578  RSET rsets[2], rset;
579  memcpy(&isam_p, info+1, sizeof(ISAM_P));
580  TERMID termid_key = rset_term_create("", -1,
581  0 /* flags */,
582  Z_Term_general /* type */,
583  nmem,
584  0, /* ord_list */
585  0, /* reg_type */
586  10000, /* hits_limit */
587  0 /* ref_id */);
588 
589  rsets[0] = zebra_create_rset_isam(zh, nmem, kc, kc->scope, isam_p,
590  termid_key);
591  rsets[1] = rset_dup(rset_set);
592 
593  rset = rset_create_and(nmem, kc, kc->scope, 2, rsets);
594 
595  zebra_count_set(zh, rset, &hits, zh->approx_limit);
596  RSFD rfd = rset_open(rset, RSETF_READ);
597  TERMID termid;
598  struct it_key key;
599  while (rset_read(rfd, &key, &termid))
600  {
601  if (termid == termid_key)
602  {
603  *first_sysno = key.mem[0];
604  *first_seq = key.mem[key.len - 1];
605  break;
606  }
607  }
608  rset_close(rfd);
609  rset_delete(rsets[0]);
610  rset_delete(rset);
611  }
612  (*kc->dec)(kc);
613  nmem_destroy(nmem);
614  return hits;
615 }
616 
617 static int term_qsort_handle(const void *a, const void *b)
618 {
619  const struct term_collect *l = a;
620  const struct term_collect *r = b;
621  if (l->set_occur < r->set_occur)
622  return 1;
623  else if (l->set_occur > r->set_occur)
624  return -1;
625  else
626  {
627  const char *lterm = l->term ? l->term : "";
628  const char *rterm = r->term ? r->term : "";
629  return strcmp(lterm, rterm);
630  }
631 }
632 
634  struct term_collect *col, int no_terms_collect,
635  int ord, RSET rset, double scale_factor)
636 {
637  int i;
638  for (i = 0; i < no_terms_collect; i++)
639  {
640  if (col[i].term)
641  {
642  if (scale_factor < 0.0)
643  {
644  col[i].set_occur = freq_term(zh, ord, col[i].term, rset,
645  &col[i].first_sysno,
646  &col[i].first_seqno);
647  }
648  else
649  col[i].set_occur = scale_factor * col[i].oc;
650  }
651  }
652  qsort(col, no_terms_collect, sizeof(*col), term_qsort_handle);
653 }
654 
656  int no_terms_collect,
657  NMEM nmem)
658 {
659  const char *term;
660  void *data_buf;
661  size_t data_len;
662  zebra_strmap_it it;
663  struct term_collect *col = nmem_malloc(nmem,
664  sizeof *col *no_terms_collect);
665  int i;
666  for (i = 0; i < no_terms_collect; i++)
667  {
668  col[i].term = 0;
669  col[i].oc = 0;
670  col[i].set_occur = 0;
671  col[i].first_sysno = col[i].first_seqno = 0;
672  }
673  /* iterate over terms and collect the most frequent ones */
674  it = zebra_strmap_it_create(sm);
675  while ((term = zebra_strmap_it_next(it, &data_buf, &data_len)))
676  {
677  /* invariant:
678  col[0] has lowest oc . col[no_terms_collect-1] has highest oc */
679  int oc = *(int*) data_buf;
680  int j = 0;
681  /* insertion may be slow but terms terms will be "infrequent" and
682  thus number of iterations should be small below
683  */
684  while (j < no_terms_collect && oc > col[j].oc)
685  j++;
686  if (j)
687  { /* oc <= col[j] and oc > col[j-1] */
688  --j;
689  memmove(col, col+1, sizeof(*col) * j);
690  col[j].term = term;
691  col[j].oc = oc;
692  }
693  }
695  return col;
696 }
697 
698 static int perform_facet_sort(ZebraHandle zh, int no_ord, int *ord_array,
699  zebra_strmap_t *map_array,
700  int num_recs, ZebraMetaRecord *poset)
701 {
702  int rec_i;
703  WRBUF w = wrbuf_alloc();
704  int ord_i;
705 
706  for (ord_i = 0; ord_i < no_ord; ord_i++)
707  {
708  for (rec_i = 0; rec_i < num_recs; rec_i++)
709  {
710  if (!poset[rec_i].sysno)
711  continue;
712 
713  zebra_sort_sysno(zh->reg->sort_index, poset[rec_i].sysno);
714  zebra_sort_type(zh->reg->sort_index, ord_array[ord_i]);
715 
716  wrbuf_rewind(w);
717  if (zebra_sort_read(zh->reg->sort_index, 0, w))
718  {
719  zebra_strmap_t sm = map_array[ord_i];
720  int off = 0;
721  while (off != wrbuf_len(w))
722  {
723  const char *str = wrbuf_buf(w) + off;
724  int *freq = zebra_strmap_lookup(sm, str, 0, 0);
725  if (freq)
726  (*freq)++;
727  else
728  {
729  int v = 1;
730  zebra_strmap_add(sm, str, &v, sizeof v);
731  }
732  off += strlen(str)+1;
733  }
734  }
735  }
736  }
737  wrbuf_destroy(w);
738  return 0;
739 }
740 
741 
743  struct special_fetch_s *fi,
744  int no_ord, int *ord_array,
745  zebra_strmap_t *map_array,
746  int num_recs, ZebraMetaRecord *poset,
747  struct index_spec *spec_list)
748 {
749  int max_chunks = 2;
750  int rec_i;
751  res_get_int(zh->res, "facetMaxChunks", &max_chunks);
752 
753  for (rec_i = 0; rec_i < num_recs; rec_i++)
754  {
755  int j;
756  zint sysnos[MAX_SYSNOS_PER_RECORD];
757  int no_sysnos = MAX_SYSNOS_PER_RECORD;
758  if (!poset[rec_i].sysno)
759  continue;
761  poset[rec_i].sysno,
762  sysnos, &no_sysnos);
763  assert(no_sysnos > 0);
764  yaz_log(YLOG_DEBUG, "Analyzing rec=%d ISAM sysno=" ZINT_FORMAT " chunks=%d",
765  rec_i, poset[rec_i].sysno, no_sysnos);
766  for (j = 0; j < no_sysnos && j < max_chunks; j++)
767  {
768  size_t slen;
769  const char *str;
770  struct it_key key_in;
771  Record rec = rec_get(zh->reg->records, sysnos[j]);
773  zebra_rec_keys_set_buf(keys, rec->info[recInfo_delKeys],
774  rec->size[recInfo_delKeys], 0);
775 
776  yaz_log(YLOG_DEBUG, "rec %d " ZINT_FORMAT " %s",
777  j, sysnos[j], zebra_rec_keys_empty(keys) ? "empty" : "non-empty");
778  if (zebra_rec_keys_rewind(keys))
779  {
780  while (zebra_rec_keys_read(keys, &str, &slen, &key_in))
781  {
782  int ord_i;
783  struct index_spec *spec;
784  for (spec = spec_list, ord_i = 0; ord_i < no_ord;
785  ord_i++, spec = spec->next)
786  {
787  int ord = CAST_ZINT_TO_INT(key_in.mem[0]);
788  if (ord == ord_array[ord_i] &&
789  str[0] != FIRST_IN_FIELD_CHAR)
790  {
791  int *freq;
792  zebra_strmap_t sm = map_array[ord_i];
793 
794  freq = zebra_strmap_lookup(sm, str, 0, 0);
795  if (freq)
796  (*freq)++;
797  else
798  {
799  int v = 1;
800  zebra_strmap_add(sm, str, &v, sizeof v);
801  }
802  }
803  }
804  }
805  }
806  zebra_rec_keys_close(keys);
807  rec_free(&rec);
808  }
809  }
810  return 0;
811 }
812 
814  struct special_fetch_s *fi,
815  WRBUF result,
816  int num_recs, ZebraMetaRecord *poset,
817  struct index_spec *spec_list,
818  int no_ord, int *ord_array,
819  int use_xml,
821 {
822  int i;
823  int ret = 0;
824  WRBUF wr = result;
825  struct index_spec *spec;
826  yaz_timing_t timing = yaz_timing_create();
827  zebra_strmap_t *map_array
828  = nmem_malloc(fi->nmem, sizeof *map_array * no_ord);
829  for (i = 0; i < no_ord; i++)
830  map_array[i] = zebra_strmap_create();
831 
832  if (cat == zinfo_index_category_sort)
833  perform_facet_sort(zh, no_ord, ord_array, map_array,
834  num_recs, poset);
835  else
836  perform_facet_index(zh, fi, no_ord, ord_array, map_array,
837  num_recs, poset, spec_list);
838  yaz_timing_stop(timing);
839  yaz_log(YLOG_LOG, "facet first phase real=%4.2f cat=%s",
840  yaz_timing_get_real(timing),
841  (cat == zinfo_index_category_sort) ? "sort" : "index");
842  yaz_timing_start(timing);
843  for (spec = spec_list, i = 0; i < no_ord; i++, spec = spec->next)
844  {
845  int j;
846  NMEM nmem = nmem_create();
847  struct term_collect *col;
848  int no_collect_terms = 20;
849 
850  if (spec->extra)
851  no_collect_terms = atoi(spec->extra);
852  if (no_collect_terms < 1)
853  no_collect_terms = 1;
854  col = term_collect_create(map_array[i], no_collect_terms, nmem);
855  term_collect_freq(zh, col, no_collect_terms, ord_array[i],
856  resultSetRef(zh, fi->setname),
857  cat == zinfo_index_category_sort ? 1.0 : -1.0);
858 
859  if (use_xml)
860  wrbuf_printf(wr, " <facet type=\"%s\" index=\"%s\">\n",
861  spec->index_type, spec->index_name);
862  else
863  wrbuf_printf(wr, "facet %s %s\n",
864  spec->index_type, spec->index_name);
865  for (j = 0; j < no_collect_terms; j++)
866  {
867  if (col[j].term)
868  {
869  WRBUF w_buf = wrbuf_alloc();
870  yaz_log(log_level_mod, "facet %s %s",
871  spec->index_type, spec->index_name);
872  if (col[j].first_sysno)
873  {
874  zebra_snippets *rec_snippets = zebra_snippets_create();
875  int code = zebra_get_rec_snippets(
876  zh, col[j].first_sysno, rec_snippets);
877  yaz_log(log_level_mod, "sysno/seqno "
879  col[j].first_sysno, col[j].first_seqno);
880  if (code == 0)
881  {
882  if (log_level_mod)
883  zebra_snippets_log(rec_snippets,
884  log_level_mod, 1);
885  const zebra_snippet_word *sn =
886  zebra_snippets_constlist(rec_snippets);
887  int first = 1; /* ignore leading whitespace */
888  for (; sn; sn = sn->next)
889  {
890  if (sn->ord == ord_array[i] &&
891  sn->seqno == col[j].first_seqno)
892  {
893  if (!sn->ws || !first)
894  {
895  first = 0;
896  wrbuf_puts(w_buf, sn->term);
897  }
898  }
899  }
900  }
901  zebra_snippets_destroy(rec_snippets);
902  }
903  char *dst_buf = 0;
904  if (wrbuf_len(w_buf))
905  zebra_term_untrans_iconv2(zh, nmem, &dst_buf, wrbuf_cstr(w_buf));
906  else
907  zebra_term_untrans_iconv(zh, nmem, spec->index_type, &dst_buf,
908  col[j].term);
909  if (use_xml)
910  {
911  wrbuf_printf(wr, " <term coccur=\"%d\"", col[j].oc);
912  if (col[j].set_occur)
913  wrbuf_printf(wr, " occur=\"" ZINT_FORMAT "\"",
914  col[j].set_occur);
915  wrbuf_printf(wr, ">");
916  wrbuf_xmlputs(wr, dst_buf);
917  wrbuf_printf(wr, "</term>\n");
918  }
919  else
920  {
921  wrbuf_printf(wr, "term %d", col[j].oc);
922  if (col[j].set_occur)
923  wrbuf_printf(wr, " " ZINT_FORMAT,
924  col[j].set_occur);
925  wrbuf_printf(wr, ": %s\n", dst_buf);
926  }
927  wrbuf_destroy(w_buf);
928  }
929  }
930  if (use_xml)
931  wrbuf_puts(wr, " </facet>\n");
932  nmem_destroy(nmem);
933  }
934  for (i = 0; i < no_ord; i++)
935  zebra_strmap_destroy(map_array[i]);
936  yaz_timing_stop(timing);
937  yaz_log(YLOG_LOG, "facet second phase real=%4.2f",
938  yaz_timing_get_real(timing));
939  yaz_timing_destroy(&timing);
940  return ret;
941 }
942 
943 static int facet_fetch(
944  struct special_fetch_s *fi, const char *elemsetname,
945  const Odr_oid *input_format,
946  const Odr_oid **output_format,
947  WRBUF result, WRBUF addinfo)
948 {
949  zint *pos_array;
950  int i;
951  int num_recs = 10; /* number of records to analyze */
952  ZebraMetaRecord *poset;
953  ZEBRA_RES ret = ZEBRA_OK;
954  int *ord_array;
955  int use_xml = 0;
956  int no_ord = 0;
957  struct index_spec *spec, *spec_list;
958  int error;
959  ZebraHandle zh = fi->zh;
960  /* whether sort or index based */
962 
963  /* see if XML is required for response */
964  if (oid_oidcmp(input_format, yaz_oid_recsyn_xml) == 0)
965  use_xml = 1;
966 
967  spec_list = parse_index_spec(elemsetname, fi->nmem, &error);
968 
969  if (!spec_list || error)
970  {
971  return YAZ_BIB1_SPECIFIED_ELEMENT_SET_NAME_NOT_VALID_FOR_SPECIFIED_;
972  }
973 
974  for (spec = spec_list; spec; spec = spec->next)
975  {
976  if (!spec->index_type)
977  return YAZ_BIB1_SPECIFIED_ELEMENT_SET_NAME_NOT_VALID_FOR_SPECIFIED_;
978  no_ord++;
979  }
980 
981  /* try to see if all specs are sort based.. If not, try the
982  index based ones */
983  ord_array = nmem_malloc(fi->nmem, sizeof(*ord_array) * no_ord);
984 
985  for (spec = spec_list, i = 0; spec; spec = spec->next, i++)
986  {
987  int ord = zebraExplain_lookup_attr_str(zh->reg->zei,
989  spec->index_type,
990  spec->index_name);
991  if (ord == -1)
992  break;
993  ord_array[i] = ord;
994  num_recs = 10000;
995  }
996  if (spec)
997  {
999  for (spec = spec_list, i = 0; spec; spec = spec->next, i++)
1000  {
1001  int ord = zebraExplain_lookup_attr_str(zh->reg->zei,
1003  spec->index_type,
1004  spec->index_name);
1005  if (ord == -1)
1006  break;
1007  ord_array[i] = ord;
1008 
1009  }
1010  }
1011  if (spec)
1012  return YAZ_BIB1_SPECIFIED_ELEMENT_SET_NAME_NOT_VALID_FOR_SPECIFIED_;
1013 
1014  res_get_int(zh->res, "facetNumRecs", &num_recs);
1015 
1016  pos_array = (zint *) nmem_malloc(fi->nmem, num_recs * sizeof(*pos_array));
1017  for (i = 0; i < num_recs; i++)
1018  pos_array[i] = i+1;
1019  poset = zebra_meta_records_create(zh, fi->setname, num_recs, pos_array);
1020  if (!poset)
1021  {
1022  wrbuf_puts(addinfo, fi->setname);
1023  return YAZ_BIB1_SPECIFIED_RESULT_SET_DOES_NOT_EXIST;
1024  }
1025  else
1026  {
1027  if (use_xml)
1028  {
1029  wrbuf_printf(result, ZEBRA_XML_HEADER_STR ">\n");
1030  }
1031  ret = perform_facet(zh, fi, result, num_recs, poset,
1032  spec_list, no_ord, ord_array, use_xml,
1033  cat);
1034  if (use_xml)
1035  wrbuf_puts(result, "</record>\n");
1036  }
1037  *output_format = yaz_oid_recsyn_xml;
1038  zebra_meta_records_destroy(zh, poset, num_recs);
1039  return ret;
1040 }
1041 
1042 
1044  void *handle, const char *elemsetname,
1045  const Odr_oid *input_format,
1046  const Odr_oid **output_format,
1047  WRBUF result, WRBUF addinfo)
1048 {
1049  Record rec = 0;
1050  struct special_fetch_s *fi = (struct special_fetch_s *) handle;
1051  ZebraHandle zh = fi->zh;
1052  zint sysno = fi->sysno;
1053 
1054  /* processing zebra::facet */
1055  if (elemsetname && 0 == strncmp(elemsetname, "facet", 5))
1056  {
1057  return facet_fetch(fi, elemsetname + 5,
1058  input_format, output_format,
1059  result, addinfo);
1060  }
1061 
1062  if (elemsetname && 0 == strcmp(elemsetname, "snippet"))
1063  {
1064  return snippet_fetch(fi, elemsetname + 7,
1065  input_format, output_format,
1066  result, addinfo);
1067  }
1068 
1069  /* processing zebra::meta::sysno */
1070  if (elemsetname && 0 == strcmp(elemsetname, "meta::sysno"))
1071  {
1072  int ret = 0;
1073  if (!oid_oidcmp(input_format, yaz_oid_recsyn_sutrs))
1074  {
1075  wrbuf_printf(result, ZINT_FORMAT, fi->sysno);
1076  *output_format = input_format;
1077  }
1078  else if (!oid_oidcmp(input_format, yaz_oid_recsyn_xml))
1079  {
1080  wrbuf_printf(result, ZEBRA_XML_HEADER_STR
1081  " sysno=\"" ZINT_FORMAT "\"/>\n",
1082  fi->sysno);
1083  *output_format = input_format;
1084  }
1085  else
1086  ret = YAZ_BIB1_NO_SYNTAXES_AVAILABLE_FOR_THIS_REQUEST;
1087  return ret;
1088  }
1089 
1090  /* processing special elementsetname zebra::index:: for sort elements */
1091  if (elemsetname && 0 == strncmp(elemsetname, "index", 5))
1092  {
1093  int ret = sort_fetch(
1094  fi, elemsetname + 5,
1095  input_format, output_format,
1096  result, addinfo);
1097  if (ret != -1)
1098  return ret;
1099  /* not a sort index so we continue to get the full record */
1100  }
1101 
1102 
1103  /* fetching binary record up for all other display elementsets */
1104  rec = rec_get(zh->reg->records, sysno);
1105  if (!rec)
1106  {
1107  yaz_log(YLOG_WARN, "rec_get fail on sysno=" ZINT_FORMAT, sysno);
1108  return YAZ_BIB1_SYSTEM_ERROR_IN_PRESENTING_RECORDS;
1109  }
1110 
1111  /* processing special elementsetnames zebra::data */
1112  if (elemsetname && 0 == strcmp(elemsetname, "data"))
1113  {
1114  struct ZebraRecStream stream;
1115  RecordAttr *recordAttr = rec_init_attr(zh->reg->zei, rec);
1116  char *b;
1117 
1118  zebra_create_record_stream(zh, &rec, &stream);
1119  *output_format = input_format;
1120 
1121  b = nmem_malloc(fi->nmem, recordAttr->recordSize);
1122  stream.readf(&stream, b, recordAttr->recordSize);
1123  wrbuf_write(result, b, recordAttr->recordSize);
1124 
1125  stream.destroy(&stream);
1126  rec_free(&rec);
1127  return 0;
1128  }
1129 
1130  /* processing special elementsetnames zebra::meta:: */
1131  if (elemsetname && 0 == strcmp(elemsetname, "meta"))
1132  {
1133  int ret = 0;
1134  RecordAttr *recordAttr = rec_init_attr(zh->reg->zei, rec);
1135 
1136  if (!oid_oidcmp(input_format, yaz_oid_recsyn_xml))
1137  {
1138  *output_format = input_format;
1139 
1140  wrbuf_printf(result, ZEBRA_XML_HEADER_STR
1141  " sysno=\"" ZINT_FORMAT "\"", sysno);
1142  retrieve_puts_attr(result, "base", rec->info[recInfo_databaseName]);
1143  retrieve_puts_attr(result, "file", rec->info[recInfo_filename]);
1144  retrieve_puts_attr(result, "type", rec->info[recInfo_fileType]);
1145  if (fi->score >= 0)
1146  retrieve_puts_attr_int(result, "score", fi->score);
1147 
1148  wrbuf_printf(result,
1149  " rank=\"" ZINT_FORMAT "\""
1150  " size=\"%i\""
1151  " set=\"zebra::%s\"/>\n",
1152  recordAttr->staticrank,
1153  recordAttr->recordSize,
1154  elemsetname);
1155  }
1156  else if (!oid_oidcmp(input_format, yaz_oid_recsyn_sutrs))
1157  {
1158  *output_format = input_format;
1159  wrbuf_printf(result, "sysno " ZINT_FORMAT "\n", sysno);
1160  retrieve_puts_str(result, "base", rec->info[recInfo_databaseName]);
1161  retrieve_puts_str(result, "file", rec->info[recInfo_filename]);
1162  retrieve_puts_str(result, "type", rec->info[recInfo_fileType]);
1163  if (fi->score >= 0)
1164  retrieve_puts_int(result, "score", fi->score);
1165 
1166  wrbuf_printf(result,
1167  "rank " ZINT_FORMAT "\n"
1168  "size %i\n"
1169  "set zebra::%s\n",
1170  recordAttr->staticrank,
1171  recordAttr->recordSize,
1172  elemsetname);
1173  }
1174  else
1175  ret = YAZ_BIB1_NO_SYNTAXES_AVAILABLE_FOR_THIS_REQUEST;
1176 
1177  rec_free(&rec);
1178  return ret;
1179  }
1180 
1181  /* processing special elementsetnames zebra::index:: */
1182  if (elemsetname && 0 == strncmp(elemsetname, "index", 5))
1183  {
1184  int ret = special_index_fetch(
1185  fi, elemsetname + 5,
1186  input_format, output_format,
1187  result, addinfo, rec);
1188  rec_free(&rec);
1189  return ret;
1190  }
1191 
1192  if (rec)
1193  rec_free(&rec);
1194  return YAZ_BIB1_SPECIFIED_ELEMENT_SET_NAME_NOT_VALID_FOR_SPECIFIED_;
1195 }
1196 
1197 int zebra_record_fetch(ZebraHandle zh, const char *setname,
1198  zint sysno, int score,
1199  ODR odr,
1200  const Odr_oid *input_format, Z_RecordComposition *comp,
1201  const Odr_oid **output_format,
1202  char **rec_bufp, int *rec_lenp, char **basenamep,
1203  WRBUF addinfo_w)
1204 {
1205  Record rec;
1206  char *fname, *file_type, *basename;
1207  const char *elemsetname;
1208  struct ZebraRecStream stream;
1209  RecordAttr *recordAttr;
1210  void *clientData;
1211  int return_code = 0;
1212  zint sysnos[MAX_SYSNOS_PER_RECORD];
1213  int no_sysnos = MAX_SYSNOS_PER_RECORD;
1214  ZEBRA_RES res;
1215  struct special_fetch_s fetch_info;
1216 
1217  if (!log_level_set)
1218  {
1219  log_level_mod = yaz_log_module_level("retrieve");
1220  log_level_set = 1;
1221  }
1222  res = zebra_result_recid_to_sysno(zh, setname, sysno, sysnos, &no_sysnos);
1223  if (res != ZEBRA_OK)
1224  return ZEBRA_FAIL;
1225 
1226  sysno = sysnos[0];
1227  *basenamep = 0;
1228  elemsetname = yaz_get_esn(comp);
1229 
1230  fetch_info.zh = zh;
1231  fetch_info.setname = setname;
1232  fetch_info.sysno = sysno;
1233  fetch_info.score = score;
1234  fetch_info.nmem = odr->mem;
1235 
1236  /* processing zebra special elementset names of form 'zebra:: */
1237  if (elemsetname && 0 == strncmp(elemsetname, "zebra::", 7))
1238  {
1239  WRBUF result = wrbuf_alloc();
1240  int r = zebra_special_fetch(&fetch_info, elemsetname + 7,
1241  input_format, output_format,
1242  result, addinfo_w);
1243  if (r == 0)
1244  {
1245  *rec_bufp = odr_strdup(odr, wrbuf_cstr(result));
1246  *rec_lenp = wrbuf_len(result);
1247  }
1248  wrbuf_destroy(result);
1249  return r;
1250  }
1251 
1252  /* processing all other element set names */
1253  rec = rec_get(zh->reg->records, sysno);
1254  if (!rec)
1255  {
1256  yaz_log(YLOG_WARN, "rec_get fail on sysno=" ZINT_FORMAT, sysno);
1257  *basenamep = 0;
1258  return YAZ_BIB1_SYSTEM_ERROR_IN_PRESENTING_RECORDS;
1259  }
1260 
1261 
1262  recordAttr = rec_init_attr(zh->reg->zei, rec);
1263 
1264  file_type = rec->info[recInfo_fileType];
1265  fname = rec->info[recInfo_filename];
1266  basename = rec->info[recInfo_databaseName];
1267  *basenamep = (char *) odr_malloc(odr, strlen(basename)+1);
1268  strcpy(*basenamep, basename);
1269 
1270  yaz_log(YLOG_DEBUG, "retrieve localno=" ZINT_FORMAT " score=%d",
1271  sysno, score);
1272 
1273  return_code = zebra_create_record_stream(zh, &rec, &stream);
1274 
1275  if (rec)
1276  {
1277  RecType rt;
1278  struct recRetrieveCtrl retrieveCtrl;
1279 
1280  retrieveCtrl.stream = &stream;
1281  retrieveCtrl.fname = fname;
1282  retrieveCtrl.localno = sysno;
1283  retrieveCtrl.staticrank = recordAttr->staticrank;
1284  retrieveCtrl.score = score;
1285  retrieveCtrl.recordSize = recordAttr->recordSize;
1286  retrieveCtrl.odr = odr;
1287  retrieveCtrl.input_format = retrieveCtrl.output_format = input_format;
1288  retrieveCtrl.comp = comp;
1289  retrieveCtrl.encoding = zh->record_encoding;
1290  retrieveCtrl.diagnostic = 0;
1291  retrieveCtrl.addinfo = 0;
1292  retrieveCtrl.dh = zh->reg->dh;
1293  retrieveCtrl.res = zh->res;
1294  retrieveCtrl.rec_buf = 0;
1295  retrieveCtrl.rec_len = -1;
1296  retrieveCtrl.handle = &fetch_info;
1297  retrieveCtrl.special_fetch = zebra_special_fetch;
1298 
1299  if (!(rt = recType_byName(zh->reg->recTypes, zh->res,
1300  file_type, &clientData)))
1301  {
1302  wrbuf_printf(addinfo_w, "Could not handle record type %.40s",
1303  file_type);
1304  return_code = YAZ_BIB1_SYSTEM_ERROR_IN_PRESENTING_RECORDS;
1305  }
1306  else
1307  {
1308  (*rt->retrieve)(clientData, &retrieveCtrl);
1309  return_code = retrieveCtrl.diagnostic;
1310 
1311  *output_format = retrieveCtrl.output_format;
1312  *rec_bufp = (char *) retrieveCtrl.rec_buf;
1313  *rec_lenp = retrieveCtrl.rec_len;
1314  if (retrieveCtrl.addinfo)
1315  wrbuf_puts(addinfo_w, retrieveCtrl.addinfo);
1316  }
1317 
1318  stream.destroy(&stream);
1319  rec_free(&rec);
1320  }
1321 
1322  return return_code;
1323 }
1324 
1325 /*
1326  * Local variables:
1327  * c-basic-offset: 4
1328  * c-file-style: "Stroustrup"
1329  * indent-tabs-mode: nil
1330  * End:
1331  * vim: shiftwidth=4 tabstop=8 expandtab
1332  */
1333 
#define O_BINARY
Definition: agrep.c:46
void error(const char *format,...)
Definition: agrep.c:51
ZebraMetaRecord * zebra_meta_records_create(ZebraHandle zh, const char *name, int num, zint *positions)
Definition: zsets.c:418
void zebra_meta_records_destroy(ZebraHandle zh, ZebraMetaRecord *records, int num)
Definition: zsets.c:547
char * dict_lookup(Dict dict, const char *p)
lookup item in dictionary
Definition: lookup.c:100
void extract_snippet(ZebraHandle zh, zebra_snippets *sn, struct ZebraRecStream *stream, RecType rt, void *recTypeClientData)
Definition: extract.c:323
void zebra_term_untrans_iconv2(ZebraHandle zh, NMEM stream, char **dst, const char *src)
Definition: untrans.c:64
ZEBRA_RES zebra_result_recid_to_sysno(ZebraHandle zh, const char *setname, zint recid, zint *sysnos, int *no_sysnos)
Definition: zsets.c:1481
RSET resultSetRef(ZebraHandle zh, const char *resultSetId)
Definition: zsets.c:1075
int zebra_term_untrans(ZebraHandle zh, const char *index_type, char *dst, const char *src)
Definition: untrans.c:31
void zebra_create_stream_fd(struct ZebraRecStream *stream, int fd, off_t start_offset)
Definition: stream.c:140
void zebra_count_set(ZebraHandle zh, RSET rset, zint *count, zint approx_limit)
Definition: zsets.c:1498
void zebra_create_stream_mem(struct ZebraRecStream *stream, const char *buf, size_t sz)
Definition: stream.c:123
#define FIRST_IN_FIELD_CHAR
Definition: index.h:420
RSET zebra_create_rset_isam(ZebraHandle zh, NMEM rset_nmem, struct rset_key_control *kctl, int scope, ISAM_P pos, TERMID termid)
Definition: rset_isam.c:32
int zebra_term_untrans_iconv(ZebraHandle zh, NMEM stream, const char *index_type, char **dst, const char *src)
Definition: untrans.c:96
struct rset_key_control * zebra_key_control_create(ZebraHandle zh)
Definition: kcontrol.c:57
ZEBRA_RES zebra_snippets_hit_vector(ZebraHandle zh, const char *setname, zint sysno, zebra_snippets *snippets)
Definition: zsets.c:1340
zint ISAM_P
Definition: isamc.h:28
#define IT_MAX_WORD
Definition: it_key.h:27
int key_SU_encode(int ch, char *out)
Definition: su_codec.c:31
RecType recType_byName(RecTypes rts, Res res, const char *name, void **clientDataP)
Definition: recctrl.c:264
Record rec_get(Records p, zint sysno)
gets record - with given system number
Definition: records.c:928
@ recInfo_databaseName
Definition: recindex.h:122
@ recInfo_filename
Definition: recindex.h:120
@ recInfo_delKeys
Definition: recindex.h:121
@ recInfo_fileType
Definition: recindex.h:119
@ recInfo_storeData
Definition: recindex.h:123
void rec_free(Record *recpp)
frees record (from memory)
Definition: records.c:1044
int zebra_rec_keys_empty(zebra_rec_keys_t keys)
Definition: reckeys.c:252
int zebra_rec_keys_read(zebra_rec_keys_t keys, const char **str, size_t *slen, struct it_key *key)
Definition: reckeys.c:259
int zebra_rec_keys_rewind(zebra_rec_keys_t keys)
Definition: reckeys.c:240
zebra_rec_keys_t zebra_rec_keys_open(void)
Definition: reckeys.c:88
void zebra_rec_keys_set_buf(zebra_rec_keys_t p, char *buf, size_t sz, int copy_buf)
Definition: reckeys.c:109
void zebra_rec_keys_close(zebra_rec_keys_t p)
Definition: reckeys.c:143
ZEBRA_RES res_get_int(Res r, const char *name, int *val)
Definition: res.c:432
#define ZEBRA_XML_HEADER_STR
Definition: retrieve.c:44
static void snippet_xml_record(ZebraHandle zh, WRBUF wrbuf, zebra_snippets *doc)
Definition: retrieve.c:420
static void retrieve_puts_str(WRBUF wrbuf, const char *name, const char *value)
Definition: retrieve.c:371
static int perform_facet_sort(ZebraHandle zh, int no_ord, int *ord_array, zebra_strmap_t *map_array, int num_recs, ZebraMetaRecord *poset)
Definition: retrieve.c:698
static struct term_collect * term_collect_create(zebra_strmap_t sm, int no_terms_collect, NMEM nmem)
Definition: retrieve.c:655
static int special_index_fetch(struct special_fetch_s *fi, const char *elemsetname, const Odr_oid *input_format, const Odr_oid **output_format, WRBUF result, WRBUF addinfo, Record rec)
Definition: retrieve.c:303
static void term_collect_freq(ZebraHandle zh, struct term_collect *col, int no_terms_collect, int ord, RSET rset, double scale_factor)
Definition: retrieve.c:633
static int perform_facet(ZebraHandle zh, struct special_fetch_s *fi, WRBUF result, int num_recs, ZebraMetaRecord *poset, struct index_spec *spec_list, int no_ord, int *ord_array, int use_xml, zinfo_index_category_t cat)
Definition: retrieve.c:813
static int perform_facet_index(ZebraHandle zh, struct special_fetch_s *fi, int no_ord, int *ord_array, zebra_strmap_t *map_array, int num_recs, ZebraMetaRecord *poset, struct index_spec *spec_list)
Definition: retrieve.c:742
int zebra_record_fetch(ZebraHandle zh, const char *setname, zint sysno, int score, ODR odr, const Odr_oid *input_format, Z_RecordComposition *comp, const Odr_oid **output_format, char **rec_bufp, int *rec_lenp, char **basenamep, WRBUF addinfo_w)
Definition: retrieve.c:1197
static int zebra_create_record_stream(ZebraHandle zh, Record *rec, struct ZebraRecStream *stream)
Definition: retrieve.c:57
static int facet_fetch(struct special_fetch_s *fi, const char *elemsetname, const Odr_oid *input_format, const Odr_oid **output_format, WRBUF result, WRBUF addinfo)
Definition: retrieve.c:943
static int term_qsort_handle(const void *a, const void *b)
Definition: retrieve.c:617
static void special_index_xml_record(ZebraHandle zh, WRBUF wrbuf, zebra_snippets *doc, zint sysno, struct index_spec *spec_list, const char *elemsetname, int use_xml)
Definition: retrieve.c:248
static int zebra_special_fetch(void *handle, const char *elemsetname, const Odr_oid *input_format, const Odr_oid **output_format, WRBUF result, WRBUF addinfo)
Definition: retrieve.c:1043
static void retrieve_puts_attr_int(WRBUF wrbuf, const char *name, const int value)
Definition: retrieve.c:365
static int snippet_fetch(struct special_fetch_s *fi, const char *elemsetname, const Odr_oid *input_format, const Odr_oid **output_format, WRBUF result, WRBUF addinfo)
Definition: retrieve.c:508
static void snippet_check_fields(ZebraHandle zh, WRBUF wrbuf, zebra_snippets *doc, const zebra_snippet_word *doc_w, const char *w_index_type)
Definition: retrieve.c:385
#define MAX_SYSNOS_PER_RECORD
Definition: retrieve.c:42
struct index_spec * parse_index_spec(const char *elem, NMEM nmem, int *error)
Definition: retrieve.c:100
static void retrieve_puts_int(WRBUF wrbuf, const char *name, const int value)
Definition: retrieve.c:378
static int log_level_mod
Definition: retrieve.c:54
static int log_level_set
Definition: retrieve.c:55
int zebra_get_rec_snippets(ZebraHandle zh, zint sysno, zebra_snippets *snippets)
Definition: retrieve.c:465
static void retrieve_puts_attr(WRBUF wrbuf, const char *name, const char *value)
Definition: retrieve.c:354
static int sort_fetch(struct special_fetch_s *fi, const char *elemsetname, const Odr_oid *input_format, const Odr_oid **output_format, WRBUF result, WRBUF addinfo)
Definition: retrieve.c:158
static zint freq_term(ZebraHandle zh, int ord, const char *term, RSET rset_set, zint *first_sysno, zint *first_seq)
Definition: retrieve.c:562
void rset_delete(RSET rs)
Destructor RSETs.
Definition: rset.c:218
RSET rset_create_and(NMEM nmem, struct rset_key_control *kcontrol, int scope, int no_rsets, RSET *rsets)
Definition: rsmultiandor.c:280
#define rset_read(rfd, buf, term)
Definition: rset.h:217
struct rset rset
RSET rset_dup(RSET rs)
Duplicate an RSET.
Definition: rset.c:255
#define RSETF_READ
Definition: rset.h:199
TERMID rset_term_create(const char *name, int length, const char *flags, int type, NMEM nmem, struct ord_list *ol, int reg_type, zint hits_limit, const char *ref_id)
Creates a TERMID entry.
Definition: rset.c:340
#define rset_open(rs, wflag)
Definition: rset.h:202
void rset_close(RSFD rfd)
Closes a result set RFD handle.
Definition: rset.c:98
void zebra_snippets_log(const zebra_snippets *l, int log_level, int all)
Definition: snippet.c:104
void zebra_snippets_destroy(zebra_snippets *l)
Definition: snippet.c:45
const zebra_snippet_word * zebra_snippets_constlist(const zebra_snippets *l)
Definition: snippet.c:99
void zebra_snippets_ring(zebra_snippets *doc, const zebra_snippets *hit, int before, int after)
Definition: snippet.c:237
zebra_snippets * zebra_snippets_create(void)
Definition: snippet.c:36
int zebra_sort_read(zebra_sort_index_t si, zint *section_id, WRBUF w)
reads sort entry
Definition: sortidx.c:470
int zebra_sort_type(zebra_sort_index_t si, int type)
sets type for sort usage
Definition: sortidx.c:235
void zebra_sort_sysno(zebra_sort_index_t si, zint sysno)
sets sort system number for read / add / delete
Definition: sortidx.c:340
off_t recordOffset
Definition: zinfo.h:107
int recordSize
Definition: zinfo.h:106
zint staticrank
Definition: zinfo.h:109
zint sysno
Definition: api.h:483
record reader stream
Definition: recctrl.h:71
void(* destroy)(struct ZebraRecStream *s)
close and destroy stream
Definition: recctrl.h:83
int(* readf)(struct ZebraRecStream *s, char *buf, size_t count)
read function
Definition: recctrl.h:75
const char * extra
Definition: retrieve.c:95
const char * index_name
Definition: retrieve.c:93
const char * index_type
Definition: retrieve.c:94
struct index_spec * next
Definition: retrieve.c:96
Definition: it_key.h:30
int len
Definition: it_key.h:31
zint mem[IT_KEY_LEVEL_MAX]
Definition: it_key.h:32
const Odr_oid * input_format
Definition: recctrl.h:123
data1_handle dh
Definition: recctrl.h:131
int(* special_fetch)(void *handle, const char *esn, const Odr_oid *input_format, const Odr_oid **output_format, WRBUF result, WRBUF addinfo)
Definition: recctrl.h:142
char * addinfo
Definition: recctrl.h:138
Z_RecordComposition * comp
Definition: recctrl.h:124
struct ZebraRecStream * stream
Definition: recctrl.h:119
const Odr_oid * output_format
Definition: recctrl.h:134
void * handle
Definition: recctrl.h:141
zint staticrank
Definition: recctrl.h:128
char * encoding
Definition: recctrl.h:125
char * fname
Definition: recctrl.h:130
void * rec_buf
Definition: recctrl.h:135
int(* retrieve)(void *clientData, struct recRetrieveCtrl *ctrl)
Definition: recctrl.h:159
char * info[REC_NO_INFO]
Definition: recindex.h:34
void(* dec)(struct rset_key_control *kc)
Definition: rset.h:138
Definition: rset.h:50
Definition: rset.h:151
Definition: rset.h:73
const char * setname
Definition: retrieve.c:48
ZebraHandle zh
Definition: retrieve.c:47
const char * term
Definition: retrieve.c:555
zint set_occur
Definition: retrieve.c:557
zint first_sysno
Definition: retrieve.c:558
zint first_seqno
Definition: retrieve.c:559
ZebraExplainInfo zei
Definition: index.h:139
RecTypes recTypes
Definition: index.h:145
data1_handle dh
Definition: index.h:142
Records records
Definition: index.h:138
zebra_sort_index_t sort_index
Definition: index.h:134
Dict dict
Definition: index.h:132
struct zebra_register * reg
Definition: index.h:174
char * path_reg
Definition: index.h:182
zint approx_limit
Definition: index.h:180
char * record_encoding
Definition: index.h:213
struct zebra_snippet_word * next
Definition: snippet.h:34
int fd
Definition: tstlockscope.c:38
long zint
Zebra integer.
Definition: util.h:66
#define ZEBRA_FAIL
Definition: util.h:81
#define ZINT_FORMAT
Definition: util.h:72
#define CAST_ZINT_TO_INT(x)
Definition: util.h:96
#define ZEBRA_OK
Definition: util.h:82
short ZEBRA_RES
Common return type for Zebra API.
Definition: util.h:80
void zebra_strmap_destroy(zebra_strmap_t st)
Definition: strmap.c:61
void * zebra_strmap_lookup(zebra_strmap_t st, const char *name, int no, size_t *data_len)
Definition: strmap.c:99
const char * zebra_strmap_it_next(zebra_strmap_it it, void **data_buf, size_t *data_len)
Definition: strmap.c:162
zebra_strmap_t zebra_strmap_create(void)
Definition: strmap.c:45
void zebra_strmap_it_destroy(zebra_strmap_it it)
Definition: strmap.c:157
void zebra_strmap_add(zebra_strmap_t st, const char *name, void *data_buf, size_t data_len)
Definition: strmap.c:80
zebra_strmap_it zebra_strmap_it_create(zebra_strmap_t st)
Definition: strmap.c:148
RecordAttr * rec_init_attr(ZebraExplainInfo zei, Record rec)
Definition: zinfo.c:1594
int zebraExplain_lookup_attr_str(ZebraExplainInfo zei, zinfo_index_category_t cat, const char *index_type, const char *str)
lookup ordinal from string index + index type
Definition: zinfo.c:1353
int zebraExplain_lookup_ord(ZebraExplainInfo zei, int ord, const char **index_type, const char **db, const char **string_index)
Definition: zinfo.c:1478
zinfo_index_category_t
Definition: zinfo.h:37
@ zinfo_index_category_index
Definition: zinfo.h:38
@ zinfo_index_category_sort
Definition: zinfo.h:39