+Implemented Z39.50 Sort. Zebra's sort handler uses use attributes to
+specify a "sort register". Refer to the gils sample records which
+refer to index type "s" which is specified as "sort" in the default.idx
+file. Each sort criteria can either be Ascending or Descending and
+at most three sort elements can be specified.
+
+Bug fix: Character mapping didn't work for text files.
+
--- 1.0b1 1998/1/29
Simple ranked searches now return correct number of hits.
<!doctype linuxdoc system>
<!--
- $Id: zebra.sgml,v 1.39 1998-01-30 15:30:57 adam Exp $
+ $Id: zebra.sgml,v 1.40 1998-02-10 12:03:05 adam Exp $
-->
<article>
<title>Zebra Server - Administrators's Guide and Reference
<author><htmlurl url="http://www.indexdata.dk/" name="Index Data">,
<tt><htmlurl url="mailto:info@indexdata.dk" name="info@indexdata.dk"></>
-<date>$Revision: 1.39 $
+<date>$Revision: 1.40 $
<abstract>
The Zebra information server combines a versatile fielded/free-text
search engine with a Z39.50-1995 frontend to provide a powerful and flexible
Supports approximate matching in registers (ie. spelling mistakes,
etc).
-<item>
+</itemize>
+
+<p>
Protocol support:
<itemize>
<item>
-Protocol facilities: Init, Search, Retrieve, Browse.
+Protocol facilities: Init, Search, Retrieve, Browse and Sort.
<item>
Piggy-backed presents are honored in the search-request.
</itemize>
-</itemize>
-
<sect1>Future Work
<p>
Currently, only the term and the globalOccurrences are returned with
the TermInfo structure.
+<sect2>Sort
+
+<p>
+Z39.50 specifies three diffent types of sort criterias.
+Of these Zebra supports the attribute specification type in which
+case the use attribute specifies the "Sort register".
+Sort registers are created for those fields that are of type "sort" in
+the default.idx file.
+The corresponding character mapping file in default.idx specifies the
+ordinal of each character used in the actual sort.
+
+Z39.50 allows the client to specify sorting on one or more input
+result sets and one output result set.
+Zebra supports sorting on one result set only which may or may not
+be the same as the output result set.
+
<sect2>Close
<p>
<descrip>
<tag>index <it/field type code/</tag>This directive introduces a new
-index code. The argument is a one-character code to be used in the
+search index code. The argument is a one-character code to be used in the
.abs files to select this particular index type. An index, roughly,
corresponds to a particular structure attribute during search. Refer
to section <ref id="search" name="Search">.
+<tag>sort <it/field code type/</tag>This directive introduces a
+sort index. The argument is a one-character code to be used in the
+.abs fie to select this particular index type. The corresponding
+use attribute must be used in the sort request to refer to this
+particular sort index. The corresponding character map (see below)
+is used in the sort process.
+
<tag>completeness <it/boolean/</tag>This directive enables or disables
complete field indexing. The value of the <it/boolean/ should be 0
(disable) or 1. If completeness is enabled, the index entry will
* Sebastian Hammer, Adam Dickmeiss
*
* $Log: recctrl.h,v $
- * Revision 1.22 1997-10-27 14:33:04 adam
+ * Revision 1.23 1998-02-10 12:03:05 adam
+ * Implemented Sort.
+ *
+ * Revision 1.22 1997/10/27 14:33:04 adam
* Moved towards generic character mapping depending on "structure"
* field in abstract syntax file. Fixed a few memory leaks. Fixed
* bug with negative integers when doing searches with relational
int attrUse;
unsigned reg_type;
char *string;
- int seqno;
+ int length;
+ int seqno;
+ ZebraMaps zebra_maps;
} RecWord;
/* Extract record control */
void (*endf)(void *fh, off_t offset); /* end of record position */
off_t offset; /* start offset */
char *subType;
- void (*init)(RecWord *p);
- void (*add)(const RecWord *p);
+ void (*init)(struct recExtractCtrl *p, RecWord *w);
+ void (*add)(RecWord *p);
ZebraMaps zebra_maps;
int flagShowRecords;
data1_handle dh;
--- /dev/null
+/*
+ * Copyright (C) 1994-1998, Index Data I/S
+ * All rights reserved.
+ * Sebastian Hammer, Adam Dickmeiss
+ *
+ * $Log: sortidx.h,v $
+ * Revision 1.1 1998-02-10 12:03:05 adam
+ * Implemented Sort.
+ *
+ */
+
+#ifndef SORTIDX_H
+#define SORTIDX_H
+
+#include <bfile.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define SORT_IDX_ENTRYSIZE 64
+
+typedef struct sortIdx *SortIdx;
+
+SortIdx sortIdx_open (BFiles bfs, int write_flag);
+void sortIdx_close (SortIdx si);
+int sortIdx_type (SortIdx si, int type);
+void sortIdx_sysno (SortIdx si, int sysno);
+void sortIdx_add (SortIdx si, const char *buf, int len);
+void sortIdx_read (SortIdx si, char *buf);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
/*
- * Copyright (C) 1994-1997, Index Data I/S
+ * Copyright (C) 1994-1998, Index Data I/S
* All rights reserved.
* Sebastian Hammer, Adam Dickmeiss
*
* $Log: zebramap.h,v $
- * Revision 1.3 1997-11-18 10:05:08 adam
+ * Revision 1.4 1998-02-10 12:03:05 adam
+ * Implemented Sort.
+ *
+ * Revision 1.3 1997/11/18 10:05:08 adam
* Changed character map facility so that admin can specify character
* mapping files for each register type, w, p, etc.
*
int zebra_maps_attr (ZebraMaps zms, Z_AttributesPlusTerm *zapt,
int *reg_type, char **search_type, int *complete_flag);
+int zebra_maps_sort (ZebraMaps zms, Z_SortAttributes *sortAttributes);
+
int zebra_maps_is_complete (ZebraMaps zms, int structure);
+int zebra_maps_is_sort (ZebraMaps zms, int reg_type);
#ifdef __cplusplus
}
#endif
* Sebastian Hammer, Adam Dickmeiss
*
* $Log: zebraver.h,v $
- * Revision 1.11 1998-01-29 13:33:04 adam
+ * Revision 1.12 1998-02-10 12:03:05 adam
+ * Implemented Sort.
+ *
+ * Revision 1.11 1998/01/29 13:33:04 adam
* 1.0b1.
*
* Revision 1.10 1997/02/12 20:45:21 adam
*/
#ifndef ZEBRAVER
-#define ZEBRAVER "1.0b1"
+#define ZEBRAVER "1.0b2"
#endif
#ifndef ZEBRADATE
-#define ZEBRADATE "$Date: 1998-01-29 13:33:04 $"
+#define ZEBRADATE "$Date: 1998-02-10 12:03:05 $"
#endif
# Copyright (C) 1995-1998, Index Data I/S
# All rights reserved.
# Sebastian Hammer, Adam Dickmeiss
-# $Id: Makefile,v 1.47 1998-01-30 15:31:49 adam Exp $
+# $Id: Makefile,v 1.48 1998-02-10 12:03:05 adam Exp $
SHELL=/bin/sh
RANLIB=ranlib
DEFS=$(INCLUDE)
O1 = main.o dir.o dirs.o trav.o extract.o kinput.o kcompare.o \
symtab.o recindex.o recstat.o lockutil.o lockidx.o \
- zinfo.o invstat.o
+ zinfo.o invstat.o sortidx.o
O2 = kdump.o
O3 = zserver.o kcompare.o zrpn.o zsets.o attribute.o recindex.o \
- zlogs.o lockutil.o locksrv.o zinfo.o trunc.o
+ zlogs.o lockutil.o locksrv.o zinfo.o trunc.o sortidx.o
O4 = hlvl.o hlvltest.o kcompare.o
CPP=$(CC) -E
* Sebastian Hammer, Adam Dickmeiss
*
* $Log: extract.c,v $
- * Revision 1.77 1998-01-12 15:04:08 adam
+ * Revision 1.78 1998-02-10 12:03:05 adam
+ * Implemented Sort.
+ *
+ * Revision 1.77 1998/01/12 15:04:08 adam
* The test option (-s) only uses read-lock (and not write lock).
*
* Revision 1.76 1997/10/27 14:33:04 adam
#include <fcntl.h>
#include <recctrl.h>
+#include <charmap.h>
+#include <sortidx.h>
#include "index.h"
#include "zinfo.h"
static Dict matchDict;
static Records records = NULL;
+static SortIdx sortIdx = NULL;
static char **key_buf;
static size_t ptr_top;
dict_close (matchDict);
return -1;
}
+ sortIdx = sortIdx_open (bfs, 1);
return 0;
}
#endif
rec_close (&records);
dict_close (matchDict);
+ sortIdx_close (sortIdx);
logRecord (1);
return key_file_no;
}
-static void wordInit (RecWord *p)
+static void wordInit (struct recExtractCtrl *p, RecWord *w)
{
- p->attrSet = 1;
- p->attrUse = 1016;
- p->reg_type = 'w';
+ w->zebra_maps = p->zebra_maps;
+ w->attrSet = 1;
+ w->attrUse = 1016;
+ w->reg_type = 'w';
}
-struct recKeys {
+static struct sortKey {
+ char *string;
+ int length;
+ int attrSet;
+ int attrUse;
+ struct sortKey *next;
+} *sortKeys = NULL;
+
+static struct recKeys {
int buf_used;
int buf_max;
char *buf;
int prevSeqNo;
} reckeys;
-static void addRecordKey (const RecWord *p)
+static void addIndexString (RecWord *p, const char *string, int length)
{
char *dst;
char attrSet;
short attrUse;
- size_t i;
int lead = 0;
int diff = 0;
dst += sizeof(attrUse);
}
*dst++ = p->reg_type;
- for (i = 0; p->string[i] && i < IT_MAX_WORD-3; i++)
- *dst++ = p->string[i];
+ memcpy (dst, string, length);
+ dst += length;
*dst++ = '\0';
if (!diff)
dst += sizeof(p->seqno);
}
reckeys.buf_used = dst - reckeys.buf;
+ (p->seqno)++;
+}
+
+static void addSortString (RecWord *p, const char *string, int length)
+{
+ struct sortKey *sk;
+
+ for (sk = sortKeys; sk; sk = sk->next)
+ if (sk->attrSet == p->attrSet && sk->attrUse == p->attrUse)
+ return;
+
+ sk = xmalloc (sizeof(*sk));
+ sk->next = sortKeys;
+ sortKeys = sk;
+
+ sk->string = xmalloc (p->length);
+ sk->length = p->length;
+ memcpy (sk->string, p->string, p->length);
+ sk->attrSet = p->attrSet;
+ sk->attrUse = p->attrUse;
+}
+
+static void addString (RecWord *p, const char *string, int length)
+{
+ if (zebra_maps_is_sort (p->zebra_maps, p->reg_type))
+ addSortString (p, string, length);
+ else
+ addIndexString (p, string, length);
+}
+
+static void addIncompleteField (RecWord *p)
+{
+ const char *b = p->string;
+ int remain = p->length;
+ const char **map = 0;
+
+ if (remain > 0)
+ map = zebra_maps_input(p->zebra_maps, p->reg_type, &b, remain);
+
+ while (map)
+ {
+ char buf[IT_MAX_WORD+1];
+ int i, remain;
+
+ /* Skip spaces */
+ while (map && *map && **map == *CHR_SPACE)
+ {
+ remain = p->length - (b - p->string);
+ if (remain > 0)
+ map = zebra_maps_input(p->zebra_maps, p->reg_type, &b, remain);
+ else
+ map = 0;
+ }
+ if (!map)
+ break;
+ i = 0;
+ while (map && *map && **map != *CHR_SPACE)
+ {
+ const char *cp = *map;
+
+ while (i < IT_MAX_WORD && *cp)
+ buf[i++] = *(cp++);
+ remain = p->length - (b - p->string);
+ if (remain > 0)
+ map = zebra_maps_input(p->zebra_maps, p->reg_type, &b, remain);
+ else
+ map = 0;
+ }
+ if (!i)
+ return;
+ addString (p, buf, i);
+ }
+}
+
+static void addCompleteField (RecWord *p)
+{
+ const char *b = p->string;
+ char buf[IT_MAX_WORD+1];
+ const char **map = 0;
+ int i = 0, remain = p->length;
+
+ if (remain > 0)
+ map = zebra_maps_input (p->zebra_maps, p->reg_type, &b, remain);
+
+ while (remain > 0 && i < IT_MAX_WORD)
+ {
+ while (map && *map && **map == *CHR_SPACE)
+ {
+ remain = p->length - (b - p->string);
+ if (remain > 0)
+ map = zebra_maps_input(p->zebra_maps, p->reg_type, &b, remain);
+ else
+ map = 0;
+ }
+ if (!map)
+ break;
+
+ if (i && i < IT_MAX_WORD)
+ buf[i++] = *CHR_SPACE;
+ while (map && *map && **map != *CHR_SPACE)
+ {
+ const char *cp = *map;
+
+ if (i >= IT_MAX_WORD)
+ break;
+ while (i < IT_MAX_WORD && *cp)
+ buf[i++] = *(cp++);
+ remain = p->length - (b - p->string);
+ if (remain > 0)
+ map = zebra_maps_input (p->zebra_maps, p->reg_type, &b,
+ remain);
+ else
+ map = 0;
+ }
+ }
+ if (!i)
+ return;
+ addString (p, buf, i);
+}
+
+static void addRecordKey (RecWord *p)
+{
+ if (zebra_maps_is_complete (p->zebra_maps, p->reg_type))
+ addCompleteField (p);
+ else
+ addIncompleteField(p);
+}
+
+static void flushSortKeys (SYSNO sysno, int cmd)
+{
+ struct sortKey *sk = sortKeys;
+
+ sortIdx_sysno (sortIdx, sysno);
+ while (sk)
+ {
+ struct sortKey *sk_next = sk->next;
+ sortIdx_type (sortIdx, sk->attrUse);
+ sortIdx_add (sortIdx, sk->string, sk->length);
+ xfree (sk->string);
+ xfree (sk);
+ sk = sk_next;
+ }
+ sortKeys = NULL;
}
static void flushRecordKeys (SYSNO sysno, int cmd, struct recKeys *reckeys,
dict_insert (matchDict, matchStr, sizeof(*sysno), sysno);
}
flushRecordKeys (*sysno, 1, &reckeys, rGroup->databaseName);
+ flushSortKeys (*sysno, 1);
records_inserted++;
}
assert (rec);
delkeys.buf_used = rec->size[recInfo_delKeys];
delkeys.buf = rec->info[recInfo_delKeys];
+ flushSortKeys (*sysno, 0);
flushRecordKeys (*sysno, 0, &delkeys, rec->info[recInfo_databaseName]);
if (deleteFlag)
{
--- /dev/null
+
+#include <string.h>
+
+#include <log.h>
+#include <bfile.h>
+#include <sortidx.h>
+
+#define SORT_IDX_BLOCKSIZE 64
+
+struct sortFileHead {
+ int sysno_max;
+};
+
+struct sortFile {
+ int type;
+ BFile bf;
+ struct sortFile *next;
+ struct sortFileHead head;
+};
+
+struct sortIdx {
+ BFiles bfs;
+ int write_flag;
+ int sysno;
+ char *entry_buf;
+ struct sortFile *current_file;
+ struct sortFile *files;
+};
+
+SortIdx sortIdx_open (BFiles bfs, int write_flag)
+{
+ SortIdx si = xmalloc (sizeof(*si));
+ si->bfs = bfs;
+ si->write_flag = write_flag;
+ si->current_file = NULL;
+ si->files = NULL;
+ si->entry_buf = xmalloc (SORT_IDX_ENTRYSIZE);
+ return si;
+}
+
+void sortIdx_close (SortIdx si)
+{
+ struct sortFile *sf = si->files;
+ while (sf)
+ {
+ struct sortFile *sf_next = sf->next;
+ if (sf->bf)
+ bf_close (sf->bf);
+ xfree (sf);
+ sf = sf_next;
+ }
+ xfree (si->entry_buf);
+ xfree (si);
+}
+
+int sortIdx_type (SortIdx si, int type)
+{
+ char fname[80];
+ struct sortFile *sf;
+ if (si->current_file && si->current_file->type == type)
+ return 0;
+ for (sf = si->files; sf; sf = sf->next)
+ if (sf->type == type)
+ {
+ si->current_file = sf;
+ return 0;
+ }
+ sf = xmalloc (sizeof(*sf));
+ sf->type = type;
+ sf->bf = NULL;
+ sf->next = si->files;
+ si->current_file = si->files = sf;
+ sprintf (fname, "sort%d", type);
+ logf (LOG_DEBUG, "sort idx %s wr=%d", fname, si->write_flag);
+ sf->bf = bf_open (si->bfs, fname, SORT_IDX_BLOCKSIZE, si->write_flag);
+ if (!sf->bf)
+ return -1;
+ if (!bf_read (sf->bf, 0, 0, sizeof(sf->head), &sf->head))
+ {
+ sf->head.sysno_max = 0;
+ if (!si->write_flag)
+ return -1;
+ }
+ return 0;
+}
+
+void sortIdx_sysno (SortIdx si, int sysno)
+{
+ si->sysno = sysno;
+}
+
+void sortIdx_add (SortIdx si, const char *buf, int len)
+{
+ if (!si->current_file || !si->current_file->bf)
+ return;
+ if (len > SORT_IDX_ENTRYSIZE)
+ {
+ len = SORT_IDX_ENTRYSIZE;
+ memcpy (si->entry_buf, buf, len);
+ }
+ else
+ {
+ memcpy (si->entry_buf, buf, len);
+ memset (si->entry_buf+len, 0, SORT_IDX_ENTRYSIZE-len);
+ }
+ bf_write (si->current_file->bf, si->sysno+1, 0, 0, si->entry_buf);
+}
+
+void sortIdx_read (SortIdx si, char *buf)
+{
+ bf_read (si->current_file->bf, si->sysno+1, 0, 0, buf);
+}
* Sebastian Hammer, Adam Dickmeiss
*
* $Log: zrpn.c,v $
- * Revision 1.73 1998-01-29 13:40:11 adam
+ * Revision 1.74 1998-02-10 12:03:06 adam
+ * Implemented Sort.
+ *
+ * Revision 1.73 1998/01/29 13:40:11 adam
* Better logging for scan service.
*
* Revision 1.72 1998/01/07 13:53:41 adam
}
static RSET rpn_search_structure (ZServerInfo *zi, Z_RPNStructure *zs,
- oid_value attributeSet,
+ oid_value attributeSet, ODR stream,
int num_bases, char **basenames)
{
RSET r = NULL;
bool_parms.rset_l = rpn_search_structure (zi, zs->u.complex->s1,
- attributeSet,
+ attributeSet, stream,
num_bases, basenames);
if (bool_parms.rset_l == NULL)
return NULL;
if (rset_is_ranked(bool_parms.rset_l))
soft = 1;
bool_parms.rset_r = rpn_search_structure (zi, zs->u.complex->s2,
- attributeSet,
+ attributeSet, stream,
num_bases, basenames);
if (bool_parms.rset_r == NULL)
{
}
if (*zop->u.prox->proximityUnitCode != Z_ProxUnit_word)
{
- char *val = odr_malloc (zi->odr, 16);
+ char *val = odr_malloc (stream, 16);
zi->errCode = 132;
zi->errString = val;
sprintf (val, "%d", *zop->u.prox->proximityUnitCode);
logf (LOG_DEBUG, "%d keys, %d distinct sysnos", kno, *count);
}
-int rpn_search (ZServerInfo *zi,
+int rpn_search (ZServerInfo *zi, ODR stream,
Z_RPNQuery *rpn, int num_bases, char **basenames,
const char *setname, int *hits)
{
attrset = oid_getentbyoid (rpn->attributeSetId);
attributeSet = attrset->value;
- rset = rpn_search_structure (zi, rpn->RPNStructure, attributeSet,
+ rset = rpn_search_structure (zi, rpn->RPNStructure, attributeSet, stream,
num_bases, basenames);
if (!rset)
return zi->errCode;
}
-static void scan_term_untrans (ZServerInfo *zi, int reg_type,
+static void scan_term_untrans (ZServerInfo *zi, ODR stream, int reg_type,
char **dstp, const char *src)
{
- char *dst = odr_malloc (zi->odr, strlen(src)*2+1);
+ char *dst = odr_malloc (stream, strlen(src)*2+1);
*dstp = dst;
while (*src)
*dst = '\0';
}
-int rpn_scan (ZServerInfo *zi, Z_AttributesPlusTerm *zapt,
+int rpn_scan (ZServerInfo *zi, ODR stream, Z_AttributesPlusTerm *zapt,
oid_value attributeset,
int num_bases, char **basenames,
int *position, int *num_entries, struct scan_entry **list,
return zi->errCode = 113;
before = pos-1;
after = 1+num-pos;
- scan_info_array = odr_malloc (zi->odr, ord_no * sizeof(*scan_info_array));
+ scan_info_array = odr_malloc (stream, ord_no * sizeof(*scan_info_array));
for (i = 0; i < ord_no; i++)
{
int j, prefix_len = 0;
scan_info->before = before;
scan_info->after = after;
- scan_info->odr = zi->odr;
+ scan_info->odr = stream;
- scan_info->list = odr_malloc (zi->odr, (before+after)*
+ scan_info->list = odr_malloc (stream, (before+after)*
sizeof(*scan_info->list));
for (j = 0; j<before+after; j++)
scan_info->list[j].term = NULL;
dict_scan (zi->dict, termz, &before_tmp, &after_tmp, scan_info,
scan_handle);
}
- glist = odr_malloc (zi->odr, (before+after)*sizeof(*glist));
+ glist = odr_malloc (stream, (before+after)*sizeof(*glist));
for (i = 0; i < ord_no; i++)
ptr[i] = before;
}
if (j0 == -1)
break;
- scan_term_untrans (zi, reg_type, &glist[i+before].term, mterm);
+ scan_term_untrans (zi, stream, reg_type,
+ &glist[i+before].term, mterm);
rset = rset_trunc (zi, &scan_info_array[j0].list[ptr[j0]].isam_p, 1);
ptr[j0]++;
if (j0 == -1)
break;
- scan_term_untrans (zi, reg_type, &glist[before-1-i].term, mterm);
+ scan_term_untrans (zi, stream, reg_type,
+ &glist[before-1-i].term, mterm);
rset = rset_trunc
(zi, &scan_info_array[j0].list[before-1-ptr[j0]].isam_p, 1);
* Sebastian Hammer, Adam Dickmeiss
*
* $Log: zserver.c,v $
- * Revision 1.54 1998-01-29 13:39:13 adam
+ * Revision 1.55 1998-02-10 12:03:06 adam
+ * Implemented Sort.
+ *
+ * Revision 1.54 1998/01/29 13:39:13 adam
* Compress ISAM is default.
*
* Revision 1.53 1998/01/12 15:04:09 adam
{
zebTargetInfo_close (zi->zti, 0);
dict_close (zi->dict);
+ sortIdx_close (zi->sortIdx);
if (zi->isam)
is_close (zi->isam);
if (zi->isamc)
zi->records = rec_open (zi->bfs, 0);
if (!(zi->dict = dict_open (zi->bfs, FNAME_DICT, 40, 0)))
return -1;
+ if (!(zi->sortIdx = sortIdx_open (zi->bfs, 0)))
+ return -1;
zi->isam = NULL;
zi->isamc = NULL;
if (!res_get_match (zi->res, "isam", "i", NULL))
zebra_server_unlock (zi, zi->registerState);
}
+static int bend_sort (void *handle, bend_sort_rr *rr);
+
bend_initresult *bend_init (bend_initrequest *q)
{
bend_initresult *r = odr_malloc (q->stream, sizeof(*r));
r->errcode = 0;
r->errstring = 0;
r->handle = zi;
+ q->bend_sort = bend_sort;
logf (LOG_DEBUG, "bend_init");
zi->registerChange = 0;
zi->records = NULL;
- zi->odr = odr_createmem (ODR_ENCODE);
zi->registered_sets = NULL;
zi->zebra_maps = zebra_maps_open (res_get(zi->res, "profilePath"),
zi->res);
r->hits = 0;
register_lock (zi);
- odr_reset (zi->odr);
zi->errCode = 0;
zi->errString = NULL;
switch (q->query->which)
{
case Z_Query_type_1: case Z_Query_type_101:
- r->errcode = rpn_search (zi, q->query->u.type_1,
+ r->errcode = rpn_search (zi, q->stream, q->query->u.type_1,
q->num_bases, q->basenames, q->setname,
&r->hits);
r->errstring = zi->errString;
r->last_in_set = 0;
r->basename = "base";
- odr_reset (zi->odr);
zi->errCode = 0;
positions[0] = q->number;
int status;
register_lock (zi);
- odr_reset (zi->odr);
zi->errCode = 0;
zi->errString = 0;
r->term_position = q->term_position;
r->num_entries = q->num_entries;
- r->errcode = rpn_scan (zi, q->term,
+ r->errcode = rpn_scan (zi, q->stream, q->term,
q->attributeset,
q->num_bases, q->basenames,
&r->term_position,
resultSetDestroy (zi);
zebTargetInfo_close (zi->zti, 0);
dict_close (zi->dict);
+ sortIdx_close (zi->sortIdx);
if (zi->isam)
is_close (zi->isam);
if (zi->isamc)
rec_close (&zi->records);
register_unlock (zi);
}
- odr_destroy (zi->odr);
zebra_maps_close (zi->zebra_maps);
bfs_destroy (zi->bfs);
data1_destroy (zi->dh);
}
#endif
+int bend_sort (void *handle, bend_sort_rr *rr)
+{
+ ZServerInfo *zi = handle;
+
+#if 1
+ register_lock (zi);
+
+ resultSetSort (zi, rr);
+
+ register_unlock (zi);
+#endif
+ return 0;
+}
+
int main (int argc, char **argv)
{
struct statserv_options_block *sob;
* Sebastian Hammer, Adam Dickmeiss
*
* $Log: zserver.h,v $
- * Revision 1.28 1998-01-29 13:40:11 adam
+ * Revision 1.29 1998-02-10 12:03:06 adam
+ * Implemented Sort.
+ *
+ * Revision 1.28 1998/01/29 13:40:11 adam
* Better logging for scan service.
*
* Revision 1.27 1997/10/27 14:33:06 adam
#include <backend.h>
#include <rset.h>
+#include <sortidx.h>
#include "index.h"
#include "zinfo.h"
char *name;
RSET rset;
int size;
+ struct zset_sort_info *sort_info;
struct ZServerSet_ *next;
} ZServerSet;
time_t registerChange;
ZServerSet *sets;
Dict dict;
+ SortIdx sortIdx;
ISAM isam;
ISAMC isamc;
Records records;
int errCode;
char *errString;
- ODR odr;
ZebTargetInfo *zti;
data1_handle dh;
data1_attset *registered_sets;
ZebraMaps zebra_maps;
} ZServerInfo;
-int rpn_search (ZServerInfo *zi,
+int rpn_search (ZServerInfo *zi, ODR stream,
Z_RPNQuery *rpn, int num_bases, char **basenames,
const char *setname, int *hits);
-int rpn_scan (ZServerInfo *zi, Z_AttributesPlusTerm *zapt,
+int rpn_scan (ZServerInfo *zi, ODR stream, Z_AttributesPlusTerm *zapt,
oid_value attributeset,
int num_bases, char **basenames,
int *position, int *num_entries, struct scan_entry **list,
ZServerSetSysno *resultSetSysnoGet (ZServerInfo *zi, const char *name,
int num, int *positions);
void resultSetSysnoDel (ZServerInfo *zi, ZServerSetSysno *records, int num);
+
+int resultSetSort (ZServerInfo *zi, bend_sort_rr *rr);
+
void zlog_rpn (Z_RPNQuery *rpn);
void zlog_scan (Z_AttributesPlusTerm *zapt, oid_value ast);
/*
- * Copyright (C) 1994-1995, Index Data I/S
+ * Copyright (C) 1994-1998, Index Data I/S
* All rights reserved.
* Sebastian Hammer, Adam Dickmeiss
*
* $Log: zsets.c,v $
- * Revision 1.12 1997-09-25 14:57:36 adam
+ * Revision 1.13 1998-02-10 12:03:06 adam
+ * Implemented Sort.
+ *
+ * Revision 1.12 1997/09/25 14:57:36 adam
* Windows NT port.
*
* Revision 1.11 1996/12/23 15:30:46 adam
#include "zserver.h"
#include <rstemp.h>
+#define SORT_IDX_ENTRYSIZE 64
+#define ZSET_SORT_MAX_LEVEL 3
+
+struct zset_sort_entry {
+ int sysno;
+ char buf[ZSET_SORT_MAX_LEVEL][SORT_IDX_ENTRYSIZE];
+};
+
+struct zset_sort_info {
+ int max_entries;
+ int num_entries;
+ struct zset_sort_entry **entries;
+};
+
+void resultSetSortReset (struct zset_sort_info **si)
+{
+ int i;
+ if (!*si)
+ return ;
+ for (i = 0; i<(*si)->num_entries; i++)
+ xfree ((*si)->entries[i]);
+ xfree ((*si)->entries);
+ xfree (*si);
+ *si = NULL;
+}
+
ZServerSet *resultSetAdd (ZServerInfo *zi, const char *name, int ov, RSET rset)
{
ZServerSet *s;
for (s = zi->sets; s; s = s->next)
if (!strcmp (s->name, name))
{
+ logf (LOG_DEBUG, "updating result set %s", name);
if (!ov)
return NULL;
+ resultSetSortReset (&s->sort_info);
rset_delete (s->rset);
s->rset = rset;
return s;
}
+ logf (LOG_DEBUG, "adding result set %s", name);
s = xmalloc (sizeof(*s));
s->next = zi->sets;
zi->sets = s;
s->name = xmalloc (strlen(name)+1);
strcpy (s->name, name);
s->rset = rset;
+ s->sort_info = NULL;
return s;
}
return NULL;
}
+
void resultSetDestroy (ZServerInfo *zi)
{
ZServerSet *s, *s1;
for (s = zi->sets; s; s = s1)
{
s1 = s->next;
+ resultSetSortReset (&s->sort_info);
rset_delete (s->rset);
xfree (s->name);
xfree (s);
ZServerSet *sset;
ZServerSetSysno *sr;
RSET rset;
- int num_i = 0;
- int position = 0;
- int psysno = 0;
- struct it_key key;
- RSFD rfd;
+ int i;
+ struct zset_sort_info *sort_info;
if (!(sset = resultSetGet (zi, name)))
return NULL;
if (!(rset = sset->rset))
return NULL;
- logf (LOG_DEBUG, "resultSetRecordGet");
sr = xmalloc (sizeof(*sr) * num);
- rfd = rset_open (rset, RSETF_READ|RSETF_SORT_RANK);
- while (rset_read (rset, rfd, &key))
+ for (i = 0; i<num; i++)
{
- if (key.sysno != psysno)
- {
- psysno = key.sysno;
- position++;
- assert (num_i < num);
- if (position == positions[num_i])
- {
- sr[num_i].sysno = psysno;
- rset_score (rset, rfd, &sr[num_i].score);
- if (++num_i == num)
- break;
- }
- }
+ sr[i].sysno = 0;
+ sr[i].score = -1;
}
- rset_close (rset, rfd);
- while (num_i < num)
+ sort_info = sset->sort_info;
+ if (sort_info)
{
- sr[num_i].sysno = 0;
- num_i++;
+ int position;
+
+ for (i = 0; i<num; i++)
+ {
+ position = positions[i];
+ if (position <= sort_info->num_entries)
+ {
+ logf (LOG_DEBUG, "got pos=%d (sorted)", position);
+ sr[i].sysno = sort_info->entries[position-1]->sysno;
+ }
+ }
+ }
+ /* did we really get all entries using sort ? */
+ for (i = 0; i<num; i++)
+ {
+ if (!sr[i].sysno)
+ break;
+ }
+ if (i < num) /* nope, get the rest, unsorted - sorry */
+ {
+ int position = 0;
+ int num_i = 0;
+ int psysno = 0;
+ RSFD rfd;
+ struct it_key key;
+
+ if (sort_info)
+ position = sort_info->num_entries;
+ while (num_i < num && positions[num_i] < position)
+ num_i++;
+ rfd = rset_open (rset, RSETF_READ|RSETF_SORT_RANK);
+ while (num_i < num && rset_read (rset, rfd, &key))
+ {
+ if (key.sysno != psysno)
+ {
+ psysno = key.sysno;
+ if (sort_info)
+ {
+ /* determine we alreay have this in our set */
+ for (i = sort_info->num_entries; --i >= 0; )
+ if (psysno == sort_info->entries[i]->sysno)
+ break;
+ if (i >= 0)
+ continue;
+ }
+ position++;
+ assert (num_i < num);
+ if (position == positions[num_i])
+ {
+ sr[num_i].sysno = psysno;
+ logf (LOG_DEBUG, "got pos=%d (unsorted)", position);
+ rset_score (rset, rfd, &sr[num_i].score);
+ num_i++;
+ }
+ }
+ }
+ rset_close (rset, rfd);
}
return sr;
}
{
xfree (records);
}
+
+struct sortKey {
+ int relation;
+ int attrUse;
+};
+
+void resultSetInsertSort (ZServerInfo *zi, ZServerSet *sset,
+ struct sortKey *criteria, int num_criteria,
+ int sysno)
+{
+ struct zset_sort_entry this_entry;
+ struct zset_sort_entry *new_entry = NULL;
+ struct zset_sort_info *sort_info = sset->sort_info;
+ int i, j;
+
+ sortIdx_sysno (zi->sortIdx, sysno);
+ for (i = 0; i<num_criteria; i++)
+ {
+ sortIdx_type (zi->sortIdx, criteria[i].attrUse);
+ sortIdx_read (zi->sortIdx, this_entry.buf[i]);
+ }
+ i = sort_info->num_entries;
+ while (--i >= 0)
+ {
+ int rel = 0;
+ for (j = 0; j<num_criteria; j++)
+ {
+ rel = memcmp (this_entry.buf[j], sort_info->entries[i]->buf[j],
+ SORT_IDX_ENTRYSIZE);
+ if (rel)
+ break;
+ }
+ if (rel)
+ {
+ if (criteria[j].relation == 'D')
+ if (rel > 0)
+ break;
+ if (criteria[j].relation == 'A')
+ if (rel < 0)
+ break;
+ }
+ }
+ j = sort_info->max_entries-1;
+ if (i == j)
+ return;
+ ++i;
+ new_entry = sort_info->entries[j];
+ while (j != i)
+ {
+ sort_info->entries[j] = sort_info->entries[j-1];
+ --j;
+ }
+ sort_info->entries[j] = new_entry;
+ assert (new_entry);
+ if (sort_info->num_entries != sort_info->max_entries)
+ (sort_info->num_entries)++;
+ for (i = 0; i<num_criteria; i++)
+ memcpy (new_entry->buf[i], this_entry.buf[i], SORT_IDX_ENTRYSIZE);
+ new_entry->sysno = sysno;
+}
+
+int resultSetSort (ZServerInfo *zi, bend_sort_rr *rr)
+{
+ ZServerSet *sset;
+ RSET rset;
+ int i, psysno = 0;
+ struct it_key key;
+ struct sortKey sort_criteria[3];
+ int num_criteria;
+ RSFD rfd;
+
+ if (rr->num_input_setnames == 0)
+ {
+ rr->errcode = 208;
+ return 0;
+ }
+ if (rr->num_input_setnames > 1)
+ {
+ rr->errcode = 230;
+ return 0;
+ }
+ sset = resultSetGet (zi, rr->input_setnames[0]);
+ if (!sset)
+ {
+ rr->errcode = 30;
+ rr->errstring = rr->input_setnames[0];
+ return 0;
+ }
+ if (!(rset = sset->rset))
+ {
+ rr->errcode = 30;
+ rr->errstring = rr->input_setnames[0];
+ return 0;
+ }
+ num_criteria = rr->sort_sequence->num_specs;
+ if (num_criteria > 3)
+ num_criteria = 3;
+ for (i = 0; i < num_criteria; i++)
+ {
+ Z_SortKeySpec *sks = rr->sort_sequence->specs[i];
+ Z_SortKey *sk;
+
+ if (*sks->sortRelation == Z_SortRelation_ascending)
+ sort_criteria[i].relation = 'A';
+ else if (*sks->sortRelation == Z_SortRelation_descending)
+ sort_criteria[i].relation = 'D';
+ else
+ {
+ rr->errcode = 214;
+ return 0;
+ }
+ if (sks->sortElement->which == Z_SortElement_databaseSpecific)
+ {
+ rr->errcode = 210;
+ return 0;
+ }
+ else if (sks->sortElement->which != Z_SortElement_generic)
+ {
+ rr->errcode = 237;
+ return 0;
+ }
+ sk = sks->sortElement->u.generic;
+ switch (sk->which)
+ {
+ case Z_SortKey_sortField:
+ logf (LOG_DEBUG, "Sort: key %d is of type sortField", i+1);
+ rr->errcode = 207;
+ return 0;
+ case Z_SortKey_elementSpec:
+ logf (LOG_DEBUG, "Sort: key %d is of type elementSpec", i+1);
+ return 0;
+ case Z_SortKey_sortAttributes:
+ logf (LOG_DEBUG, "Sort: key %d is of type sortAttributes", i+1);
+ sort_criteria[i].attrUse =
+ zebra_maps_sort (zi->zebra_maps, sk->u.sortAttributes);
+ logf (LOG_DEBUG, "use value = %d", sort_criteria[i].attrUse);
+ if (sort_criteria[i].attrUse == -1)
+ {
+ rr->errcode = 116;
+ return 0;
+ }
+ if (sortIdx_type (zi->sortIdx, sort_criteria[i].attrUse))
+ {
+ rr->errcode = 207;
+ return 0;
+ }
+ break;
+ }
+ }
+ if (strcmp (rr->output_setname, rr->input_setnames[0]))
+ {
+ rset = rset_dup (rset);
+ sset = resultSetAdd (zi, rr->output_setname, 1, rset);
+ }
+ resultSetSortReset (&sset->sort_info);
+
+ sset->sort_info = xmalloc (sizeof(*sset->sort_info));
+ sset->sort_info->max_entries = 10;
+ sset->sort_info->num_entries = 0;
+ sset->sort_info->entries = xmalloc (sizeof(*sset->sort_info->entries) *
+ sset->sort_info->max_entries);
+ for (i = 0; i<sset->sort_info->max_entries; i++)
+ sset->sort_info->entries[i] =
+ xmalloc (sizeof(*sset->sort_info->entries[i]));
+
+
+ rfd = rset_open (rset, RSETF_READ|RSETF_SORT_SYSNO);
+ while (rset_read (rset, rfd, &key))
+ {
+ if (key.sysno != psysno)
+ {
+ psysno = key.sysno;
+ resultSetInsertSort (zi, sset,
+ sort_criteria, num_criteria, psysno);
+ }
+ }
+ rset_close (rset, rfd);
+
+ rr->errcode = 0;
+ rr->sort_status = Z_SortStatus_success;
+
+ return 0;
+}
+
* Sebastian Hammer, Adam Dickmeiss
*
* $Log: recgrs.c,v $
- * Revision 1.16 1998-01-29 13:38:17 adam
+ * Revision 1.17 1998-02-10 12:03:06 adam
+ * Implemented Sort.
+ *
+ * Revision 1.16 1998/01/29 13:38:17 adam
* Fixed problem with mapping to record with unknown schema.
*
* Revision 1.15 1998/01/26 10:37:57 adam
#include <oid.h>
#include <recctrl.h>
-#include <charmap.h>
#include "grsread.h"
#define GRS_MAX_WORD 512
{
}
-static void dumpkeys_incomplete_field(data1_node *n, struct recExtractCtrl *p,
- data1_att *att, int reg_type)
-{
- const char *b = n->u.data.data;
- int remain;
- const char **map = 0;
-
- remain = n->u.data.len - (b - n->u.data.data);
- if (remain > 0)
- map = zebra_maps_input(p->zebra_maps, reg_type, &b, remain);
-
- while (map)
- {
- RecWord wrd;
- char buf[GRS_MAX_WORD+1];
- int i, remain;
-
- /* Skip spaces */
- while (map && *map && **map == *CHR_SPACE)
- {
- remain = n->u.data.len - (b - n->u.data.data);
- if (remain > 0)
- map = zebra_maps_input(p->zebra_maps, reg_type, &b, remain);
- else
- map = 0;
- }
- if (!map)
- break;
- i = 0;
- while (map && *map && **map != *CHR_SPACE)
- {
- const char *cp = *map;
-
- while (i < GRS_MAX_WORD && *cp)
- buf[i++] = *(cp++);
- remain = n->u.data.len - (b - n->u.data.data);
- if (remain > 0)
- map = zebra_maps_input(p->zebra_maps, reg_type, &b, remain);
- else
- map = 0;
- }
- if (!i)
- return;
- buf[i] = '\0';
- (*p->init)(&wrd); /* set defaults */
- wrd.reg_type = reg_type;
- wrd.seqno = seqno++;
- wrd.string = buf;
- wrd.attrSet = att->parent->ordinal;
- wrd.attrUse = att->locals->local;
- (*p->add)(&wrd);
- }
-}
-
-static void dumpkeys_complete_field(data1_node *n, struct recExtractCtrl *p,
- data1_att *att, int reg_type)
-{
- const char *b = n->u.data.data;
- char buf[GRS_MAX_WORD+1];
- const char **map = 0;
- RecWord wrd;
- int i = 0, remain;
-
- remain = n->u.data.len - (b - n->u.data.data);
- if (remain > 0)
- map = zebra_maps_input (p->zebra_maps, reg_type, &b, remain);
-
- while (remain > 0 && i < GRS_MAX_WORD)
- {
- while (map && *map && **map == *CHR_SPACE)
- {
- remain = n->u.data.len - (b - n->u.data.data);
- if (remain > 0)
- map = zebra_maps_input(p->zebra_maps, reg_type, &b, remain);
- else
- map = 0;
- }
- if (!map)
- break;
-
- if (i && i < GRS_MAX_WORD)
- buf[i++] = *CHR_SPACE;
- while (map && *map && **map != *CHR_SPACE)
- {
- const char *cp = *map;
-
- if (i >= GRS_MAX_WORD)
- break;
- while (i < GRS_MAX_WORD && *cp)
- buf[i++] = *(cp++);
- remain = n->u.data.len - (b - n->u.data.data);
- if (remain > 0)
- map = zebra_maps_input (p->zebra_maps, reg_type, &b, remain);
- else
- map = 0;
- }
- }
- if (!i)
- return;
- buf[i] = '\0';
- (*p->init)(&wrd);
-
- wrd.reg_type = reg_type;
- wrd.seqno = seqno++;
- wrd.string = buf;
- wrd.attrSet = att->parent->ordinal;
- wrd.attrUse = att->locals->local;
- (*p->add)(&wrd);
-}
-
static int dumpkeys(data1_node *n, struct recExtractCtrl *p, int level)
{
+ RecWord wrd;
+ (*p->init)(p, &wrd); /* set defaults */
for (; n; n = n->next)
{
if (p->flagShowRecords) /* display element description to user */
tlist->att->name, tlist->att->value);
}
else
- if (zebra_maps_is_complete (p->zebra_maps,
- *tlist->structure))
- dumpkeys_complete_field(n, p, tlist->att,
- *tlist->structure);
- else
- dumpkeys_incomplete_field(n, p, tlist->att,
- *tlist->structure);
+ {
+ wrd.reg_type = *tlist->structure;
+ wrd.seqno = seqno;
+ wrd.string = n->u.data.data;
+ wrd.length = n->u.data.len;
+ wrd.attrSet = tlist->att->parent->ordinal;
+ wrd.attrUse = tlist->att->locals->local;
+ (*p->add)(&wrd);
+ seqno = wrd.seqno;
+ }
}
}
if (p->flagShowRecords && n->which == DATA1N_root)
/*
- * Copyright (C) 1994-1995, Index Data I/S
+ * Copyright (C) 1994-1998, Index Data I/S
* All rights reserved.
* Sebastian Hammer, Adam Dickmeiss
*
* $Log: rectext.c,v $
- * Revision 1.5 1997-10-27 14:33:06 adam
+ * Revision 1.6 1998-02-10 12:03:06 adam
+ * Implemented Sort.
+ *
+ * Revision 1.5 1997/10/27 14:33:06 adam
* Moved towards generic character mapping depending on "structure"
* field in abstract syntax file. Fixed a few memory leaks. Fixed
* bug with negative integers when doing searches with relational
static int text_extract (struct recExtractCtrl *p)
{
- char w[256];
+ char w[512];
RecWord recWord;
int r, seqno = 1;
struct buf_info *fi = buf_open (p);
- (*p->init)(&recWord);
+ (*p->init)(p, &recWord);
recWord.reg_type = 'w';
do
{
int i = 0;
r = buf_read (fi, w);
- while (r > 0 && i < 255 && isalnum(w[i]))
+ while (r > 0 && i < 511 && w[i] != '\n' && w[i] != '\r')
{
i++;
r = buf_read (fi, w + i);
}
if (i)
{
- int j;
- for (j = 0; j<i; j++)
- w[j] = tolower(w[j]);
- w[i] = 0;
recWord.seqno = seqno++;
recWord.string = w;
+ recWord.length = i;
(*p->add)(&recWord);
}
} while (r > 0);
# Zebra indexes as referred to from the *.abs-files.
-# $Id: default.idx,v 1.3 1998-01-26 10:36:49 adam Exp $
+# $Id: default.idx,v 1.4 1998-02-10 12:03:06 adam Exp $
#
# Traditional word index
index w
index 0
completeness 0
charmap @
+
+# Sort register (no mapping at all)
+sort s
+completeness 1
+charmap @
* Sebastian Hammer, Adam Dickmeiss
*
* $Log: zebramap.c,v $
- * Revision 1.6 1998-01-29 13:36:01 adam
+ * Revision 1.7 1998-02-10 12:03:07 adam
+ * Implemented Sort.
+ *
+ * Revision 1.6 1998/01/29 13:36:01 adam
* Structure word-list, free-form-text and document-text all
* trigger ranked search.
*
struct zebra_map {
int reg_type;
int completeness;
+ int sort_flag;
chrmaptab maptab;
const char *maptab_name;
struct zebra_map *next;
struct zebra_map *map_list;
char temp_map_str[2];
const char *temp_map_ptr[2];
+ struct zebra_map **lookup_array;
};
void zebra_maps_close (ZebraMaps zms)
char line[512];
char *argv[10];
int argc;
- struct zebra_map **zm = 0;
+ struct zebra_map **zm = 0, *zp;
if (!(f = yaz_path_fopen(zms->tabpath, name, "r")))
{
(*zm)->reg_type = argv[1][0];
(*zm)->maptab_name = NULL;
(*zm)->maptab = NULL;
+ (*zm)->sort_flag = 0;
+ (*zm)->completeness = 0;
+ }
+ else if (!strcmp (argv[0], "sort") && argc == 2)
+ {
+ if (!zm)
+ zm = &zms->map_list;
+ else
+ zm = &(*zm)->next;
+ *zm = nmem_malloc (zms->nmem, sizeof(**zm));
+ (*zm)->reg_type = argv[1][0];
+ (*zm)->maptab_name = NULL;
+ (*zm)->sort_flag = 1;
+ (*zm)->maptab = NULL;
(*zm)->completeness = 0;
}
else if (zm && !strcmp (argv[0], "charmap") && argc == 2)
if (zm)
(*zm)->next = NULL;
fclose (f);
+
+ for (zp = zms->map_list; zp; zp = zp->next)
+ zms->lookup_array[zp->reg_type & 255] = zp;
}
+
static void zms_map_handle (void *p, const char *name, const char *value)
{
ZebraMaps zms = p;
ZebraMaps zebra_maps_open (const char *tabpath, Res res)
{
ZebraMaps zms = xmalloc (sizeof(*zms));
+ int i;
zms->nmem = nmem_create ();
zms->tabpath = nmem_strdup (zms->nmem, tabpath);
zms->temp_map_ptr[0] = zms->temp_map_str;
zms->temp_map_ptr[1] = NULL;
-
+
+ zms->lookup_array =
+ nmem_malloc (zms->nmem, sizeof(*zms->lookup_array)*256);
+ for (i = 0; i<256; i++)
+ zms->lookup_array[i] = 0;
if (!res_trav (res, "index", zms, zms_map_handle))
zebra_map_read (zms, "default.idx");
return zms;
}
-chrmaptab zebra_map_get (ZebraMaps zms, int reg_type)
+struct zebra_map *zebra_map_get (ZebraMaps zms, int reg_type)
{
- struct zebra_map *zm;
-
- for (zm = zms->map_list; zm; zm = zm->next)
- if (reg_type == zm->reg_type)
- break;
+ return zms->lookup_array[reg_type];
+}
+
+chrmaptab zebra_charmap_get (ZebraMaps zms, int reg_type)
+{
+ struct zebra_map *zm = zebra_map_get (zms, reg_type);
if (!zm)
{
logf (LOG_WARN, "Unknown register type: %c", reg_type);
{
chrmaptab maptab;
- maptab = zebra_map_get (zms, reg_type);
+ maptab = zebra_charmap_get (zms, reg_type);
if (maptab)
return chr_map_input(maptab, from, len);
unsigned char i = (unsigned char) **from;
static char buf[2] = {0,0};
- maptab = zebra_map_get (zms, reg_type);
+ maptab = zebra_charmap_get (zms, reg_type);
if (maptab)
return chr_map_output (maptab, from, 1);
(*from)++;
int type;
int major;
int minor;
- Z_AttributesPlusTerm *zapt;
+ Z_AttributeElement **attributeList;
+ int num_attributes;
} AttrType;
static int attr_find (AttrType *src, oid_value *attributeSetP)
{
- while (src->major < src->zapt->num_attributes)
+ while (src->major < src->num_attributes)
{
Z_AttributeElement *element;
- element = src->zapt->attributeList[src->major];
+ element = src->attributeList[src->major];
if (src->type == *element->attributeType)
{
switch (element->which)
return -1;
}
-static void attr_init (AttrType *src, Z_AttributesPlusTerm *zapt,
- int type)
+static void attr_init_APT (AttrType *src, Z_AttributesPlusTerm *zapt, int type)
+{
+
+ src->attributeList = zapt->attributeList;
+ src->num_attributes = zapt->num_attributes;
+ src->type = type;
+ src->major = 0;
+ src->minor = 0;
+}
+
+static void attr_init_AttrList (AttrType *src, Z_AttributeList *list, int type)
{
- src->zapt = zapt;
+ src->attributeList = list->attributes;
+ src->num_attributes = list->num_attributes;
src->type = type;
src->major = 0;
src->minor = 0;
int zebra_maps_is_complete (ZebraMaps zms, int reg_type)
{
- struct zebra_map *zm;
-
- for (zm = zms->map_list; zm; zm = zm->next)
- if (reg_type == zm->reg_type)
- return zm->completeness;
+ struct zebra_map *zm = zebra_map_get (zms, reg_type);
+ if (zm)
+ return zm->completeness;
return 0;
}
+int zebra_maps_is_sort (ZebraMaps zms, int reg_type)
+{
+ struct zebra_map *zm = zebra_map_get (zms, reg_type);
+ if (zm)
+ return zm->sort_flag;
+ return 0;
+}
+
+int zebra_maps_sort (ZebraMaps zms, Z_SortAttributes *sortAttributes)
+{
+ AttrType use;
+ attr_init_AttrList (&use, sortAttributes->list, 1);
+
+ return attr_find (&use, NULL);
+}
+
int zebra_maps_attr (ZebraMaps zms, Z_AttributesPlusTerm *zapt,
int *reg_type, char **search_type, int *complete_flag)
{
int structure_value;
int relation_value;
- attr_init (&structure, zapt, 4);
- attr_init (&completeness, zapt, 6);
- attr_init (&relation, zapt, 2);
+ attr_init_APT (&structure, zapt, 4);
+ attr_init_APT (&completeness, zapt, 6);
+ attr_init_APT (&relation, zapt, 2);
completeness_value = attr_find (&completeness, NULL);
structure_value = attr_find (&structure, NULL);