comparison audioDB.cpp @ 548:e18843dc0aea

Implement a rudimentary API for audioDB::liszt The API is rudimentary because we've dropped support for the incremental retrieval of tracks and their number of vectors (at the API level; the SOAP and command-line support is still there -- no changes should be visible). This is potentially bad for the large-scale databases, of course; one million tracks will take of the order of 16MB of RAM, more if I'm unlucky about how std::string.c_str() is implemented. Both this liszt operation and querying (and sampling, forthcoming...) would benefit from a `cursor-like' interface to retrieval results: for an API like that, instead of getting a struct with the data there, you get a cookie with which you can ask the database for successive results. This would be neat for all sorts of reasons. In the meantime, at least this change fixes SOAP memory leaks related to liszt. Make liszt.o part of LIBOBJS rather than ordinary OBJS, so that the liszt functionality is actually compiled into the library. Add a test for this library functionality; also modify the command-line test file to run the SOAP server on its own port.
author mas01cr
date Wed, 11 Feb 2009 12:38:03 +0000
parents 5da228727a2d
children 048688d47697
comparison
equal deleted inserted replaced
547:5a248cedd3e9 548:e18843dc0aea
109 cleanup(); 109 cleanup();
110 throw(err); 110 throw(err);
111 } 111 }
112 } 112 }
113 113
114 audioDB::audioDB(const unsigned argc, const char *argv[], adb__lisztResponse *adbLisztResponse): O2_AUDIODB_INITIALIZERS 114 audioDB::audioDB(const unsigned argc, const char *argv[], struct soap *soap, adb__lisztResponse *adbLisztResponse): O2_AUDIODB_INITIALIZERS
115 { 115 {
116 try { 116 try {
117 isServer = 1; // Set to make errors report over SOAP 117 isServer = 1; // Set to make errors report over SOAP
118 processArgs(argc, argv); 118 processArgs(argc, argv);
119 // Perform database prefix substitution 119 // Perform database prefix substitution
120 if(dbName && adb_root) 120 if(dbName && adb_root)
121 prefix_name((char** const)&dbName, adb_root); 121 prefix_name((char** const)&dbName, adb_root);
122 assert(O2_ACTION(COM_LISZT)); 122 assert(O2_ACTION(COM_LISZT));
123 liszt(dbName, lisztOffset, lisztLength, adbLisztResponse); 123 liszt(dbName, lisztOffset, lisztLength, soap, adbLisztResponse);
124 } catch(char *err) { 124 } catch(char *err) {
125 cleanup(); 125 cleanup();
126 throw(err); 126 throw(err);
127 } 127 }
128 } 128 }
948 audiodb_query_free_results(adb, &qspec, rs); 948 audiodb_query_free_results(adb, &qspec, rs);
949 949
950 reporter->report(adb, soap, adbQueryResponse); 950 reporter->report(adb, soap, adbQueryResponse);
951 } 951 }
952 952
953 void audioDB::liszt(const char* dbName, unsigned offset, unsigned numLines, struct soap *soap, adb__lisztResponse* adbLisztResponse) {
954 if(!adb) {
955 if(!(adb = audiodb_open(dbName, O_RDONLY))) {
956 error("failed to open database", dbName);
957 }
958 }
959
960 adb_liszt_results_t *results = audiodb_liszt(adb);
961 if(!results) {
962 error("audiodb_liszt() failed");
963 }
964
965 if(offset > results->nresults) {
966 audiodb_liszt_free_results(adb, results);
967 error("listKeys offset out of range");
968 }
969
970 if(!adbLisztResponse){
971 for(uint32_t k = 0; k < numLines && offset + k < results->nresults; k++) {
972 uint32_t index = offset + k;
973 printf("[%d] %s (%d)\n", index, results->entries[index].key, results->entries[index].nvectors);
974 }
975 } else {
976 adbLisztResponse->result.Rkey = (char **) soap_malloc(soap, numLines * sizeof(char *));
977 adbLisztResponse->result.Rlen = (unsigned int *) soap_malloc(soap, numLines * sizeof(unsigned int));
978 uint32_t k;
979 for(k = 0; k < numLines && offset + k < results->nresults; k++) {
980 uint32_t index = offset + k;
981 adbLisztResponse->result.Rkey[k] = (char *) soap_malloc(soap, O2_MAXFILESTR);
982 snprintf(adbLisztResponse->result.Rkey[k], O2_MAXFILESTR, "%s", results->entries[index].key);
983 adbLisztResponse->result.Rlen[k] = results->entries[index].nvectors;
984 }
985 adbLisztResponse->result.__sizeRkey = k;
986 adbLisztResponse->result.__sizeRlen = k;
987 }
988 audiodb_liszt_free_results(adb, results);
989 }
990
953 // This entry point is visited once per instance 991 // This entry point is visited once per instance
954 // so it is a good place to set any global state variables 992 // so it is a good place to set any global state variables
955 int main(const int argc, const char* argv[]){ 993 int main(const int argc, const char* argv[]){
956 SERVER_ADB_ROOT = 0; // Server-side database root prefix 994 SERVER_ADB_ROOT = 0; // Server-side database root prefix
957 SERVER_ADB_FEATURE_ROOT = 0; // Server-side features root prefix 995 SERVER_ADB_FEATURE_ROOT = 0; // Server-side features root prefix