X-Git-Url: http://git.indexdata.com/?p=yazpp-moved-to-github.git;a=blobdiff_plain;f=src%2Fyaz-z-cache.cpp;h=cb2fac0393fa5ced745a7177e0f20994465be1fd;hp=125fdb59c2dc64896a76643509c3f165f5a63430;hb=2c25ce513613784819fcb216c60d1584402e7907;hpb=be8de1a2cca3c7162563ddfe524ad4e389758150 diff --git a/src/yaz-z-cache.cpp b/src/yaz-z-cache.cpp index 125fdb5..cb2fac0 100644 --- a/src/yaz-z-cache.cpp +++ b/src/yaz-z-cache.cpp @@ -1,24 +1,28 @@ /* - * Copyright (c) 1998-2003, Index Data. + * Copyright (c) 2002-2004, Index Data. * See the file LICENSE for details. * - * $Id: yaz-z-cache.cpp,v 1.1 2003-07-18 13:27:20 adam Exp $ + * $Id: yaz-z-cache.cpp,v 1.9 2004-03-29 22:46:51 adam Exp $ */ #include -#include +#include +#include struct Yaz_RecordCache_Entry { int m_offset; Z_NamePlusRecord *m_record; + Z_RecordComposition *m_comp; Yaz_RecordCache_Entry *m_next; }; - Yaz_RecordCache::Yaz_RecordCache () { m_mem = nmem_create(); m_entries = 0; + m_presentRequest = 0; + m_searchRequest = 0; + m_max_size = 200000; } Yaz_RecordCache::~Yaz_RecordCache () @@ -26,65 +30,163 @@ Yaz_RecordCache::~Yaz_RecordCache () nmem_destroy(m_mem); } +void Yaz_RecordCache::set_max_size(int sz) +{ + m_max_size = sz; +} + void Yaz_RecordCache::clear () { nmem_destroy(m_mem); m_mem = nmem_create(); m_entries = 0; + m_presentRequest = 0; + m_searchRequest = 0; } -#if 0 -void Yaz_RecordCache::prepare_present(Z_RecordComposition *comp) +void Yaz_RecordCache::copy_searchRequest(Z_SearchRequest *sr) { - if (!comp) - m_recordComposition = 0; - else + ODR encode = odr_createmem(ODR_ENCODE); + ODR decode = odr_createmem(ODR_DECODE); + + m_searchRequest = 0; + m_presentRequest = 0; + int v = z_SearchRequest (encode, &sr, 1, 0); + if (v) { - m_recordComposition = nmem_malloc(m_mem, sizeof(*m_recordComposition)); - m_recordComposition->which = comp->which; - if (comp->which == Z_RecordComp_simple) - { - m_recordComposition->u.simple = (Z_ElementSetNames *) - nmem_malloc(m_mem, sizeof(Z_ElementSetNames)); - } + int len; + char *buf = odr_getbuf(encode, &len, 0); + odr_setbuf(decode, buf, len, 0); + z_SearchRequest(decode, &m_searchRequest, 1, 0); + nmem_transfer(m_mem, decode->mem); } + odr_destroy(encode); + odr_destroy(decode); +} +void Yaz_RecordCache::copy_presentRequest(Z_PresentRequest *pr) +{ + ODR encode = odr_createmem(ODR_ENCODE); + ODR decode = odr_createmem(ODR_DECODE); + + m_searchRequest = 0; + m_presentRequest = 0; + int v = z_PresentRequest (encode, &pr, 1, 0); + if (v) + { + int len; + char *buf = odr_getbuf(encode, &len, 0); + odr_setbuf(decode, buf, len, 0); + z_PresentRequest(decode, &m_presentRequest, 1, 0); + nmem_transfer(m_mem, decode->mem); + } + odr_destroy(encode); + odr_destroy(decode); } -#endif -void Yaz_RecordCache::add (ODR o, Z_NamePlusRecordList *npr, int start) +void Yaz_RecordCache::add (ODR o, Z_NamePlusRecordList *npr, int start, + int hits) { + if (nmem_total(m_mem) > m_max_size) + return; + // Build appropriate compspec for this response + Z_RecordComposition *comp = 0; + if (hits == -1 && m_presentRequest) + comp = m_presentRequest->recordComposition; + else if (hits > 0 && m_searchRequest) + { + Z_ElementSetNames *esn; + + if (hits <= *m_searchRequest->smallSetUpperBound) + esn = m_searchRequest->smallSetElementSetNames; + else + esn = m_searchRequest->mediumSetElementSetNames; + comp = (Z_RecordComposition *) nmem_malloc(m_mem, sizeof(*comp)); + comp->which = Z_RecordComp_simple; + comp->u.simple = esn; + } + + // Z_NamePlusRecordList *npr to be owned by m_mem.. NMEM tmp_mem = odr_extract_mem(o); nmem_transfer(m_mem, tmp_mem); nmem_destroy(tmp_mem); - + + // Insert individual records in cache int i; for (i = 0; inum_records; i++) { Yaz_RecordCache_Entry *entry = (Yaz_RecordCache_Entry *) nmem_malloc(m_mem, sizeof(*entry)); - entry->m_record = npr->records[i]; + entry->m_record = (Z_NamePlusRecord *) + nmem_malloc(m_mem, sizeof(*entry->m_record)); + entry->m_record->databaseName = npr->records[i]->databaseName; + entry->m_record->which = npr->records[i]->which; + entry->m_record->u.databaseRecord = npr->records[i]->u.databaseRecord; + entry->m_comp = comp; entry->m_offset = i + start; entry->m_next = m_entries; m_entries = entry; } } +int Yaz_RecordCache::match (Yaz_RecordCache_Entry *entry, + Odr_oid *syntax, int offset, + Z_RecordComposition *comp) +{ + // See if our compspec match... + int match = 0; + ODR o1 = odr_createmem(ODR_ENCODE); + ODR o2 = odr_createmem(ODR_ENCODE); + + z_RecordComposition(o1, &comp, 1, 0); + z_RecordComposition(o2, &entry->m_comp, 1, 0); + + int len1 = -1; + char *buf1 = odr_getbuf(o1, &len1, 0); + int len2 = -1; + char *buf2 = odr_getbuf(o2, &len2, 0); + + if (buf1 && buf2 && len1 && len1 == len2 && !memcmp(buf1, buf2, len1)) + match = 1; + else if (!buf1 && !buf2 && !len1 && !len2) + match = 1; + + odr_destroy(o1); + odr_destroy(o2); + if (!match) + return 0; + if (!syntax) + return 0; + // See if offset, OID match.. + if (entry->m_offset == offset && + entry->m_record->which == Z_NamePlusRecord_databaseRecord && + !oid_oidcmp(entry->m_record->u.databaseRecord->direct_reference, + syntax)) + return 1; +#if 0 + char mstr1[100]; + oid_to_dotstring(entry->m_record->u.databaseRecord->direct_reference, mstr1); + char mstr2[100]; + oid_to_dotstring(syntax, mstr2); + yaz_log(LOG_LOG, "match fail 3 d=%s s=%s", mstr1, mstr2); +#endif + + return 0; +} + int Yaz_RecordCache::lookup (ODR o, Z_NamePlusRecordList **npr, int start, int num, - Odr_oid *syntax) + Odr_oid *syntax, + Z_RecordComposition *comp) { int i; - yaz_log(LOG_LOG, "cache lookup start=%d num=%d", start, num); + yaz_log(LOG_DEBUG, "cache lookup start=%d num=%d", start, num); for (i = 0; im_next) - if (entry->m_offset == start + i && - entry->m_record->which == Z_NamePlusRecord_databaseRecord && - !oid_oidcmp(entry->m_record->u.databaseRecord->direct_reference, - syntax)) + if (match(entry, syntax, start+i, comp)) break; if (!entry) return 0; @@ -97,14 +199,16 @@ int Yaz_RecordCache::lookup (ODR o, Z_NamePlusRecordList **npr, { Yaz_RecordCache_Entry *entry = m_entries; for(; entry; entry = entry->m_next) - if (entry->m_offset == start + i && - entry->m_record->which == Z_NamePlusRecord_databaseRecord && - !oid_oidcmp(entry->m_record->u.databaseRecord->direct_reference, - syntax)) + if (match(entry, syntax, start+i, comp)) break; if (!entry) return 0; - (*npr)->records[i] = entry->m_record; + (*npr)->records[i] = (Z_NamePlusRecord *) + odr_malloc(o, sizeof(Z_NamePlusRecord)); + (*npr)->records[i]->databaseName = entry->m_record->databaseName; + (*npr)->records[i]->which = entry->m_record->which; + (*npr)->records[i]->u.databaseRecord = + entry->m_record->u.databaseRecord; } return 1; }