+yf::SessionShared::BackendClass::BackendClass(const yazpp_1::GDU &init_request)
+ : m_named_result_sets(false), m_init_request(init_request),
+ m_sequence_top(0), m_backend_set_ttl(30),
+ m_backend_expiry_ttl(90), m_backend_set_max(10)
+{}
+
+yf::SessionShared::BackendClass::~BackendClass()
+{}
+
+void yf::SessionShared::Rep::init(mp::Package &package, const Z_GDU *gdu,
+ FrontendPtr frontend)
+{
+ Z_InitRequest *req = gdu->u.z3950->u.initRequest;
+
+ frontend->m_is_virtual = true;
+ InitKey k(req);
+ {
+ boost::mutex::scoped_lock lock(m_mutex_backend_map);
+ BackendClassMap::const_iterator it;
+ it = m_backend_map.find(k);
+ if (it == m_backend_map.end())
+ {
+ BackendClassPtr b(new BackendClass(gdu->u.z3950));
+ m_backend_map[k] = b;
+ frontend->m_backend_class = b;
+ std::cout << "SessionShared::Rep::init new session "
+ << frontend->m_backend_class << "\n";
+ }
+ else
+ {
+ frontend->m_backend_class = it->second;
+ std::cout << "SessionShared::Rep::init existing session "
+ << frontend->m_backend_class << "\n";
+ }
+ }
+ BackendClassPtr bc = frontend->m_backend_class;
+ BackendInstancePtr backend = bc->get_backend(package);
+
+ mp::odr odr;
+ if (!backend)
+ {
+ Z_APDU *apdu = odr.create_initResponse(gdu->u.z3950, 0, 0);
+ *apdu->u.initResponse->result = 0;
+ package.response() = apdu;
+ package.session().close();
+ }
+ else
+ {
+ boost::mutex::scoped_lock lock(bc->m_mutex_backend_class);
+ Z_GDU *response_gdu = bc->m_init_response.get();
+ mp::util::transfer_referenceId(odr, gdu->u.z3950,
+ response_gdu->u.z3950);
+ package.response() = response_gdu;
+ }
+ if (backend)
+ bc->release_backend(backend);
+}
+
+void yf::SessionShared::BackendSet::timestamp()
+{
+ time(&m_time_last_use);
+}
+
+yf::SessionShared::BackendSet::BackendSet(
+ const std::string &result_set_id,
+ const Databases &databases,
+ const yazpp_1::Yaz_Z_Query &query) :
+ m_result_set_id(result_set_id),
+ m_databases(databases), m_result_set_size(0), m_query(query)
+{
+ timestamp();
+}
+
+bool yf::SessionShared::BackendSet::search(
+ Package &frontend_package,
+ const Z_APDU *frontend_apdu,
+ const BackendInstancePtr bp)
+{
+ Package search_package(bp->m_session, frontend_package.origin());
+
+ search_package.copy_filter(frontend_package);
+
+ mp::odr odr;
+ Z_APDU *apdu_req = zget_APDU(odr, Z_APDU_searchRequest);
+ Z_SearchRequest *req = apdu_req->u.searchRequest;
+
+ req->resultSetName = odr_strdup(odr, m_result_set_id.c_str());
+ req->query = m_query.get_Z_Query();
+
+ req->num_databaseNames = m_databases.size();
+ req->databaseNames = (char**)
+ odr_malloc(odr, req->num_databaseNames * sizeof(char *));
+ Databases::const_iterator it = m_databases.begin();
+ size_t i = 0;
+ for (; it != m_databases.end(); it++)
+ req->databaseNames[i++] = odr_strdup(odr, it->c_str());
+
+ search_package.request() = apdu_req;
+
+ search_package.move();
+
+ Z_Records *z_records_diag = 0;
+ Z_GDU *gdu = search_package.response().get();
+ if (!search_package.session().is_closed()
+ && gdu && gdu->which == Z_GDU_Z3950
+ && gdu->u.z3950->which == Z_APDU_searchResponse)
+ {
+ Z_SearchResponse *b_resp = gdu->u.z3950->u.searchResponse;
+ if (b_resp->records)
+ {
+ if (b_resp->records->which == Z_Records_NSD
+ || b_resp->records->which == Z_Records_multipleNSD)
+ z_records_diag = b_resp->records;
+ }
+ if (z_records_diag)
+ {
+ if (frontend_apdu->which == Z_APDU_searchRequest)
+ {
+ Z_APDU *f_apdu = odr.create_searchResponse(frontend_apdu,
+ 0, 0);
+ Z_SearchResponse *f_resp = f_apdu->u.searchResponse;
+ f_resp->records = z_records_diag;
+ frontend_package.response() = f_apdu;
+ return false;
+ }
+ if (frontend_apdu->which == Z_APDU_presentRequest)
+ {
+ Z_APDU *f_apdu = odr.create_presentResponse(frontend_apdu,
+ 0, 0);
+ Z_PresentResponse *f_resp = f_apdu->u.presentResponse;
+ f_resp->records = z_records_diag;
+ frontend_package.response() = f_apdu;
+ return false;
+ }
+ }
+ m_result_set_size = *b_resp->resultCount;
+ return true;
+ }
+ if (frontend_apdu->which == Z_APDU_searchRequest)
+ {
+ Z_APDU *f_apdu =
+ odr.create_searchResponse(frontend_apdu, 1, "Search closed");
+ frontend_package.response() = f_apdu;
+ }
+ if (frontend_apdu->which == Z_APDU_presentRequest)
+ {
+ Z_APDU *f_apdu =
+ odr.create_presentResponse(frontend_apdu, 1, "Search closed");
+ frontend_package.response() = f_apdu;
+ }
+ return false;
+}
+
+void yf::SessionShared::Frontend::override_set(
+ BackendInstancePtr &found_backend,
+ std::string &result_set_id)