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.
8 #include <yaz/copy_types.h>
9 #include <yazpp/record-cache.h>
11 using namespace yazpp_1;
13 struct yazpp_1::RecordCache_Entry {
15 Z_NamePlusRecord *m_record;
16 Z_RecordComposition *m_comp;
17 RecordCache_Entry *m_next;
20 RecordCache::RecordCache ()
22 m_mem = nmem_create();
29 RecordCache::~RecordCache ()
34 void RecordCache::set_max_size(size_t sz)
39 void RecordCache::clear ()
42 m_mem = nmem_create();
48 void RecordCache::copy_searchRequest(Z_SearchRequest *sr)
50 ODR encode = odr_createmem(ODR_ENCODE);
51 ODR decode = odr_createmem(ODR_DECODE);
55 int v = z_SearchRequest (encode, &sr, 1, 0);
59 char *buf = odr_getbuf(encode, &len, 0);
60 odr_setbuf(decode, buf, len, 0);
61 z_SearchRequest(decode, &m_searchRequest, 1, 0);
62 nmem_transfer(m_mem, decode->mem);
68 void RecordCache::copy_presentRequest(Z_PresentRequest *pr)
70 ODR encode = odr_createmem(ODR_ENCODE);
71 ODR decode = odr_createmem(ODR_DECODE);
75 int v = z_PresentRequest (encode, &pr, 1, 0);
79 char *buf = odr_getbuf(encode, &len, 0);
80 odr_setbuf(decode, buf, len, 0);
81 z_PresentRequest(decode, &m_presentRequest, 1, 0);
82 nmem_transfer(m_mem, decode->mem);
89 void RecordCache::add (ODR o, Z_NamePlusRecordList *npr, int start,
92 if (nmem_total(m_mem) > m_max_size)
94 // Build appropriate compspec for this response
95 Z_RecordComposition *comp = 0;
96 if (hits == -1 && m_presentRequest)
97 comp = m_presentRequest->recordComposition;
98 else if (hits > 0 && m_searchRequest)
100 Z_ElementSetNames *esn;
102 if (hits <= *m_searchRequest->smallSetUpperBound)
103 esn = m_searchRequest->smallSetElementSetNames;
105 esn = m_searchRequest->mediumSetElementSetNames;
106 comp = (Z_RecordComposition *) nmem_malloc(m_mem, sizeof(*comp));
107 comp->which = Z_RecordComp_simple;
108 comp->u.simple = esn;
111 // Insert individual records in cache
113 for (i = 0; i<npr->num_records; i++)
115 RecordCache_Entry *entry = (RecordCache_Entry *)
116 nmem_malloc(m_mem, sizeof(*entry));
117 entry->m_record = yaz_clone_z_NamePlusRecord(npr->records[i], m_mem);
118 entry->m_comp = yaz_clone_z_RecordComposition(comp, m_mem);
119 entry->m_offset = i + start;
120 entry->m_next = m_entries;
125 int RecordCache::match (RecordCache_Entry *entry,
126 Odr_oid *syntax, int offset,
127 Z_RecordComposition *comp)
129 // See if our compspec match...
131 ODR o1 = odr_createmem(ODR_ENCODE);
132 ODR o2 = odr_createmem(ODR_ENCODE);
134 z_RecordComposition(o1, &comp, 1, 0);
135 z_RecordComposition(o2, &entry->m_comp, 1, 0);
138 char *buf1 = odr_getbuf(o1, &len1, 0);
140 char *buf2 = odr_getbuf(o2, &len2, 0);
142 if (buf1 && buf2 && len1 && len1 == len2 && !memcmp(buf1, buf2, len1))
144 else if (!buf1 && !buf2 && !len1 && !len2)
153 // See if offset, OID match..
154 if (entry->m_offset == offset &&
155 entry->m_record->which == Z_NamePlusRecord_databaseRecord &&
156 !oid_oidcmp(entry->m_record->u.databaseRecord->direct_reference,
161 oid_to_dotstring(entry->m_record->u.databaseRecord->direct_reference, mstr1);
163 oid_to_dotstring(syntax, mstr2);
164 yaz_log(YLOG_LOG, "match fail 3 d=%s s=%s", mstr1, mstr2);
170 int RecordCache::lookup (ODR o, Z_NamePlusRecordList **npr,
173 Z_RecordComposition *comp)
176 yaz_log(YLOG_DEBUG, "cache lookup start=%d num=%d", start, num);
178 for (i = 0; i<num; i++)
180 RecordCache_Entry *entry = m_entries;
181 for(; entry; entry = entry->m_next)
182 if (match(entry, syntax, start+i, comp))
187 *npr = (Z_NamePlusRecordList *) odr_malloc(o, sizeof(**npr));
188 (*npr)->num_records = num;
189 (*npr)->records = (Z_NamePlusRecord **)
190 odr_malloc(o, num * sizeof(Z_NamePlusRecord *));
191 for (i = 0; i<num; i++)
193 RecordCache_Entry *entry = m_entries;
194 for(; entry; entry = entry->m_next)
195 if (match(entry, syntax, start+i, comp))
199 (*npr)->records[i] = (Z_NamePlusRecord *)
200 odr_malloc(o, sizeof(Z_NamePlusRecord));
201 (*npr)->records[i]->databaseName = entry->m_record->databaseName;
202 (*npr)->records[i]->which = entry->m_record->which;
203 (*npr)->records[i]->u.databaseRecord =
204 entry->m_record->u.databaseRecord;
211 * c-file-style: "Stroustrup"
212 * indent-tabs-mode: nil
214 * vim: shiftwidth=4 tabstop=8 expandtab