Mercurial > hg > audiodb
comparison audioDB.cpp @ 469:d3afc91d205d api-inversion
Move audioDB::query over to audioDB.cpp
At the same time, remove all the abstraction violations in
audioDB::query, which came in two flavours: use of dbH->numFiles, which
is dealt with by getting the database status instead (and is eventually
unnecessary, being only needed now because reporters are implemented in
terms of vectors indexed by ID), and use of fileTable in reporter's
report functions (dealt with by passing in the adb instead).
To actually implement reporting as of now, we continue to use stuff from
audioDB-internals.h; maybe someday we will be clean and shiny.
author | mas01cr |
---|---|
date | Wed, 31 Dec 2008 15:44:16 +0000 |
parents | 1030664df98c |
children | 8fb85fbcaba6 |
comparison
equal
deleted
inserted
replaced
468:4dbd7917bf9e | 469:d3afc91d205d |
---|---|
1 #include "audioDB.h" | 1 #include "audioDB.h" |
2 extern "C" { | 2 extern "C" { |
3 #include "audioDB_API.h" | 3 #include "audioDB_API.h" |
4 #include "audioDB-internals.h" | 4 #include "audioDB-internals.h" |
5 } | 5 } |
6 #include "reporter.h" | |
6 | 7 |
7 char* SERVER_ADB_ROOT; | 8 char* SERVER_ADB_ROOT; |
8 char* SERVER_ADB_FEATURE_ROOT; | 9 char* SERVER_ADB_FEATURE_ROOT; |
9 | 10 |
10 PointPair::PointPair(Uns32T a, Uns32T b, Uns32T c):trackID(a),qpos(b),spos(c){}; | 11 PointPair::PointPair(Uns32T a, Uns32T b, Uns32T c):trackID(a),qpos(b),spos(c){}; |
820 | 821 |
821 // Report status | 822 // Report status |
822 status(dbName); | 823 status(dbName); |
823 } | 824 } |
824 | 825 |
826 void audioDB::query(const char* dbName, const char* inFile, adb__queryResponse *adbQueryResponse) { | |
827 | |
828 if(!adb) { | |
829 if(!(adb = audiodb_open(dbName, O_RDWR))) { | |
830 error("failed to open database", dbName); | |
831 } | |
832 } | |
833 | |
834 /* FIXME: we only need this for getting nfiles, which we only need | |
835 * because the reporters aren't desperately well implemented, | |
836 * relying on statically-sized vectors rather than adjustable data | |
837 * structures. Rework reporter.h to be less lame. */ | |
838 adb_status_t status; | |
839 audiodb_status(adb, &status); | |
840 uint32_t nfiles = status.numFiles; | |
841 | |
842 adb_query_spec_t qspec; | |
843 adb_datum_t datum = {0}; | |
844 | |
845 qspec.refine.flags = 0; | |
846 if(trackFile) { | |
847 qspec.refine.flags |= ADB_REFINE_INCLUDE_KEYLIST; | |
848 std::vector<const char *> v; | |
849 char *k = new char[MAXSTR]; | |
850 trackFile->getline(k, MAXSTR); | |
851 while(!trackFile->eof()) { | |
852 v.push_back(k); | |
853 k = new char[MAXSTR]; | |
854 trackFile->getline(k, MAXSTR); | |
855 } | |
856 delete [] k; | |
857 qspec.refine.include.nkeys = v.size(); | |
858 qspec.refine.include.keys = new const char *[qspec.refine.include.nkeys]; | |
859 for(unsigned int k = 0; k < qspec.refine.include.nkeys; k++) { | |
860 qspec.refine.include.keys[k] = v[k]; | |
861 } | |
862 } | |
863 if(query_from_key) { | |
864 qspec.refine.flags |= ADB_REFINE_EXCLUDE_KEYLIST; | |
865 qspec.refine.exclude.nkeys = 1; | |
866 qspec.refine.exclude.keys = &key; | |
867 } | |
868 if(radius) { | |
869 qspec.refine.flags |= ADB_REFINE_RADIUS; | |
870 qspec.refine.radius = radius; | |
871 } | |
872 if(use_absolute_threshold) { | |
873 qspec.refine.flags |= ADB_REFINE_ABSOLUTE_THRESHOLD; | |
874 qspec.refine.absolute_threshold = absolute_threshold; | |
875 } | |
876 if(use_relative_threshold) { | |
877 qspec.refine.flags |= ADB_REFINE_RELATIVE_THRESHOLD; | |
878 qspec.refine.relative_threshold = relative_threshold; | |
879 } | |
880 if(usingTimes) { | |
881 qspec.refine.flags |= ADB_REFINE_DURATION_RATIO; | |
882 qspec.refine.duration_ratio = timesTol; | |
883 } | |
884 /* FIXME: not sure about this any more; maybe it belongs in | |
885 query_id? Or maybe we just don't need a flag for it? */ | |
886 qspec.refine.hopsize = sequenceHop; | |
887 if(sequenceHop != 1) { | |
888 qspec.refine.flags |= ADB_REFINE_HOP_SIZE; | |
889 } | |
890 | |
891 if(query_from_key) { | |
892 datum.key = key; | |
893 } else { | |
894 int fd; | |
895 struct stat st; | |
896 | |
897 /* FIXME: around here there are all sorts of hideous leaks. */ | |
898 fd = open(inFile, O_RDONLY); | |
899 if(fd < 0) { | |
900 error("failed to open feature file", inFile); | |
901 } | |
902 fstat(fd, &st); | |
903 read(fd, &datum.dim, sizeof(uint32_t)); | |
904 datum.nvectors = (st.st_size - sizeof(uint32_t)) / (datum.dim * sizeof(double)); | |
905 datum.data = (double *) malloc(st.st_size - sizeof(uint32_t)); | |
906 read(fd, datum.data, st.st_size - sizeof(uint32_t)); | |
907 close(fd); | |
908 if(usingPower) { | |
909 uint32_t one; | |
910 fd = open(powerFileName, O_RDONLY); | |
911 if(fd < 0) { | |
912 error("failed to open power file", powerFileName); | |
913 } | |
914 read(fd, &one, sizeof(uint32_t)); | |
915 if(one != 1) { | |
916 error("malformed power file dimensionality", powerFileName); | |
917 } | |
918 datum.power = (double *) malloc(datum.nvectors * sizeof(double)); | |
919 if(read(fd, datum.power, datum.nvectors * sizeof(double)) != (ssize_t) (datum.nvectors * sizeof(double))) { | |
920 error("malformed power file", powerFileName); | |
921 } | |
922 close(fd); | |
923 } | |
924 if(usingTimes) { | |
925 datum.times = (double *) malloc(2 * datum.nvectors * sizeof(double)); | |
926 insertTimeStamps(datum.nvectors, timesFile, datum.times); | |
927 } | |
928 } | |
929 | |
930 qspec.qid.datum = &datum; | |
931 qspec.qid.sequence_length = sequenceLength; | |
932 qspec.qid.flags = 0; | |
933 qspec.qid.flags |= usingQueryPoint ? 0 : ADB_QID_FLAG_EXHAUSTIVE; | |
934 qspec.qid.flags |= lsh_exact ? 0 : ADB_QID_FLAG_ALLOW_FALSE_POSITIVES; | |
935 qspec.qid.sequence_start = queryPoint; | |
936 | |
937 switch(queryType) { | |
938 case O2_POINT_QUERY: | |
939 qspec.qid.sequence_length = 1; | |
940 qspec.params.accumulation = ADB_ACCUMULATION_DB; | |
941 qspec.params.distance = ADB_DISTANCE_DOT_PRODUCT; | |
942 qspec.params.npoints = pointNN; | |
943 qspec.params.ntracks = 0; | |
944 reporter = new pointQueryReporter< std::greater < NNresult > >(pointNN); | |
945 break; | |
946 case O2_TRACK_QUERY: | |
947 qspec.qid.sequence_length = 1; | |
948 qspec.params.accumulation = ADB_ACCUMULATION_PER_TRACK; | |
949 qspec.params.distance = ADB_DISTANCE_DOT_PRODUCT; | |
950 qspec.params.npoints = pointNN; | |
951 qspec.params.ntracks = trackNN; | |
952 reporter = new trackAveragingReporter< std::greater< NNresult > >(pointNN, trackNN, nfiles); | |
953 break; | |
954 case O2_SEQUENCE_QUERY: | |
955 case O2_N_SEQUENCE_QUERY: | |
956 qspec.params.accumulation = ADB_ACCUMULATION_PER_TRACK; | |
957 qspec.params.distance = no_unit_norming ? ADB_DISTANCE_EUCLIDEAN : ADB_DISTANCE_EUCLIDEAN_NORMED; | |
958 qspec.params.npoints = pointNN; | |
959 qspec.params.ntracks = trackNN; | |
960 switch(queryType) { | |
961 case O2_SEQUENCE_QUERY: | |
962 if(!(qspec.refine.flags & ADB_REFINE_RADIUS)) { | |
963 reporter = new trackAveragingReporter< std::less< NNresult > >(pointNN, trackNN, nfiles); | |
964 } else { | |
965 reporter = new trackSequenceQueryRadReporter(trackNN, nfiles); | |
966 } | |
967 break; | |
968 case O2_N_SEQUENCE_QUERY: | |
969 if(!(qspec.refine.flags & ADB_REFINE_RADIUS)) { | |
970 reporter = new trackSequenceQueryNNReporter< std::less < NNresult > >(pointNN, trackNN, nfiles); | |
971 } else { | |
972 reporter = new trackSequenceQueryRadNNReporter(pointNN, trackNN, nfiles); | |
973 } | |
974 break; | |
975 } | |
976 break; | |
977 case O2_ONE_TO_ONE_N_SEQUENCE_QUERY: | |
978 qspec.params.accumulation = ADB_ACCUMULATION_ONE_TO_ONE; | |
979 qspec.params.distance = ADB_DISTANCE_EUCLIDEAN_NORMED; | |
980 qspec.params.npoints = 0; | |
981 qspec.params.ntracks = 0; | |
982 break; | |
983 default: | |
984 error("unrecognized queryType"); | |
985 } | |
986 | |
987 adb_query_results_t *rs = audiodb_query_spec(adb, &qspec); | |
988 | |
989 // FIXME: free bits of datum if !query_from_key | |
990 | |
991 if(rs == NULL) { | |
992 error("audiodb_query_spec failed"); | |
993 } | |
994 | |
995 for(unsigned int k = 0; k < rs->nresults; k++) { | |
996 adb_result_t r = rs->results[k]; | |
997 reporter->add_point(audiodb_key_index(adb, r.key), r.qpos, r.ipos, r.dist); | |
998 } | |
999 audiodb_query_free_results(adb, &qspec, rs); | |
1000 | |
1001 reporter->report(adb, adbQueryResponse); | |
1002 } | |
1003 | |
825 // This entry point is visited once per instance | 1004 // This entry point is visited once per instance |
826 // so it is a good place to set any global state variables | 1005 // so it is a good place to set any global state variables |
827 int main(const int argc, const char* argv[]){ | 1006 int main(const int argc, const char* argv[]){ |
828 SERVER_ADB_ROOT = 0; // Server-side database root prefix | 1007 SERVER_ADB_ROOT = 0; // Server-side database root prefix |
829 SERVER_ADB_FEATURE_ROOT = 0; // Server-side features root prefix | 1008 SERVER_ADB_FEATURE_ROOT = 0; // Server-side features root prefix |