2 * Copyright (c) 2002-2003, Index Data.
3 * See the file LICENSE for details.
5 * $Id: yaz-z-cache.cpp,v 1.6 2003-10-08 08:52:59 adam Exp $
9 #include <yaz++/proxy.h>
11 struct Yaz_RecordCache_Entry {
13 Z_NamePlusRecord *m_record;
14 Z_RecordComposition *m_comp;
15 Yaz_RecordCache_Entry *m_next;
18 Yaz_RecordCache::Yaz_RecordCache ()
20 m_mem = nmem_create();
27 Yaz_RecordCache::~Yaz_RecordCache ()
32 void Yaz_RecordCache::set_max_size(int sz)
37 void Yaz_RecordCache::clear ()
40 m_mem = nmem_create();
46 void Yaz_RecordCache::copy_searchRequest(Z_SearchRequest *sr)
48 ODR encode = odr_createmem(ODR_ENCODE);
49 ODR decode = odr_createmem(ODR_DECODE);
53 int v = z_SearchRequest (encode, &sr, 1, 0);
57 char *buf = odr_getbuf(encode, &len, 0);
58 odr_setbuf(decode, buf, len, 0);
59 z_SearchRequest(decode, &m_searchRequest, 1, 0);
60 nmem_transfer(m_mem, decode->mem);
66 void Yaz_RecordCache::copy_presentRequest(Z_PresentRequest *pr)
68 ODR encode = odr_createmem(ODR_ENCODE);
69 ODR decode = odr_createmem(ODR_DECODE);
73 int v = z_PresentRequest (encode, &pr, 1, 0);
77 char *buf = odr_getbuf(encode, &len, 0);
78 odr_setbuf(decode, buf, len, 0);
79 z_PresentRequest(decode, &m_presentRequest, 1, 0);
80 nmem_transfer(m_mem, decode->mem);
86 void Yaz_RecordCache::add (ODR o, Z_NamePlusRecordList *npr, int start,
89 if (nmem_total(m_mem) > m_max_size)
91 // Build appropriate compspec for this response
92 Z_RecordComposition *comp = 0;
93 if (hits == -1 && m_presentRequest)
94 comp = m_presentRequest->recordComposition;
95 else if (hits > 0 && m_searchRequest)
97 Z_ElementSetNames *esn;
99 if (hits <= *m_searchRequest->smallSetUpperBound)
100 esn = m_searchRequest->smallSetElementSetNames;
102 esn = m_searchRequest->mediumSetElementSetNames;
103 comp = (Z_RecordComposition *) nmem_malloc(m_mem, sizeof(*comp));
104 comp->which = Z_RecordComp_simple;
105 comp->u.simple = esn;
108 // Z_NamePlusRecordList *npr to be owned by m_mem..
109 NMEM tmp_mem = odr_extract_mem(o);
110 nmem_transfer(m_mem, tmp_mem);
111 nmem_destroy(tmp_mem);
113 // Insert individual records in cache
115 for (i = 0; i<npr->num_records; i++)
117 Yaz_RecordCache_Entry *entry = (Yaz_RecordCache_Entry *)
118 nmem_malloc(m_mem, sizeof(*entry));
119 entry->m_record = npr->records[i];
120 entry->m_comp = comp;
121 entry->m_offset = i + start;
122 entry->m_next = m_entries;
127 int Yaz_RecordCache::match (Yaz_RecordCache_Entry *entry,
128 Odr_oid *syntax, int offset,
129 Z_RecordComposition *comp)
131 // See if our compspec match...
133 ODR o1 = odr_createmem(ODR_ENCODE);
134 ODR o2 = odr_createmem(ODR_ENCODE);
136 z_RecordComposition(o1, &comp, 1, 0);
137 z_RecordComposition(o2, &entry->m_comp, 1, 0);
140 char *buf1 = odr_getbuf(o1, &len1, 0);
142 char *buf2 = odr_getbuf(o2, &len2, 0);
144 if (buf1 && buf2 && len1 && len1 == len2 && !memcmp(buf1, buf2, len1))
146 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,
165 int Yaz_RecordCache::lookup (ODR o, Z_NamePlusRecordList **npr,
168 Z_RecordComposition *comp)
171 yaz_log(LOG_DEBUG, "cache lookup start=%d num=%d", start, num);
173 for (i = 0; i<num; i++)
175 Yaz_RecordCache_Entry *entry = m_entries;
176 for(; entry; entry = entry->m_next)
177 if (match(entry, syntax, start+i, comp))
182 *npr = (Z_NamePlusRecordList *) odr_malloc(o, sizeof(**npr));
183 (*npr)->num_records = num;
184 (*npr)->records = (Z_NamePlusRecord **)
185 odr_malloc(o, num * sizeof(Z_NamePlusRecord *));
186 for (i = 0; i<num; i++)
188 Yaz_RecordCache_Entry *entry = m_entries;
189 for(; entry; entry = entry->m_next)
190 if (match(entry, syntax, start+i, comp))
194 (*npr)->records[i] = entry->m_record;