From bef547be3c6f3c9389af841564959f407257a311 Mon Sep 17 00:00:00 2001 From: erickson Date: Mon, 12 Jun 2006 18:40:09 +0000 Subject: [PATCH] moved to server side caching of opac search results - sped up the details page by only fetching and drawing local copy info by default git-svn-id: svn://svn.open-ils.org/ILS/trunk@4580 dcc99617-32d9-48b4-a31d-7c20da2025e4 --- .../perlmods/OpenILS/Application/Search.pm | 1 + .../OpenILS/Application/Search/Biblio.pm | 94 ++++++++++++++++--- Open-ILS/web/opac/common/js/config.js | 4 +- Open-ILS/web/opac/common/js/opac_utils.js | 8 +- Open-ILS/web/opac/skin/default/js/mresult.js | 13 +++ Open-ILS/web/opac/skin/default/js/rdetail.js | 92 ++++++++++++++++-- .../web/opac/skin/default/js/result_common.js | 7 +- Open-ILS/web/opac/skin/default/js/rresult.js | 58 ++++++++++-- .../opac/skin/default/xml/page_rdetail.xml | 2 + 9 files changed, 245 insertions(+), 34 deletions(-) diff --git a/Open-ILS/src/perlmods/OpenILS/Application/Search.pm b/Open-ILS/src/perlmods/OpenILS/Application/Search.pm index 90cb8f3cd1..e4753afbe0 100644 --- a/Open-ILS/src/perlmods/OpenILS/Application/Search.pm +++ b/Open-ILS/src/perlmods/OpenILS/Application/Search.pm @@ -27,6 +27,7 @@ use Text::Aspell; sub initialize { OpenILS::Application::Search::Z3950->initialize(); OpenILS::Application::Search::Zips->initialize(); + OpenILS::Application::Search::Biblio->initialize(); # try to load the added content handler my $conf = OpenSRF::Utils::SettingsClient->new; diff --git a/Open-ILS/src/perlmods/OpenILS/Application/Search/Biblio.pm b/Open-ILS/src/perlmods/OpenILS/Application/Search/Biblio.pm index 3957706eca..c8fc22fc6c 100644 --- a/Open-ILS/src/perlmods/OpenILS/Application/Search/Biblio.pm +++ b/Open-ILS/src/perlmods/OpenILS/Application/Search/Biblio.pm @@ -8,6 +8,7 @@ use OpenILS::Utils::Fieldmapper; use OpenILS::Utils::ModsParser; use OpenSRF::Utils::SettingsClient; use OpenILS::Utils::Editor q/:funcs/; +use OpenSRF::Utils::Cache; use OpenSRF::Utils::Logger qw/:logger/; @@ -28,13 +29,12 @@ use OpenILS::Application::AppUtils; my $apputils = "OpenILS::Application::AppUtils"; my $U = $apputils; +my $pfx = "open-ils.search"; -# useful for MARC based searches -#my $cat_search_hash = { - #isbn => [ { tag => '020', subfield => 'a' }, ], - ##issn => [ { tag => '022', subfield => 'a' }, ], -#}; - +my $cache; +sub initialize { + $cache = OpenSRF::Utils::Cache->new('global'); +} @@ -321,6 +321,7 @@ __PACKAGE__->register_method( signature => q/@see open-ils.search.biblio.multiclass/); + sub the_quest_for_knowledge { my( $self, $conn, $searchhash ) = @_; @@ -328,28 +329,85 @@ sub the_quest_for_knowledge { my $ismeta = 0; my @recs; + my $maxlimit = 500; + + my $o = $searchhash->{offset} || 0; + my $l = $searchhash->{limit} || 10; + $searchhash->{offset} = 0; + $searchhash->{limit} = 0; + + my $ckey = $pfx . md5_hex($method . JSON->perl2JSON($searchhash)); + + $searchhash->{offset} = $o; + $searchhash->{limit} = $l; + + if($self->api_name =~ /metabib/) { $ismeta = 1; $method =~ s/biblio/metabib/o; } - $method .= ".staff" if($self->api_name =~ /staff/); - $method .= ".atomic"; + # don't cache past max limit + my $result = ($o < $maxlimit) ? search_cache($ckey, $o, $l) : undef; + my $docache = 1; + + if(!$result) { - for (keys %$searchhash) { - delete $$searchhash{$_} unless defined $$searchhash{$_}; } + $method .= ".staff" if($self->api_name =~ /staff/); + $method .= ".atomic"; + + for (keys %$searchhash) { + delete $$searchhash{$_} unless defined $$searchhash{$_}; } + + $searchhash->{limit} = $maxlimit; + $result = new_editor()->request( $method, %$searchhash ); - my $result = new_editor()->request( $method, %$searchhash ); + + } else { + $logger->debug("cache returned results: " . JSON->perl2JSON($result)); + $docache = 0; + } return {count => 0} unless ($result && $$result[0]); for my $r (@$result) { push(@recs, $r) if ($r and $$r[0]); } + + if( $docache ) { + $logger->debug("putting search cache $ckey\n"); + $cache->put_cache($ckey, \@recs, 900); + } + return { ids => \@recs, count => ($ismeta) ? $result->[0]->[3] : $result->[0]->[2] }; } +#$cache_handle->put_cache( "_open-ils_seed_$username", $seed, 30 ); +#my $current_seed = $cache_handle->get_cache("_open-ils_seed_$username"); +#$cache_handle->delete_cache( "_open-ils_seed_$username" ); + +sub search_cache { + + my $key = shift; + my $offset = shift; + my $limit = shift; + + $logger->debug("fetching search cache $key\n"); + + my $data = $cache->get_cache($key); + return undef unless $data; + + $logger->debug("search_cache found some data: o=$offset, l=$limit"); + + #$data = JSON->JSON2perl($data); + return undef unless $data and ref $data eq 'ARRAY'; + return undef unless $$data[$offset] and $$data[$offset+($limit-1)]; + + $logger->debug("search_cache found data..$offset - " . ($offset + ($limit - 1))); + return [ @$data[$offset..($offset+$limit)] ]; +} + @@ -767,13 +825,23 @@ __PACKAGE__->register_method( NOTES sub marc_search { - my( $self, $conn, $args ) = @_; + my( $self, $conn, $args, $limit, $offset ) = @_; my $method = 'open-ils.storage.biblio.full_rec.multi_search'; $method .= ".staff" if $self->api_name =~ /staff/; $method .= ".atomic"; - my $recs = new_editor()->request($method, %$args); + $limit ||= 10; + $offset ||= 0; + + my $ckey = $pfx . md5_hex($method . JSON->perl2JSON($args)); + my $recs = search_cache($ckey, $offset, $limit); + + if(!$recs) { + $recs = new_editor()->request($method, %$args); + $cache->put_cache($ckey, $recs, 900); + $recs = [ @$recs[$offset..($offset + ($limit - 1))] ]; + } my $count = 0; $count = $recs->[0]->[2] if $recs->[0] and $recs->[0]->[2]; diff --git a/Open-ILS/web/opac/common/js/config.js b/Open-ILS/web/opac/common/js/config.js index 56f72915f2..58fc173cd2 100644 --- a/Open-ILS/web/opac/common/js/config.js +++ b/Open-ILS/web/opac/common/js/config.js @@ -69,8 +69,8 @@ var SKIN; /* cookies */ var COOKIE_SB = "sbe"; var COOKIE_SES = "ses"; -var COOKIE_IDS = "ids"; /* list of mrecord ids */ -var COOKIE_SRIDS = "srids"; /* record ids cached from a search */ +//var COOKIE_IDS = "ids"; /* list of mrecord ids */ +//var COOKIE_SRIDS = "srids"; /* record ids cached from a search */ var COOKIE_FONT = "fnt"; var COOKIE_SKIN = "skin"; var COOKIE_RIDS = "rids"; /* list of record ids */ diff --git a/Open-ILS/web/opac/common/js/opac_utils.js b/Open-ILS/web/opac/common/js/opac_utils.js index 5e1f4b3fc4..8c369a7565 100644 --- a/Open-ILS/web/opac/common/js/opac_utils.js +++ b/Open-ILS/web/opac/common/js/opac_utils.js @@ -276,7 +276,7 @@ function buildOPACLink(args, slim, ssl) { } if(getDebug()) - string += _appendParam(DEBUG, PARAM_DEBUG, args, getDebug, string); + string += _appendParam(DEBUG, PARAM_DEBUG, args, getDebug, string); if(getOrigLocation() != 1) string += _appendParam(ORIGLOC, PARAM_ORIGLOC, args, getOrigLocation, string); if(getTerm()) @@ -323,6 +323,10 @@ function buildOPACLink(args, slim, ssl) { string += _appendParam(LANGUAGE, PARAM_LANGUAGE, args, getLanguage, string); if(getRdepth() != null) string += _appendParam(RDEPTH, PARAM_RDEPTH, args, getRdepth, string); + if(getSort() != null) + string += _appendParam(SORT, PARAM_SORT, args, getSort, string); + if(getSortDir() != null) + string += _appendParam(SORT_DIR, PARAM_SORT_DIR, args, getSortDir, string); return string.replace(/\&$/,'').replace(/\?\&/,"?"); } @@ -373,7 +377,7 @@ function buildTitleDetailLink(rec, link) { link.appendChild(text(normalize(truncate(rec.title(), 65)))); var args = {}; args.page = RDETAIL; - args[PARAM_OFFSET] = 0; + //args[PARAM_OFFSET] = 0; args[PARAM_RID] = rec.doc_id(); link.setAttribute("href", buildOPACLink(args)); } diff --git a/Open-ILS/web/opac/skin/default/js/mresult.js b/Open-ILS/web/opac/skin/default/js/mresult.js index 1a684f0e0f..ff3114461a 100644 --- a/Open-ILS/web/opac/skin/default/js/mresult.js +++ b/Open-ILS/web/opac/skin/default/js/mresult.js @@ -39,14 +39,20 @@ function mresultDoSearch() { } } +/* function mresultLoadCachedSearch() { if( (getOffset() > 0) && (getOffset() < mresultPreCache) ) { var c = JSON2js(cookieManager.read(COOKIE_IDS)); if(c) { records = c[0]; ranks = c[1]; } } } +*/ function mresultTryCachedSearch() { + /* XXX */ + return false; + + /* mresultLoadCachedSearch(); if( getOffset() != 0 && records[getOffset()] != null && records[resultFinalPageIndex()] != null) { @@ -55,6 +61,7 @@ function mresultTryCachedSearch() { return true; } return false; + */ } function _mresultCollectIds() { @@ -89,6 +96,8 @@ function mresultHandleMRIds(r) { runEvt('result', 'idsReceived', res.ids); } + + function mresultSetRecords(idstruct) { if(!idstruct) return; var o = getOffset(); @@ -103,14 +112,18 @@ function mresultSetRecords(idstruct) { } } + /* if(getOffset() == 0) { cookieManager.remove(COOKIE_IDS); cookieManager.write(COOKIE_IDS, js2JSON([ records, ranks ]), '+1d' ); } + */ TOPRANK = ranks[getOffset()]; } + + function mresultCollectRecords() { if(getHitCount() > 0 ) runEvt("result", "preCollectRecords"); var i = 0; diff --git a/Open-ILS/web/opac/skin/default/js/rdetail.js b/Open-ILS/web/opac/skin/default/js/rdetail.js index a8595af76b..76365fb669 100644 --- a/Open-ILS/web/opac/skin/default/js/rdetail.js +++ b/Open-ILS/web/opac/skin/default/js/rdetail.js @@ -1,5 +1,6 @@ /* */ +detachAllEvt('common', 'run'); attachEvt("common", "run", rdetailDraw); attachEvt("rdetail", "recordDrawn", rdetailBuildStatusColumns); attachEvt("rdetail", "recordDrawn", rdetailBuildInfoRows); @@ -19,6 +20,8 @@ var globalCNCache = {}; var localTOC; var cachedRecords; +var rdetailShowLocal = true; + var nextContainerIndex; @@ -38,12 +41,20 @@ var rdetailNext = null; var rdetailStart = null; var rdetailEnd = null; + + /* looks to see if we have a next and/or previous record in the record cache, if so, set up the nav links */ -function rdetailSetPaging() { +function rdetailSetPaging(ids) { + /* cachedRecords = JSON2js(cookieManager.read(COOKIE_SRIDS)); if(!(cachedRecords && cachedRecords.ids)) return; + */ + + //alert(getOffset()); + cachedRecords = {}; + cachedRecords.ids = ids; for( var i = 0; i < cachedRecords.ids.length; i++ ) { var rec = cachedRecords.ids[i]; @@ -55,8 +66,8 @@ function rdetailSetPaging() { } } - $('np_offset').appendChild(text(i+1)); - $('np_count').appendChild(text(cachedRecords.ids.length)); + $('np_offset').appendChild(text(i + 1)); + $('np_count').appendChild(text(getHitCount())); if(prevRecord) { unHideMe($('np_table')); @@ -108,7 +119,18 @@ function rdetailDraw() { req.callback(_rdetailDraw); req.send(); - rdetailSetPaging(); + detachAllEvt("result", "idsReceived"); + G.evt.result.hitCountReceived = []; + G.evt.result.recordReceived = []; + G.evt.result.copyCountsReceived = []; + G.evt.result.allRecordsReceived = []; + + attachEvt("result", "idsReceived", rdetailSetPaging ); + + resultFetchAllRecords = true; + rresultCollectIds(); + + //rdetailSetPaging(); } function buildunAPISpan (span, type, id) { @@ -143,11 +165,21 @@ function rdetailViewMarc(r,id) { function rdetailShowLocalCopies() { + /* XXX */ + rdetailShowLocal = true; + rdetailBuildInfoRows(); + hideMe(G.ui.rdetail.cp_info_local); + unHideMe(G.ui.rdetail.cp_info_all); + hideMe(G.ui.rdetail.cp_info_none); /* XXX */ + return; + + + var found = false; var rows = copyRowParent.getElementsByTagName("tr"); for( var r in rows ) { var row = rows[r]; - if( row.parentNode != copyRowParent ) continue; /* don't hide copy details sub-rows */ + if( row.parentNode != copyRowParent ) continue; if(row.id == "__rdsrow") continue; if(row.getAttribute && row.getAttribute("local")) { unHideMe(row); @@ -164,6 +196,18 @@ function rdetailShowLocalCopies() { } function rdetailShowAllCopies() { + + /* XXX */ + rdetailShowLocal = false; + rdetailBuildInfoRows(); + hideMe(G.ui.rdetail.cp_info_all); + unHideMe(G.ui.rdetail.cp_info_local); + hideMe(G.ui.rdetail.cp_info_none); /* XXX */ + return; + + + + var rows = copyRowParent.getElementsByTagName("tr"); for( var r in rows ) if(rows[r].getAttribute && rows[r].getAttribute("hasinfo")) @@ -449,8 +493,11 @@ function rdetailShowTOC(r) { function rdetailBuildInfoRows() { - //var req = new Request(FETCH_COPY_COUNTS_SUMMARY, record.doc_id(), getLocation(), getDepth()) - var req = new Request(FETCH_COPY_COUNTS_SUMMARY, record.doc_id()); + var req; + if( rdetailShowLocal ) + req = new Request(FETCH_COPY_COUNTS_SUMMARY, record.doc_id(), getLocation(), getDepth()) + else + req = new Request(FETCH_COPY_COUNTS_SUMMARY, record.doc_id()); req.callback(_rdetailBuildInfoRows); req.send(); } @@ -458,6 +505,27 @@ function rdetailBuildInfoRows() { /* pre-allocate the copy info table with all org units in correct order */ function _rdetailRows(node) { + if( rdetailShowLocal && getLocation() != globalOrgTree.id() ) { + + var loc = findOrgUnit(getLocation()); + + if( !node ) { + for( var i = 0; i < globalOrgTree.children().length; i++ ) { + var org = findOrgUnit(globalOrgTree.children()[i]); + if( orgIsMine(org, loc) ) { + node = org; + break; + } + } + } else { + /* if the current node is not in our node trail */ + var trail = orgNodeTrail(loc); + var intrail = grep( trail, function(i) { return (i.id() == node.id()); } ); + if(!intrail) return; + } + } + + if(node) { var row = copyRow.cloneNode(true); @@ -514,13 +582,18 @@ var localCNFound = false; var ctr = 0; function _rdetailBuildInfoRows(r) { + /* XXX */ + removeChildren(copyRowParent); + _rdetailRows(); var summary = r.getResultObject(); if(!summary) return; + /* XXX G.ui.rdetail.cp_info_loading.parentNode.removeChild( G.ui.rdetail.cp_info_loading); + */ var found = false; for( var i = 0; i < summary.length; i++ ) { @@ -629,10 +702,15 @@ function rdetailSetPath(org, local) { if( findOrgDepth(org) == 0 ) return; var row = $("cp_info_" + org.id()); row.setAttribute("hasinfo", "1"); + /* if(local) { unHideMe(row); row.setAttribute("local", "1"); } + */ + /* XXX */ + unHideMe(row); + rdetailSetPath(findOrgUnit(org.parent_ou()), local); } diff --git a/Open-ILS/web/opac/skin/default/js/result_common.js b/Open-ILS/web/opac/skin/default/js/result_common.js index 142fd42605..69517a4835 100644 --- a/Open-ILS/web/opac/skin/default/js/result_common.js +++ b/Open-ILS/web/opac/skin/default/js/result_common.js @@ -3,6 +3,8 @@ var recordsHandled = 0; var recordsCache = []; var lowHitCount = 4; +var resultFetchAllRecords = false; + /* set up the event handlers */ G.evt.result.hitCountReceived.push(resultSetHitInfo); G.evt.result.recordReceived.push(resultDisplayRecord, resultAddCopyCounts); @@ -57,7 +59,9 @@ function resultCollectSearchIds( type, method, handler ) { args.org_unit = getLocation(); args.depth = getDepth(); - args.limit = 200; + /*args.limit = 200;*/ + args.limit = (resultFetchAllRecords) ? 1000 : getDisplayCount(); + /*args.limit = 500;*/ args.offset = getOffset(); if(sort) args.sort = sort; @@ -72,6 +76,7 @@ function resultCollectSearchIds( type, method, handler ) { //alert('form = ' + item_form + ' : type = ' + item_type); + //alert(js2JSON(args)); var req = new Request(method, args); req.callback(handler); req.send(); diff --git a/Open-ILS/web/opac/skin/default/js/rresult.js b/Open-ILS/web/opac/skin/default/js/rresult.js index 442e17a63b..7011fe3e71 100644 --- a/Open-ILS/web/opac/skin/default/js/rresult.js +++ b/Open-ILS/web/opac/skin/default/js/rresult.js @@ -3,6 +3,8 @@ var table; var rowtemplate; var rresultLimit = 200; +var rresultIsPaged = false; + function rresultUnload() { removeChildren(table); table = null;} attachEvt("common", "unload", rresultUnload); @@ -25,6 +27,10 @@ function rresultDoSearch() { function rresultCachedSearch() { + /* XXX */ + return false; + + /* if(!getOffset()) { cookieManager.remove(COOKIE_SRIDS); return false; @@ -40,6 +46,7 @@ function rresultCachedSearch() { } return false; + */ } function rresultCollectIds() { @@ -98,17 +105,21 @@ function rresultCollectIds() { req.send(); if( rresultGetDepth() != findOrgDepth(globalOrgTree) ) { - unHideMe($('rresult_show_all')); var link = $('rresult_show_all_link'); - link.appendChild( text( - findOrgType(globalOrgTree.ou_type()).opac_label())); + if(link) { + unHideMe($('rresult_show_all')); + link.appendChild( text( + findOrgType(globalOrgTree.ou_type()).opac_label())); + } } else { if( rresultGetDepth() != getDepth() ) { /* inside a limited display */ var link = $('rresult_show_here_link'); - link.appendChild( text( - findOrgType(findOrgUnit(getLocation()).ou_type()).opac_label())); - unHideMe($('rresult_show_here')); + if(link) { + link.appendChild( text( + findOrgType(findOrgUnit(getLocation()).ou_type()).opac_label())); + unHideMe($('rresult_show_here')); + } } } } @@ -166,7 +177,8 @@ function rresultCollectMARCIds() { args.org_unit = globalOrgTree.id(); args.depth = 0; - var req = new Request(FETCH_ADV_MARC_MRIDS, args); + rresultIsPaged = true; + var req = new Request(FETCH_ADV_MARC_MRIDS, args, getDisplayCount(), getOffset()); req.callback(rresultHandleRIds); req.request.noretry = true; req.send(); @@ -234,13 +246,16 @@ function rresultHandleRIds(r) { function _rresultHandleIds(ids, count) { var json = js2JSON({ids:ids,count:count}); + /* cookieManager.write(COOKIE_SRIDS, json, '+1d'); + */ HITCOUNT = parseInt(count); runEvt('result', 'hitCountReceived'); runEvt('result', 'idsReceived', ids); } +/* function rresultCollectRecords(ids) { runEvt("result", "preCollectRecords"); var x = 0; @@ -252,6 +267,25 @@ function rresultCollectRecords(ids) { req.send(); } } +*/ + + +function rresultCollectRecords(ids) { + runEvt("result", "preCollectRecords"); + var x = 0; + + var base = getOffset(); + if( rresultIsPaged ) base = 0; + + for( var i = base; i!= getDisplayCount() + base; i++ ) { + if(ids[i] == null) break; + var req = new Request(FETCH_RMODS, parseInt(ids[i])); + req.callback(rresultHandleMods); + req.request.userdata = x++; + req.send(); + } +} + function rresultHandleMods(r) { var rec = r.getResultObject(); @@ -269,13 +303,19 @@ function rresultLaunchDrawn(id, node) { function rresultDoRecordSearch() { - resultCollectSearchIds(true, SEARCH_RS, rresultFilterSearchResults ); } + rresultIsPaged = true; + resultCollectSearchIds(true, SEARCH_RS, rresultFilterSearchResults ); +} + function rresultDoRecordMultiSearch() { - resultCollectSearchIds(false, SEARCH_RS, rresultFilterSearchResults ); } + rresultIsPaged = true; + resultCollectSearchIds(false, SEARCH_RS, rresultFilterSearchResults ); +} function rresultFilterSearchResults(r) { var result = r.getResultObject(); + var ids = []; for( var i = 0; i != result.ids.length; i++ ) ids.push(result.ids[i][0]); diff --git a/Open-ILS/web/opac/skin/default/xml/page_rdetail.xml b/Open-ILS/web/opac/skin/default/xml/page_rdetail.xml index 4d0f3a9f15..bb457c7e20 100644 --- a/Open-ILS/web/opac/skin/default/xml/page_rdetail.xml +++ b/Open-ILS/web/opac/skin/default/xml/page_rdetail.xml @@ -1,6 +1,8 @@
+ + -- 2.43.2