Mercurial > hg > audiodb
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 |