1 /* This file is part of the yazpp toolkit.
2 * Copyright (C) 1998-2013 Index Data and Mike Taylor
3 * See the file LICENSE for details.
10 #include <yaz/proto.h>
11 #include <yaz/copy_types.h>
12 #include <yazpp/record-cache.h>
14 using namespace yazpp_1;
16 struct RecordCache::Rep {
18 RecordCache_Entry *entries;
19 Z_SearchRequest *searchRequest;
20 Z_PresentRequest *presentRequest;
21 int match(RecordCache_Entry *entry, Odr_oid *syntax, int offset,
22 Z_RecordComposition *comp);
26 struct RecordCache::RecordCache_Entry {
28 Z_NamePlusRecord *m_record;
29 Z_RecordComposition *m_comp;
30 RecordCache_Entry *m_next;
33 RecordCache::RecordCache ()
36 m_p->nmem = nmem_create();
38 m_p->presentRequest = 0;
39 m_p->searchRequest = 0;
40 m_p->max_size = 200000;
43 RecordCache::~RecordCache ()
45 nmem_destroy(m_p->nmem);
49 void RecordCache::set_max_size(size_t sz)
54 void RecordCache::clear ()
56 nmem_destroy(m_p->nmem);
57 m_p->nmem = nmem_create();
59 m_p->presentRequest = 0;
60 m_p->searchRequest = 0;
63 void RecordCache::copy_searchRequest(Z_SearchRequest *sr)
65 ODR encode = odr_createmem(ODR_ENCODE);
66 ODR decode = odr_createmem(ODR_DECODE);
68 m_p->searchRequest = 0;
69 m_p->presentRequest = 0;
70 int v = z_SearchRequest (encode, &sr, 1, 0);
74 char *buf = odr_getbuf(encode, &len, 0);
75 odr_setbuf(decode, buf, len, 0);
76 z_SearchRequest(decode, &m_p->searchRequest, 1, 0);
77 nmem_transfer(m_p->nmem, decode->mem);
83 void RecordCache::copy_presentRequest(Z_PresentRequest *pr)
85 ODR encode = odr_createmem(ODR_ENCODE);
86 ODR decode = odr_createmem(ODR_DECODE);
88 m_p->searchRequest = 0;
89 m_p->presentRequest = 0;
90 int v = z_PresentRequest (encode, &pr, 1, 0);
94 char *buf = odr_getbuf(encode, &len, 0);
95 odr_setbuf(decode, buf, len, 0);
96 z_PresentRequest(decode, &m_p->presentRequest, 1, 0);
97 nmem_transfer(m_p->nmem, decode->mem);
103 void RecordCache::add(ODR o, Z_NamePlusRecordList *npr, int start,
104 Z_RecordComposition *comp)
106 if (nmem_total(m_p->nmem) > m_p->max_size)
108 // Insert individual records in cache
110 for (i = 0; i < npr->num_records; i++)
112 RecordCache_Entry *entry = (RecordCache_Entry *)
113 nmem_malloc(m_p->nmem, sizeof(*entry));
115 yaz_clone_z_NamePlusRecord(npr->records[i], m_p->nmem);
116 entry->m_comp = yaz_clone_z_RecordComposition(comp, m_p->nmem);
117 entry->m_offset = i + start;
118 entry->m_next = m_p->entries;
119 m_p->entries = entry;
123 void RecordCache::add(ODR o, Z_NamePlusRecordList *npr, int start,
126 // Build appropriate compspec for this response
127 Z_RecordComposition *comp = 0;
128 if (hits == -1 && m_p->presentRequest)
129 comp = m_p->presentRequest->recordComposition;
130 else if (hits > 0 && m_p->searchRequest)
132 Z_ElementSetNames *esn;
134 if (hits <= *m_p->searchRequest->smallSetUpperBound)
135 esn = m_p->searchRequest->smallSetElementSetNames;
137 esn = m_p->searchRequest->mediumSetElementSetNames;
138 comp = (Z_RecordComposition *) nmem_malloc(m_p->nmem, sizeof(*comp));
139 comp->which = Z_RecordComp_simple;
140 comp->u.simple = esn;
142 add(o, npr, start, comp);
145 int RecordCache::Rep::match(RecordCache_Entry *entry,
146 Odr_oid *syntax, int offset,
147 Z_RecordComposition *comp)
149 // See if our compspec match...
151 ODR o1 = odr_createmem(ODR_ENCODE);
152 ODR o2 = odr_createmem(ODR_ENCODE);
154 z_RecordComposition(o1, &comp, 1, 0);
155 z_RecordComposition(o2, &entry->m_comp, 1, 0);
158 char *buf1 = odr_getbuf(o1, &len1, 0);
160 char *buf2 = odr_getbuf(o2, &len2, 0);
162 if (buf1 && buf2 && len1 && len1 == len2 && !memcmp(buf1, buf2, len1))
164 else if (!buf1 && !buf2 && !len1 && !len2)
173 // See if offset, OID match..
174 if (entry->m_offset == offset &&
175 entry->m_record->which == Z_NamePlusRecord_databaseRecord &&
176 !oid_oidcmp(entry->m_record->u.databaseRecord->direct_reference,
181 oid_to_dotstring(entry->m_record->u.databaseRecord->direct_reference, mstr1);
183 oid_to_dotstring(syntax, mstr2);
184 yaz_log(YLOG_LOG, "match fail 3 d=%s s=%s", mstr1, mstr2);
190 int RecordCache::lookup(ODR o, Z_NamePlusRecordList **npr,
193 Z_RecordComposition *comp)
196 yaz_log(YLOG_DEBUG, "cache lookup start=%d num=%d", start, num);
198 for (i = 0; i<num; i++)
200 RecordCache_Entry *entry = m_p->entries;
201 for(; entry; entry = entry->m_next)
202 if (m_p->match(entry, syntax, start+i, comp))
207 *npr = (Z_NamePlusRecordList *) odr_malloc(o, sizeof(**npr));
208 (*npr)->num_records = num;
209 (*npr)->records = (Z_NamePlusRecord **)
210 odr_malloc(o, num * sizeof(Z_NamePlusRecord *));
211 for (i = 0; i<num; i++)
213 RecordCache_Entry *entry = m_p->entries;
214 for(; entry; entry = entry->m_next)
215 if (m_p->match(entry, syntax, start+i, comp))
219 (*npr)->records[i] = (Z_NamePlusRecord *)
220 odr_malloc(o, sizeof(Z_NamePlusRecord));
221 (*npr)->records[i]->databaseName = entry->m_record->databaseName;
222 (*npr)->records[i]->which = entry->m_record->which;
223 (*npr)->records[i]->u.databaseRecord =
224 entry->m_record->u.databaseRecord;
231 * c-file-style: "Stroustrup"
232 * indent-tabs-mode: nil
234 * vim: shiftwidth=4 tabstop=8 expandtab