2 * Copyright (c) 2002-2004, Index Data.
3 * See the file LICENSE for details.
5 * $Id: yaz-z-cache.cpp,v 1.14 2005-06-25 15:53:19 adam Exp $
10 #include <yaz++/record-cache.h>
12 using namespace yazpp_1;
14 struct yazpp_1::RecordCache_Entry {
16 Z_NamePlusRecord *m_record;
17 Z_RecordComposition *m_comp;
18 RecordCache_Entry *m_next;
21 RecordCache::RecordCache ()
23 m_mem = nmem_create();
30 RecordCache::~RecordCache ()
35 void RecordCache::set_max_size(int sz)
40 void RecordCache::clear ()
43 m_mem = nmem_create();
49 void RecordCache::copy_searchRequest(Z_SearchRequest *sr)
51 ODR encode = odr_createmem(ODR_ENCODE);
52 ODR decode = odr_createmem(ODR_DECODE);
56 int v = z_SearchRequest (encode, &sr, 1, 0);
60 char *buf = odr_getbuf(encode, &len, 0);
61 odr_setbuf(decode, buf, len, 0);
62 z_SearchRequest(decode, &m_searchRequest, 1, 0);
63 nmem_transfer(m_mem, decode->mem);
69 void RecordCache::copy_presentRequest(Z_PresentRequest *pr)
71 ODR encode = odr_createmem(ODR_ENCODE);
72 ODR decode = odr_createmem(ODR_DECODE);
76 int v = z_PresentRequest (encode, &pr, 1, 0);
80 char *buf = odr_getbuf(encode, &len, 0);
81 odr_setbuf(decode, buf, len, 0);
82 z_PresentRequest(decode, &m_presentRequest, 1, 0);
83 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 // Z_NamePlusRecordList *npr to be owned by m_mem..
112 NMEM tmp_mem = odr_extract_mem(o);
113 nmem_transfer(m_mem, tmp_mem);
114 nmem_destroy(tmp_mem);
116 // Insert individual records in cache
118 for (i = 0; i<npr->num_records; i++)
120 RecordCache_Entry *entry = (RecordCache_Entry *)
121 nmem_malloc(m_mem, sizeof(*entry));
122 entry->m_record = (Z_NamePlusRecord *)
123 nmem_malloc(m_mem, sizeof(*entry->m_record));
124 entry->m_record->databaseName = npr->records[i]->databaseName;
125 entry->m_record->which = npr->records[i]->which;
126 entry->m_record->u.databaseRecord = npr->records[i]->u.databaseRecord;
127 entry->m_comp = comp;
128 entry->m_offset = i + start;
129 entry->m_next = m_entries;
134 int RecordCache::match (RecordCache_Entry *entry,
135 Odr_oid *syntax, int offset,
136 Z_RecordComposition *comp)
138 // See if our compspec match...
140 ODR o1 = odr_createmem(ODR_ENCODE);
141 ODR o2 = odr_createmem(ODR_ENCODE);
143 z_RecordComposition(o1, &comp, 1, 0);
144 z_RecordComposition(o2, &entry->m_comp, 1, 0);
147 char *buf1 = odr_getbuf(o1, &len1, 0);
149 char *buf2 = odr_getbuf(o2, &len2, 0);
151 if (buf1 && buf2 && len1 && len1 == len2 && !memcmp(buf1, buf2, len1))
153 else if (!buf1 && !buf2 && !len1 && !len2)
162 // See if offset, OID match..
163 if (entry->m_offset == offset &&
164 entry->m_record->which == Z_NamePlusRecord_databaseRecord &&
165 !oid_oidcmp(entry->m_record->u.databaseRecord->direct_reference,
170 oid_to_dotstring(entry->m_record->u.databaseRecord->direct_reference, mstr1);
172 oid_to_dotstring(syntax, mstr2);
173 yaz_log(YLOG_LOG, "match fail 3 d=%s s=%s", mstr1, mstr2);
179 int RecordCache::lookup (ODR o, Z_NamePlusRecordList **npr,
182 Z_RecordComposition *comp)
185 yaz_log(YLOG_DEBUG, "cache lookup start=%d num=%d", start, num);
187 for (i = 0; i<num; i++)
189 RecordCache_Entry *entry = m_entries;
190 for(; entry; entry = entry->m_next)
191 if (match(entry, syntax, start+i, comp))
196 *npr = (Z_NamePlusRecordList *) odr_malloc(o, sizeof(**npr));
197 (*npr)->num_records = num;
198 (*npr)->records = (Z_NamePlusRecord **)
199 odr_malloc(o, num * sizeof(Z_NamePlusRecord *));
200 for (i = 0; i<num; i++)
202 RecordCache_Entry *entry = m_entries;
203 for(; entry; entry = entry->m_next)
204 if (match(entry, syntax, start+i, comp))
208 (*npr)->records[i] = (Z_NamePlusRecord *)
209 odr_malloc(o, sizeof(Z_NamePlusRecord));
210 (*npr)->records[i]->databaseName = entry->m_record->databaseName;
211 (*npr)->records[i]->which = entry->m_record->which;
212 (*npr)->records[i]->u.databaseRecord =
213 entry->m_record->u.databaseRecord;
220 * indent-tabs-mode: nil
222 * vim: shiftwidth=4 tabstop=8 expandtab