changeset 307:d1b8b2dec37e

Added reporters radius search via Web Services. The ordering for radius search is degenerate if usingQueryPoint, because the query point can only be counted once. This behaviour is changed by specifying -n 1 to emulate the trackAveragingReporter ordering behaviour
author mas01mc
date Wed, 06 Aug 2008 21:23:14 +0000
parents 921ba500a024
children 896679d8cc39
files audioDB.cpp audioDB.h audioDBws.h gengetopt.in reporter.h soap.cpp
diffstat 6 files changed, 175 insertions(+), 62 deletions(-) [+]
line wrap: on
line diff
--- a/audioDB.cpp	Tue Aug 05 22:40:38 2008 +0000
+++ b/audioDB.cpp	Wed Aug 06 21:23:14 2008 +0000
@@ -45,8 +45,12 @@
     batchinsert(dbName, inFile);
 
   else if(O2_ACTION(COM_QUERY))
-    if(isClient)
-      ws_query(dbName, inFile, (char*)hostport);
+    if(isClient){
+      if(query_from_key)
+	ws_query_by_key(dbName, key, (char*)hostport);	
+      else
+	ws_query(dbName, inFile, (char*)hostport);
+    }
     else
       query(dbName, inFile);
 
@@ -199,7 +203,7 @@
 
   if(args_info.radius_given) {
     radius = args_info.radius_arg;
-    if(radius <= 0 || radius > 1000000000) {
+    if(radius < 0 || radius > 1000000000) {
       error("radius out of range");
     } else {
       VERB_LOG(3, "Setting radius to %f\n", radius);
--- a/audioDB.h	Tue Aug 05 22:40:38 2008 +0000
+++ b/audioDB.h	Wed Aug 06 21:23:14 2008 +0000
@@ -49,6 +49,7 @@
 #define COM_SEQLEN "--sequencelength"
 #define COM_SEQHOP "--sequencehop"
 #define COM_POINTNN "--pointnn"
+#define COM_RADIUS "--radius"
 #define COM_TRACKNN "--resultlength"
 #define COM_QPOINT "--qpoint"
 #define COM_FEATURES "--features"
@@ -296,7 +297,8 @@
   unsigned random_track(unsigned *propTable, unsigned total);
   void sample(const char *dbName);
   void ws_status(const char*dbName, char* hostport);
-  void ws_query(const char*dbName, const char *trackKey, const char* hostport);
+  void ws_query(const char*dbName, const char *featureFileName, const char* hostport);
+  void ws_query_by_key(const char*dbName, const char *trackKey, const char* hostport);
   void l2norm(const char* dbName);
   void power_flag(const char *dbName);
   bool powers_acceptable(double p1, double p2);
--- a/audioDBws.h	Tue Aug 05 22:40:38 2008 +0000
+++ b/audioDBws.h	Wed Aug 06 21:23:14 2008 +0000
@@ -49,16 +49,16 @@
 struct adb__sequenceQueryParms {
   xsd__string keyList;
   xsd__string timesFileName;
-  xsd__string powerFileName;
-  xsd__int qPos;
+  xsd__int queryPoint;
   xsd__int pointNN;
-  xsd__int segNN;
-  xsd__int segLen;
+  xsd__int trackNN;
+  xsd__int sequenceLength;
+  xsd__double radius;
   xsd__double relative_threshold;
   xsd__double absolute_threshold;
 };
 
 // Perform a sequence query
-int adb__sequenceQuery(xsd__string dbName, xsd__string qKey, 
+int adb__sequenceQuery_by_key(xsd__string dbName, xsd__string qKey, xsd__int qType,
 		       struct adb__sequenceQueryParms *parms, 
 		       struct adb__queryResponse &adbQueryResponse);
--- a/gengetopt.in	Tue Aug 05 22:40:38 2008 +0000
+++ b/gengetopt.in	Wed Aug 06 21:23:14 2008 +0000
@@ -67,7 +67,7 @@
 option "lsh_m" - "number of hash tables is m(m-1)/2" int typestr="size" default="5" dependon="INDEX" optional
 option "lsh_N" - "number of rows per hash tables" int typestr="size" default="100000" dependon="INDEX" optional
 option "lsh_b" - "number of tracks per indexing iteration" int typestr="size" default="500" dependon="INDEX" optional
-option "lsh_ncols" - "number of columns (collisions) to allocate in LSH serialization" int typestr="size" default="250" dependon="INDEX" optional
+option "lsh_ncols" - "number of columns (collisions) to allocate for FORMAT1 LSH serialization" int typestr="size" default="250" dependon="INDEX" optional hidden
 option "lsh_exact" - "use exact evaluation of points retrieved by LSH." flag off dependon="QUERY" optional
 option "lsh_on_disk" - "Construct LSH hash tables for on-disk query (INDEX/QUERY)" flag off optional
 option "lsh_use_u_functions" - "use m independent hash functions combinatorically to approximate L independent hash functions." flag off optional
--- a/reporter.h	Tue Aug 05 22:40:38 2008 +0000
+++ b/reporter.h	Wed Aug 06 21:23:14 2008 +0000
@@ -379,7 +379,6 @@
   return *t;
 }
 
-
 // track Sequence Query Radius Reporter
 // only return tracks and retrieved point counts
 class trackSequenceQueryRadReporter : public Reporter { 
@@ -469,8 +468,28 @@
 	std::cout << r.trackID << " ";
       std::cout << r.count << std::endl;
     }
-  } else {
-    // FIXME
+  } 
+ else {
+    ((adb__queryResponse*)adbQueryResponse)->result.__sizeRlist=size;
+    ((adb__queryResponse*)adbQueryResponse)->result.__sizeDist=size;
+    ((adb__queryResponse*)adbQueryResponse)->result.__sizeQpos=size;
+    ((adb__queryResponse*)adbQueryResponse)->result.__sizeSpos=size;
+    ((adb__queryResponse*)adbQueryResponse)->result.Rlist= new char*[size];
+    ((adb__queryResponse*)adbQueryResponse)->result.Dist = new double[size];
+    ((adb__queryResponse*)adbQueryResponse)->result.Qpos = new unsigned int[size];
+    ((adb__queryResponse*)adbQueryResponse)->result.Spos = new unsigned int[size];
+    unsigned int k = 0;
+    for(rit = v.rbegin(); rit < v.rend(); rit++, k++) {
+      r = *rit;
+      ((adb__queryResponse*)adbQueryResponse)->result.Rlist[k] = new char[O2_MAXFILESTR];
+      ((adb__queryResponse*)adbQueryResponse)->result.Dist[k] = 0;
+      ((adb__queryResponse*)adbQueryResponse)->result.Qpos[k] = 0;
+      ((adb__queryResponse*)adbQueryResponse)->result.Spos[k] = 0;
+      if(fileTable)
+	snprintf(((adb__queryResponse*)adbQueryResponse)->result.Rlist[k], O2_MAXFILESTR, "%s", fileTable+r.trackID*O2_FILETABLE_ENTRY_SIZE);
+      else
+	snprintf(((adb__queryResponse*)adbQueryResponse)->result.Rlist[k], O2_MAXFILESTR, "%d", r.trackID);
+    }
   }
 }
 
@@ -533,15 +552,15 @@
     if (it == set->end()) {
       set->insert(pair);
       count[trackID]++;
-      if (!isnan(dist)) {
-	r.trackID = trackID;
-	r.qpos = qpos;
-	r.dist = dist;
-	r.spos = spos;
-	point_queues[trackID].push(r);
-	if(point_queues[trackID].size() > pointNN)
-	  point_queues[trackID].pop();
-      }
+    }
+    if (!isnan(dist)) {
+      r.trackID = trackID;
+      r.qpos = qpos;
+      r.dist = dist;
+      r.spos = spos;
+      point_queues[trackID].push(r);
+      if(point_queues[trackID].size() > pointNN)
+	point_queues[trackID].pop();
     }
   }
 }
@@ -552,25 +571,46 @@
   // tiebreak behaviour as before.
   Radresult r;
   NNresult rk;
+  std::vector<Radresult> v;
+  unsigned int size;
 
-  for (int i = numFiles-1; i >= 0; i--) {
-    r.trackID = i;
-    r.count = count[i];
-    if(r.count > 0) {
-      cout.flush();
-      result.push(r);
-      if (result.size() > trackNN) {
-        result.pop();
+  if(pointNN>1){
+    for (int i = numFiles-1; i >= 0; i--) {
+      r.trackID = i;
+      r.count = count[i];
+      if(r.count > 0) {
+	cout.flush();
+	result.push(r);
+	if (result.size() > trackNN) {
+	  result.pop();
+	}
       }
     }
+    
+    size = result.size();
+    for(unsigned int k = 0; k < size; k++) {
+      r = result.top();
+      v.push_back(r);
+      result.pop();
+    }
   }
-
-  std::vector<Radresult> v;
-  unsigned int size = result.size();
-  for(unsigned int k = 0; k < size; k++) {
-    r = result.top();
-    v.push_back(r);
-    result.pop();
+  else{
+    // Instantiate a 1-NN trackAveragingNN reporter
+    trackSequenceQueryNNReporter<std::less <NNresult> >* rep = new trackSequenceQueryNNReporter<std::less <NNresult> >(1, trackNN, numFiles);
+    // Add all the points we've got to the reporter
+    for(unsigned int i=0; i<numFiles; i++){
+      int qsize = point_queues[i].size();
+      while(qsize--){
+	rk = point_queues[i].top();
+	rep->add_point(i, rk.qpos, rk.spos, rk.dist);
+	point_queues[i].pop();
+      }	
+    }
+    // Report
+    rep->report(fileTable, adbQueryResponse);
+    // Exit
+    delete[] point_queues;
+    return;
   }
 
 
@@ -599,9 +639,40 @@
 	point_queue.pop();
       }
     }
-  } else {
-    // FIXME
   }
+ else {
+   ((adb__queryResponse*)adbQueryResponse)->result.__sizeRlist=size;
+    ((adb__queryResponse*)adbQueryResponse)->result.__sizeDist=size;
+    ((adb__queryResponse*)adbQueryResponse)->result.__sizeQpos=size;
+    ((adb__queryResponse*)adbQueryResponse)->result.__sizeSpos=size;
+    ((adb__queryResponse*)adbQueryResponse)->result.Rlist= new char*[size];
+    ((adb__queryResponse*)adbQueryResponse)->result.Dist = new double[size];
+    ((adb__queryResponse*)adbQueryResponse)->result.Qpos = new unsigned int[size];
+    ((adb__queryResponse*)adbQueryResponse)->result.Spos = new unsigned int[size];
+    unsigned int k = 0;
+    // Loop over returned tracks
+    for(rit = v.rbegin(); rit < v.rend(); rit++, k++) {
+      r = *rit;
+      // Reverse the order of the points stored in point_queues
+      unsigned int qsize=point_queues[r.trackID].size();
+      while(qsize--){
+	point_queue.push(point_queues[r.trackID].top());
+	point_queues[r.trackID].pop();
+      }
+      qsize=point_queue.size();
+      rk = point_queue.top(); // Take one point from the top of the queue
+      ((adb__queryResponse*)adbQueryResponse)->result.Rlist[k] = new char[O2_MAXFILESTR];
+      ((adb__queryResponse*)adbQueryResponse)->result.Dist[k] = rk.dist;
+      ((adb__queryResponse*)adbQueryResponse)->result.Qpos[k] = rk.qpos;
+      ((adb__queryResponse*)adbQueryResponse)->result.Spos[k] = rk.spos;
+      if(fileTable)
+	snprintf(((adb__queryResponse*)adbQueryResponse)->result.Rlist[k], O2_MAXFILESTR, "%s", fileTable+r.trackID*O2_FILETABLE_ENTRY_SIZE);
+      else
+	snprintf(((adb__queryResponse*)adbQueryResponse)->result.Rlist[k], O2_MAXFILESTR, "%d", r.trackID);
+      while(qsize--) // pop the rest of the points
+	point_queue.pop();
+    }
+ }
   delete[] point_queues;
 }
 
--- a/soap.cpp	Tue Aug 05 22:40:38 2008 +0000
+++ b/soap.cpp	Wed Aug 06 21:23:14 2008 +0000
@@ -28,13 +28,13 @@
   soap_done(&soap);
 }
 
-void audioDB::ws_query(const char*dbName, const char *trackKey, const char* hostport){
+void audioDB::ws_query(const char*dbName, const char *featureFileName, const char* hostport){
   struct soap soap;
   adb__queryResponse adbQueryResponse;  
 
   soap_init(&soap);  
   if(soap_call_adb__query(&soap,hostport,NULL,
-			  (char*)dbName,(char*)trackKey,(char*)trackFileName,(char*)timesFileName,
+			  (char*)dbName,(char*)featureFileName,(char*)trackFileName,(char*)timesFileName,
 			  queryType, queryPoint, pointNN, trackNN, sequenceLength, adbQueryResponse)==SOAP_OK){
     //std::std::cerr << "result list length:" << adbQueryResponse.result.__sizeRlist << std::std::endl;
     for(int i=0; i<adbQueryResponse.result.__sizeRlist; i++)
@@ -48,10 +48,44 @@
   soap_end(&soap);
   soap_done(&soap);
 }
+
+void audioDB::ws_query_by_key(const char*dbName, const char *trackKey, const char* hostport){
+  struct soap soap;
+  adb__queryResponse adbQueryResponse;  
+  adb__sequenceQueryParms asqp;
+  
+  asqp.keyList = (char*)trackFileName;
+  asqp.timesFileName = (char*)timesFileName;
+  asqp.queryPoint = queryPoint;
+  asqp.pointNN = pointNN;
+  asqp.trackNN = trackNN;
+  asqp.sequenceLength = sequenceLength;
+  asqp.radius = radius;
+  asqp.relative_threshold = relative_threshold;
+  asqp.absolute_threshold = absolute_threshold;
+
+  soap_init(&soap);  
+  if(queryType==O2_SEQUENCE_QUERY || queryType==O2_N_SEQUENCE_QUERY){
+    if(soap_call_adb__sequenceQuery_by_key(&soap,hostport,NULL,(char*)dbName,(char*)trackKey,queryType,&asqp,adbQueryResponse)==SOAP_OK){
+      //std::std::cerr << "result list length:" << adbQueryResponse.result.__sizeRlist << std::std::endl;
+      for(int i=0; i<adbQueryResponse.result.__sizeRlist; i++)
+	std::cout << adbQueryResponse.result.Rlist[i] << " " << adbQueryResponse.result.Dist[i] 
+		  << " " << adbQueryResponse.result.Qpos[i] << " " << adbQueryResponse.result.Spos[i] << std::endl;
+    }
+    else
+      soap_print_fault(&soap,stderr);
+  }else
+    ;// FIX ME: WRITE NON-SEQUENCE QUERY BY KEY ?
+  
+  soap_destroy(&soap);
+  soap_end(&soap);
+  soap_done(&soap);
+}
+
 
 /* Server definitions */
 int adb__status(struct soap* soap, xsd__string dbName, adb__statusResponse &adbStatusResponse){
-  char* const argv[]={"audioDB",COM_STATUS,"-d",dbName};
+  char* const argv[]={"./audioDB",COM_STATUS,"-d",dbName};
   const unsigned argc = 4;
   try {
     audioDB(argc, argv, &adbStatusResponse);
@@ -125,16 +159,19 @@
   }
 }
 
-int adb__sequenceQuery(struct soap* soap, xsd__string dbName, xsd__string qKey,
-		       adb__sequenceQueryParms *parms,
-		       adb__queryResponse &adbQueryResponse) {
+// A sequence query using radius and a query key
+int adb__sequenceQuery_by_key(struct soap* soap, xsd__string dbName, xsd__string qKey, int qType,
+		       adb__sequenceQueryParms* parms,
+		       adb__queryResponse& adbQueryResponse) {
 
+  char radiusStr[256];
   char qPosStr[256];
   char pointNNStr[256];
   char trackNNStr[256];
   char seqLenStr[256];
   char relative_thresholdStr[256];
   char absolute_thresholdStr[256];
+  char qtypeStr[256];
 
   /* When the branch is merged, move this to a header and use it
      elsewhere */
@@ -143,45 +180,44 @@
 #define DOUBLESTRINGIFY(val, str) \
   snprintf(str, 256, "%f", val);
 
-  INTSTRINGIFY(parms->qPos, qPosStr);
+  INTSTRINGIFY(parms->queryPoint, qPosStr);
   INTSTRINGIFY(parms->pointNN, pointNNStr);
-  INTSTRINGIFY(parms->segNN, trackNNStr);
-  /* FIXME: decide which of segLen and seqLen should live */
-  INTSTRINGIFY(parms->segLen, seqLenStr);
+  INTSTRINGIFY(parms->trackNN, trackNNStr);
+  INTSTRINGIFY(parms->sequenceLength, seqLenStr);
 
   DOUBLESTRINGIFY(parms->relative_threshold, relative_thresholdStr);
   DOUBLESTRINGIFY(parms->absolute_threshold, absolute_thresholdStr);
-  
+  DOUBLESTRINGIFY(parms->radius, radiusStr);  
+
+  // WS queries only support 1-nearest neighbour point reporting
+  // at the moment, until we figure out how to better serve results
+  snprintf(qtypeStr, 256, "nsequence");
+
   const char *argv[] = {
     "./audioDB",
     COM_QUERY,
-    "sequence",
+    qtypeStr,
     COM_DATABASE,
     dbName, 
-    COM_FEATURES,
-    qKey,
+    COM_QUERYKEY,
+    ENSURE_STRING(qKey),
     COM_KEYLIST,
-    /* FIXME: when this branch is merged, use ENSURE_STRING */
-    parms->keyList==0?"":parms->keyList,
-    COM_TIMES,
-    parms->timesFileName==0?"":parms->timesFileName,
-    COM_QUERYPOWER,
-    parms->powerFileName==0?"":parms->powerFileName,
+    ENSURE_STRING(parms->keyList),
     COM_QPOINT, 
     qPosStr,
     COM_POINTNN,
     pointNNStr,
     COM_TRACKNN,
     trackNNStr,
+    COM_RADIUS,
+    radiusStr,
     COM_SEQLEN,
     seqLenStr,
-    COM_RELATIVE_THRESH,
-    relative_thresholdStr,
     COM_ABSOLUTE_THRESH,
     absolute_thresholdStr
   };
 
-  const unsigned argc = 25;
+  const unsigned argc = 21;
 
   try {
     audioDB(argc, (char* const*)argv, &adbQueryResponse);