1 /* This file is part of the yazpp toolkit.
2 * Copyright (C) 1998-2011 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 yazpp_1::RecordCache_Entry {
18 Z_NamePlusRecord *m_record;
19 Z_RecordComposition *m_comp;
20 RecordCache_Entry *m_next;
23 RecordCache::RecordCache ()
25 m_mem = nmem_create();
32 RecordCache::~RecordCache ()
37 void RecordCache::set_max_size(size_t sz)
42 void RecordCache::clear ()
45 m_mem = nmem_create();
51 void RecordCache::copy_searchRequest(Z_SearchRequest *sr)
53 ODR encode = odr_createmem(ODR_ENCODE);
54 ODR decode = odr_createmem(ODR_DECODE);
58 int v = z_SearchRequest (encode, &sr, 1, 0);
62 char *buf = odr_getbuf(encode, &len, 0);
63 odr_setbuf(decode, buf, len, 0);
64 z_SearchRequest(decode, &m_searchRequest, 1, 0);
65 nmem_transfer(m_mem, decode->mem);
71 void RecordCache::copy_presentRequest(Z_PresentRequest *pr)
73 ODR encode = odr_createmem(ODR_ENCODE);
74 ODR decode = odr_createmem(ODR_DECODE);
78 int v = z_PresentRequest (encode, &pr, 1, 0);
82 char *buf = odr_getbuf(encode, &len, 0);
83 odr_setbuf(decode, buf, len, 0);
84 z_PresentRequest(decode, &m_presentRequest, 1, 0);
85 nmem_transfer(m_mem, decode->mem);
92 void RecordCache::add (ODR o, Z_NamePlusRecordList *npr, int start,
95 if (nmem_total(m_mem) > m_max_size)
97 // Build appropriate compspec for this response
98 Z_RecordComposition *comp = 0;
99 if (hits == -1 && m_presentRequest)
100 comp = m_presentRequest->recordComposition;
101 else if (hits > 0 && m_searchRequest)
103 Z_ElementSetNames *esn;
105 if (hits <= *m_searchRequest->smallSetUpperBound)
106 esn = m_searchRequest->smallSetElementSetNames;
108 esn = m_searchRequest->mediumSetElementSetNames;
109 comp = (Z_RecordComposition *) nmem_malloc(m_mem, sizeof(*comp));
110 comp->which = Z_RecordComp_simple;
111 comp->u.simple = esn;
114 // Insert individual records in cache
116 for (i = 0; i<npr->num_records; i++)
118 RecordCache_Entry *entry = (RecordCache_Entry *)
119 nmem_malloc(m_mem, sizeof(*entry));
120 entry->m_record = yaz_clone_z_NamePlusRecord(npr->records[i], m_mem);
121 entry->m_comp = yaz_clone_z_RecordComposition(comp, m_mem);
122 entry->m_offset = i + start;
123 entry->m_next = m_entries;
128 int RecordCache::match (RecordCache_Entry *entry,
129 Odr_oid *syntax, int offset,
130 Z_RecordComposition *comp)
132 // See if our compspec match...
134 ODR o1 = odr_createmem(ODR_ENCODE);
135 ODR o2 = odr_createmem(ODR_ENCODE);
137 z_RecordComposition(o1, &comp, 1, 0);
138 z_RecordComposition(o2, &entry->m_comp, 1, 0);
141 char *buf1 = odr_getbuf(o1, &len1, 0);
143 char *buf2 = odr_getbuf(o2, &len2, 0);
145 if (buf1 && buf2 && len1 && len1 == len2 && !memcmp(buf1, buf2, len1))
147 else if (!buf1 && !buf2 && !len1 && !len2)
156 // See if offset, OID match..
157 if (entry->m_offset == offset &&
158 entry->m_record->which == Z_NamePlusRecord_databaseRecord &&
159 !oid_oidcmp(entry->m_record->u.databaseRecord->direct_reference,
164 oid_to_dotstring(entry->m_record->u.databaseRecord->direct_reference, mstr1);
166 oid_to_dotstring(syntax, mstr2);
167 yaz_log(YLOG_LOG, "match fail 3 d=%s s=%s", mstr1, mstr2);
173 int RecordCache::lookup (ODR o, Z_NamePlusRecordList **npr,
176 Z_RecordComposition *comp)
179 yaz_log(YLOG_DEBUG, "cache lookup start=%d num=%d", start, num);
181 for (i = 0; i<num; i++)
183 RecordCache_Entry *entry = m_entries;
184 for(; entry; entry = entry->m_next)
185 if (match(entry, syntax, start+i, comp))
190 *npr = (Z_NamePlusRecordList *) odr_malloc(o, sizeof(**npr));
191 (*npr)->num_records = num;
192 (*npr)->records = (Z_NamePlusRecord **)
193 odr_malloc(o, num * sizeof(Z_NamePlusRecord *));
194 for (i = 0; i<num; i++)
196 RecordCache_Entry *entry = m_entries;
197 for(; entry; entry = entry->m_next)
198 if (match(entry, syntax, start+i, comp))
202 (*npr)->records[i] = (Z_NamePlusRecord *)
203 odr_malloc(o, sizeof(Z_NamePlusRecord));
204 (*npr)->records[i]->databaseName = entry->m_record->databaseName;
205 (*npr)->records[i]->which = entry->m_record->which;
206 (*npr)->records[i]->u.databaseRecord =
207 entry->m_record->u.databaseRecord;
214 * c-file-style: "Stroustrup"
215 * indent-tabs-mode: nil
217 * vim: shiftwidth=4 tabstop=8 expandtab