Mercurial > hg > audiodb
changeset 395:bc7a821004bb api-inversion
Invert audioDB::status / audiodb_status().
To do that without breaking abstractions, we actually need a new field
in the status structure, storing the size of the data region.
Previously, this was computed in the audioDB::status request from the
database header, but I'm assuming that "user" code doesn't have access
to such internals. While we're at it, name some intermediate values in
audioDB::status() so that I don't get confused.
Here's the thing, though: we need to make sure that the adb_t * that we
have from audiodb_open() or audiodb_create() is propagated all the way
through into the C++ routines that implement library functions -- in
particular those which actually write to the database; otherwise we
won't have a consistent view in memory of the header on-disk (as the adb
header that will have been written to disk won't be the same as the one
in memory).
We can do that, by altering the "API" audioDB constructors to take the
adb_t * argument, and setting the adb field in the audioDB object that
we've already introduced to that. But now we need to be careful a
couple of times: if we have one, then audioDB::initTables() mustn't
stomp on it; also, if we're only constructing an audioDB instance to
fulfil an API request, we mustn't audiodb_close() the one we have when
we destroy the audioDB object, because the adb_t * is the one we have
passed in and are going to reuse in later calls to the API.
The good news is that we can be careful in just these ways with minimal
code. The really good news is that once the inversion is complete, all
of this horribleness will automatically go away (as there will be no
code which constructs audioDB objects to fulfil API functions). Hooray!
It's almost like it was all planned this way.
author | mas01cr |
---|---|
date | Tue, 25 Nov 2008 16:41:01 +0000 |
parents | 64b2bf35d30b |
children | fb633cac9c3a |
files | Makefile audioDB.cpp audioDB.h audioDB_API.h common.cpp status.cpp |
diffstat | 6 files changed, 123 insertions(+), 141 deletions(-) [+] |
line wrap: on
line diff
--- a/Makefile Tue Nov 25 16:41:00 2008 +0000 +++ b/Makefile Tue Nov 25 16:41:01 2008 +0000 @@ -8,7 +8,7 @@ SHARED_LIB_FLAGS=-shared -Wl,-soname, -LIBOBJS=insert.o create.o common.o open.o close.o dump.o liszt.o query.o sample.o index.o lshlib.o cmdline.o +LIBOBJS=insert.o create.o common.o open.o close.o status.o dump.o liszt.o query.o sample.o index.o lshlib.o cmdline.o OBJS=$(LIBOBJS) soap.o audioDB.o
--- a/audioDB.cpp Tue Nov 25 16:41:00 2008 +0000 +++ b/audioDB.cpp Tue Nov 25 16:41:01 2008 +0000 @@ -166,11 +166,12 @@ //for the lib / API -audioDB::audioDB(const unsigned argc, const char *argv[], int * apierror): O2_AUDIODB_INITIALIZERS +audioDB::audioDB(const unsigned argc, const char *argv[], int * apierror, adb_t *a): O2_AUDIODB_INITIALIZERS { try { UseApiError=1; + adb = a; if(processArgs(argc, argv)<0){ printf("No command found.\n"); @@ -230,46 +231,13 @@ } -//for API status -audioDB::audioDB(const unsigned argc, const char *argv[], adb_status_t *stat, int * apierror): O2_AUDIODB_INITIALIZERS +//for API query +audioDB::audioDB(const unsigned argc, const char *argv[],adb__queryResponse *adbQueryResponse, int * apierror, adb_t *a): O2_AUDIODB_INITIALIZERS { try { UseApiError=1; - - - if(processArgs(argc, argv)<0){ - printf("No command found.\n"); - cmdline_parser_print_version (); - if (strlen(gengetopt_args_info_purpose) > 0) - printf("%s\n", gengetopt_args_info_purpose); - printf("%s\n", gengetopt_args_info_usage); - printf("%s\n", gengetopt_args_info_help[1]); - printf("%s\n", gengetopt_args_info_help[2]); - printf("%s\n", gengetopt_args_info_help[0]); - error("No command found"); - } - - status(dbName, stat); - - - } catch(int a) { - *apierror=a; - return; - - } - *apierror=apierrortemp; - return; - -} - - -//for API query -audioDB::audioDB(const unsigned argc, const char *argv[],adb__queryResponse *adbQueryResponse, int * apierror): O2_AUDIODB_INITIALIZERS -{ - - try { - UseApiError=1; + adb = a; if(processArgs(argc, argv)<0){ printf("No command found.\n"); @@ -295,10 +263,6 @@ } - - - - void audioDB::cleanup() { cmdline_parser_free(&args_info); if(indata) @@ -335,7 +299,7 @@ delete vv; if(infid>0) close(infid); - if(adb) { + if(adb && !UseApiError) { audiodb_close(adb); adb = NULL; } @@ -742,83 +706,56 @@ } void audioDB::status(const char* dbName, adb__statusResponse *adbStatusResponse){ - if(!dbH) - initTables(dbName, 0); - - unsigned dudCount=0; - unsigned nullCount=0; - for(unsigned k=0; k<dbH->numFiles; k++){ - if(trackTable[k]<sequenceLength){ - dudCount++; - if(!trackTable[k]) - nullCount++; - } + adb_t *adb; + adb_status_t status; + if(!(adb = audiodb_open(dbName, O_RDONLY))) { + error("Failed to open database file", dbName); } + if(audiodb_status(adb, &status)) { + error("Failed to retrieve database status", dbName); + } + audiodb_close(adb); if(adbStatusResponse == 0) { - - // Update Header information - std::cout << "num files:" << dbH->numFiles << std::endl; - std::cout << "data dim:" << dbH->dim <<std::endl; - if(dbH->dim>0){ - std::cout << "total vectors:" << dbH->length/(sizeof(double)*dbH->dim)<<std::endl; - if(dbH->flags & O2_FLAG_LARGE_ADB) - std::cout << "vectors available:" << O2_MAX_VECTORS - (dbH->length / (sizeof(double)*dbH->dim)) << std::endl; - else - std::cout << "vectors available:" << (dbH->timesTableOffset-(dbH->dataOffset+dbH->length))/(sizeof(double)*dbH->dim) << std::endl; + size_t bytes_per_vector = sizeof(double) * status.dim; + off_t nvectors = status.length / bytes_per_vector; + off_t data_region_vectors = status.data_region_size / bytes_per_vector; + std::cout << "num files:" << status.numFiles << std::endl; + std::cout << "data dim:" << status.dim <<std::endl; + if(status.dim > 0) { + std::cout << "total vectors:" << nvectors << std::endl; + std::cout << "vectors available:"; + if(status.flags & O2_FLAG_LARGE_ADB) { + std::cout << O2_MAX_VECTORS - nvectors << std::endl; + } else { + std::cout << data_region_vectors - nvectors << std::endl; + } } - if( ! (dbH->flags & O2_FLAG_LARGE_ADB) ){ - std::cout << "total bytes:" << dbH->length << " (" << (100.0*dbH->length)/(dbH->timesTableOffset-dbH->dataOffset) << "%)" << std::endl; - std::cout << "bytes available:" << dbH->timesTableOffset-(dbH->dataOffset+dbH->length) << " (" << - (100.0*(dbH->timesTableOffset-(dbH->dataOffset+dbH->length)))/(dbH->timesTableOffset-dbH->dataOffset) << "%)" << std::endl; + if(!(status.flags & O2_FLAG_LARGE_ADB)) { + double used_frac = ((double) status.length) / status.data_region_size; + std::cout << "total bytes:" << status.length << + " (" << (100.0*used_frac) << "%)" << std::endl; + std::cout << "bytes available:" << status.data_region_size - status.length << + " (" << (100.0*(1-used_frac)) << "%)" << std::endl; } - std::cout << "flags:" << " l2norm[" << DISPLAY_FLAG(dbH->flags&O2_FLAG_L2NORM) - << "] minmax[" << DISPLAY_FLAG(dbH->flags&O2_FLAG_MINMAX) - << "] power[" << DISPLAY_FLAG(dbH->flags&O2_FLAG_POWER) - << "] times[" << DISPLAY_FLAG(dbH->flags&O2_FLAG_TIMES) - << "] largeADB[" << DISPLAY_FLAG(dbH->flags&O2_FLAG_LARGE_ADB) + std::cout << "flags:" << " l2norm[" << DISPLAY_FLAG(status.flags&O2_FLAG_L2NORM) + << "] minmax[" << DISPLAY_FLAG(status.flags&O2_FLAG_MINMAX) + << "] power[" << DISPLAY_FLAG(status.flags&O2_FLAG_POWER) + << "] times[" << DISPLAY_FLAG(status.flags&O2_FLAG_TIMES) + << "] largeADB[" << DISPLAY_FLAG(status.flags&O2_FLAG_LARGE_ADB) << "]" << endl; - std::cout << "null count: " << nullCount << " small sequence count " << dudCount-nullCount << std::endl; + std::cout << "null count: " << status.nullCount << " small sequence count " << status.dudCount-status.nullCount << std::endl; } else { - adbStatusResponse->result.numFiles = dbH->numFiles; - adbStatusResponse->result.dim = dbH->dim; - adbStatusResponse->result.length = dbH->length; - adbStatusResponse->result.dudCount = dudCount; - adbStatusResponse->result.nullCount = nullCount; - adbStatusResponse->result.flags = dbH->flags; + adbStatusResponse->result.numFiles = status.numFiles; + adbStatusResponse->result.dim = status.dim; + adbStatusResponse->result.length = status.length; + adbStatusResponse->result.dudCount = status.dudCount; + adbStatusResponse->result.nullCount = status.nullCount; + adbStatusResponse->result.flags = status.flags; } } -///used by lib/API -void audioDB::status(const char* dbName, adb_status_t *status){ - if(!dbH) { - initTables(dbName, 0); - } - - unsigned dudCount=0; - unsigned nullCount=0; - for(unsigned k=0; k<dbH->numFiles; k++){ - if(trackTable[k]<sequenceLength){ - dudCount++; - if(!trackTable[k]) - nullCount++; - } - } - - status->numFiles = dbH->numFiles; - status->dim = dbH->dim; - status->length = dbH->length; - status->dudCount = dudCount; - status->nullCount = nullCount; - status->flags = dbH->flags; - - return; -} - - - - void audioDB::l2norm(const char* dbName) { forWrite = true; initTables(dbName, 0); @@ -944,7 +881,7 @@ } argv[argvctr]='\0'; - audioDB::audioDB(argvctr,argv,&apierror); + audioDB::audioDB(argvctr,argv,&apierror,mydb); return apierror; } @@ -1051,7 +988,7 @@ argv[argvctr]='\0'; - audioDB::audioDB(argvctr,argv,&apierror); + audioDB::audioDB(argvctr,argv,&apierror,mydb); remove(tempfeaturename); remove(temppowername); @@ -1176,7 +1113,7 @@ /* debugging */ - audioDB::audioDB(argvctr,argv, &adbQueryResponse, &apierror); + audioDB::audioDB(argvctr,argv, &adbQueryResponse, &apierror,mydb); //copy data over here from adbQueryResponse to adbqr adbqr->sizeRlist=adbQueryResponse.result.__sizeRlist; @@ -1191,24 +1128,6 @@ return apierror; } - ///* status command */ - int audiodb_status(adb_ptr mydb, adb_status_ptr status){ - int apierror=0; - - const char *argv[5]; - - apierror=0; - argv[0]="audioDB"; - argv[1]="--STATUS"; - argv[2]="-d"; - argv[3]=mydb->path; - argv[4]='\0'; - - audioDB::audioDB(4,argv,status ,&apierror); - - return apierror; - } - int audiodb_dump(adb_ptr mydb){ return audiodb_dump_withdir(mydb,"audioDB.dump"); } @@ -1227,7 +1146,7 @@ argv[argvctr++]=(char *)outputdir; argv[argvctr]='\0'; - audioDB::audioDB(6,argv,&apierror); + audioDB::audioDB(6,argv,&apierror,mydb); return apierror; } @@ -1243,7 +1162,7 @@ argv[3]=mydb->path; argv[4]='\0'; - audioDB::audioDB(4,argv,&apierror); + audioDB::audioDB(4,argv,&apierror,mydb); return apierror; } @@ -1258,7 +1177,7 @@ argv[3]=mydb->path; argv[4]='\0'; - audioDB::audioDB(4,argv,&apierror); + audioDB::audioDB(4,argv,&apierror,mydb); return apierror; } }
--- a/audioDB.h Tue Nov 25 16:41:00 2008 +0000 +++ b/audioDB.h Tue Nov 25 16:41:01 2008 +0000 @@ -347,9 +347,8 @@ audioDB(const unsigned argc, const char *argv[], adb__queryResponse *adbQueryResponse); audioDB(const unsigned argc, const char *argv[], adb__statusResponse *adbStatusResponse); audioDB(const unsigned argc, const char *argv[], adb__lisztResponse *adbLisztResponse); - audioDB(const unsigned argc, const char *argv[], int * apierror); - audioDB(const unsigned argc, const char *argv[], struct adbstatus *status, int * apierror); - audioDB(const unsigned argc, const char *argv[],adb__queryResponse *adbQueryResponse, int * apierror); + audioDB(const unsigned argc, const char *argv[], int * apierror, struct adb *a); + audioDB(const unsigned argc, const char *argv[],adb__queryResponse *adbQueryResponse, int * apierror, struct adb *a); void cleanup(); @@ -366,7 +365,6 @@ void batchinsert_large_adb(const char* dbName, const char* inFile); void query(const char* dbName, const char* inFile, adb__queryResponse *adbQueryResponse=0); void status(const char* dbName, adb__statusResponse *adbStatusResponse=0); - void status(const char* dbName, struct adbstatus *status); unsigned random_track(unsigned *propTable, unsigned total); void sample(const char *dbName);
--- a/audioDB_API.h Tue Nov 25 16:41:00 2008 +0000 +++ b/audioDB_API.h Tue Nov 25 16:41:01 2008 +0000 @@ -38,14 +38,13 @@ /* struct for returning status results */ struct adbstatus { - unsigned int numFiles; unsigned int dim; unsigned int length; unsigned int dudCount; unsigned int nullCount; unsigned int flags; - + off_t data_region_size; }; typedef struct adbstatus adb_status_t, *adb_status_ptr;
--- a/common.cpp Tue Nov 25 16:41:00 2008 +0000 +++ b/common.cpp Tue Nov 25 16:41:01 2008 +0000 @@ -98,9 +98,11 @@ } void audioDB::initDBHeader(const char* dbName) { - adb = audiodb_open(dbName, forWrite ? O_RDWR : O_RDONLY); if(!adb) { - error("Failed to open database", dbName); + adb = audiodb_open(dbName, forWrite ? O_RDWR : O_RDONLY); + if(!adb) { + error("Failed to open database", dbName); + } } dbfid = adb->fd; dbH = adb->header;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/status.cpp Tue Nov 25 16:41:01 2008 +0000 @@ -0,0 +1,64 @@ +#include "audioDB.h" +extern "C" { +#include "audioDB_API.h" +} + +int audiodb_status(adb_t *adb, adb_status_t *status) { + /* FIXME: it would be nice to be able to test for "is this database + pointer valid", but at the moment we punt that to memory + discipline. */ + + unsigned dudCount = 0; + unsigned nullCount = 0; + + off_t trackTableLength = ALIGN_PAGE_UP(adb->header->numFiles * O2_TRACKTABLE_ENTRY_SIZE); + unsigned *trackTable = 0; + void *tmp = 0; + if (adb->header->length > 0) { + tmp = mmap(0, trackTableLength, PROT_READ, MAP_SHARED, adb->fd, adb->header->trackTableOffset); + if (tmp == (void *) -1) { + return 1; + } + trackTable = (unsigned *) tmp; + } + + for(unsigned k = 0; k < adb->header->numFiles; k++) { + /* FIXME: this bare "16" here reveals a problem (or maybe two). + * 16 here means the default value of the sequenceLength parameter + * initializer (both in C++ and corresponding to the "-l" or + * "--sequencelength" command-line argument). + * + * The problem is that the API as currently designed provides no + * way to pass that information in to this routine; there's no + * input parameter; nor is there in the SOAP version of this + * query. However, there /is/ a way to pass that information on + * the command-line -- though that codepath is completely + * untested. I can see that it might be useful to provide this + * information, but at present it's probably completely unused, so + * the compromise for now is to hardwire the 16. + */ + if(trackTable[k] < 16) { + dudCount++; + if(!trackTable[k]) { + nullCount++; + } + } + } + + if(adb->header->length > 0) { + if(munmap(trackTable, trackTableLength)) { + return 1; + } + } + + status->numFiles = adb->header->numFiles; + status->dim = adb->header->dim; + status->length = adb->header->length; + status->dudCount = dudCount; + status->nullCount = nullCount; + status->flags = adb->header->flags; + status->data_region_size = adb->header->timesTableOffset - adb->header->dataOffset; + + return 0; +} +