annotate open.cpp @ 524:469b50a3dd84 multiprobeLSH

Fixed a bug in LSH hashtable writing to disk that doesn't always sort the t2 entries into strict weak ordering. Now it does. Lots of debugging informational code inserted.
author mas01mc
date Wed, 28 Jan 2009 16:02:17 +0000
parents cc2b97d020b1
children cfa74bcc1249
rev   line source
mas01cr@498 1 extern "C" {
mas01cr@498 2 #include "audioDB_API.h"
mas01cr@509 3 }
mas01cr@498 4 #include "audioDB-internals.h"
mas01cr@498 5
mas01cr@498 6 static bool audiodb_check_header(adb_header_t *header) {
mas01cr@498 7 /* FIXME: use syslog() or write to stderr or something to give the
mas01cr@498 8 poor user some diagnostics. */
mas01cr@509 9 if(header->magic == ADB_OLD_MAGIC) {
mas01cr@498 10 return false;
mas01cr@498 11 }
mas01cr@509 12 if(header->magic != ADB_MAGIC) {
mas01cr@498 13 return false;
mas01cr@498 14 }
mas01cr@509 15 if(header->version != ADB_FORMAT_VERSION) {
mas01cr@498 16 return false;
mas01cr@498 17 }
mas01cr@509 18 if(header->headerSize != ADB_HEADER_SIZE) {
mas01cr@498 19 return false;
mas01cr@498 20 }
mas01cr@498 21 return true;
mas01cr@498 22 }
mas01cr@498 23
mas01cr@498 24 static int audiodb_collect_keys(adb_t *adb) {
mas01cr@498 25 char *key_table = 0;
mas01cr@498 26 size_t key_table_length = 0;
mas01cr@498 27
mas01cr@498 28 if(adb->header->length > 0) {
mas01cr@498 29 unsigned nfiles = adb->header->numFiles;
mas01cr@509 30 key_table_length = align_page_up(nfiles * ADB_FILETABLE_ENTRY_SIZE);
mas01cr@498 31 mmap_or_goto_error(char *, key_table, adb->header->fileTableOffset, key_table_length);
mas01cr@498 32 for (unsigned int k = 0; k < nfiles; k++) {
mas01cr@509 33 adb->keys->push_back(key_table + k*ADB_FILETABLE_ENTRY_SIZE);
mas01cr@509 34 (*adb->keymap)[(key_table + k*ADB_FILETABLE_ENTRY_SIZE)] = k;
mas01cr@498 35 }
mas01cr@498 36 munmap(key_table, key_table_length);
mas01cr@498 37 }
mas01cr@498 38
mas01cr@498 39 return 0;
mas01cr@498 40
mas01cr@498 41 error:
mas01cr@498 42 maybe_munmap(key_table, key_table_length);
mas01cr@498 43 return 1;
mas01cr@498 44 }
mas01cr@498 45
mas01cr@498 46 static int audiodb_collect_track_lengths(adb_t *adb) {
mas01cr@498 47 uint32_t *track_table = 0;
mas01cr@498 48 size_t track_table_length = 0;
mas01cr@498 49 if(adb->header->length > 0) {
mas01cr@498 50 unsigned nfiles = adb->header->numFiles;
mas01cr@509 51 track_table_length = align_page_up(nfiles * ADB_TRACKTABLE_ENTRY_SIZE);
mas01cr@498 52 mmap_or_goto_error(uint32_t *, track_table, adb->header->trackTableOffset, track_table_length);
mas01cr@498 53 off_t offset = 0;
mas01cr@498 54 for (unsigned int k = 0; k < nfiles; k++) {
mas01cr@498 55 uint32_t track_length = track_table[k];
mas01cr@498 56 adb->track_lengths->push_back(track_length);
mas01cr@498 57 adb->track_offsets->push_back(offset);
mas01cr@498 58 offset += track_length * adb->header->dim * sizeof(double);
mas01cr@498 59 }
mas01cr@498 60 munmap(track_table, track_table_length);
mas01cr@498 61 }
mas01cr@498 62
mas01cr@498 63 return 0;
mas01cr@498 64
mas01cr@498 65 error:
mas01cr@498 66 maybe_munmap(track_table, track_table_length);
mas01cr@498 67 return 1;
mas01cr@498 68 }
mas01cr@498 69
mas01cr@498 70 adb_t *audiodb_open(const char *path, int flags) {
mas01cr@498 71 adb_t *adb = 0;
mas01cr@498 72 int fd = -1;
mas01cr@498 73
mas01cr@498 74 flags &= (O_RDONLY|O_RDWR);
mas01cr@498 75 fd = open(path, flags);
mas01cr@498 76 if(fd == -1) {
mas01cr@498 77 goto error;
mas01cr@498 78 }
mas01cr@498 79 if(acquire_lock(fd, flags == O_RDWR)) {
mas01cr@498 80 goto error;
mas01cr@498 81 }
mas01cr@498 82
mas01cr@498 83 adb = (adb_t *) calloc(1, sizeof(adb_t));
mas01cr@498 84 if(!adb) {
mas01cr@498 85 goto error;
mas01cr@498 86 }
mas01cr@498 87 adb->fd = fd;
mas01cr@498 88 adb->flags = flags;
mas01cr@498 89 adb->path = (char *) malloc(1+strlen(path));
mas01cr@498 90 if(!(adb->path)) {
mas01cr@498 91 goto error;
mas01cr@498 92 }
mas01cr@498 93 strcpy(adb->path, path);
mas01cr@498 94
mas01cr@498 95 adb->header = (adb_header_t *) malloc(sizeof(adb_header_t));
mas01cr@498 96 if(!(adb->header)) {
mas01cr@498 97 goto error;
mas01cr@498 98 }
mas01cr@509 99 if(read(fd, (char *) adb->header, ADB_HEADER_SIZE) != ADB_HEADER_SIZE) {
mas01cr@498 100 goto error;
mas01cr@498 101 }
mas01cr@498 102 if(!audiodb_check_header(adb->header)) {
mas01cr@498 103 goto error;
mas01cr@498 104 }
mas01cr@498 105
mas01cr@498 106 adb->keys = new std::vector<std::string>;
mas01cr@498 107 if(!adb->keys) {
mas01cr@498 108 goto error;
mas01cr@498 109 }
mas01cr@498 110 adb->keymap = new std::map<std::string,uint32_t>;
mas01cr@498 111 if(!adb->keymap) {
mas01cr@498 112 goto error;
mas01cr@498 113 }
mas01cr@498 114 if(audiodb_collect_keys(adb)) {
mas01cr@498 115 goto error;
mas01cr@498 116 }
mas01cr@498 117 adb->track_lengths = new std::vector<uint32_t>;
mas01cr@498 118 if(!adb->track_lengths) {
mas01cr@498 119 goto error;
mas01cr@498 120 }
mas01cr@498 121 adb->track_lengths->reserve(adb->header->numFiles);
mas01cr@498 122 adb->track_offsets = new std::vector<off_t>;
mas01cr@498 123 if(!adb->track_offsets) {
mas01cr@498 124 goto error;
mas01cr@498 125 }
mas01cr@498 126 adb->track_offsets->reserve(adb->header->numFiles);
mas01cr@498 127 if(audiodb_collect_track_lengths(adb)) {
mas01cr@498 128 goto error;
mas01cr@498 129 }
mas01cr@498 130 adb->cached_lsh = 0;
mas01cr@498 131 return adb;
mas01cr@498 132
mas01cr@498 133 error:
mas01cr@498 134 if(adb) {
mas01cr@498 135 if(adb->header) {
mas01cr@498 136 free(adb->header);
mas01cr@498 137 }
mas01cr@498 138 if(adb->path) {
mas01cr@498 139 free(adb->path);
mas01cr@498 140 }
mas01cr@498 141 if(adb->keys) {
mas01cr@498 142 delete adb->keys;
mas01cr@498 143 }
mas01cr@498 144 if(adb->keymap) {
mas01cr@498 145 delete adb->keymap;
mas01cr@498 146 }
mas01cr@498 147 if(adb->track_lengths) {
mas01cr@498 148 delete adb->track_lengths;
mas01cr@498 149 }
mas01cr@498 150 free(adb);
mas01cr@498 151 }
mas01cr@498 152 if(fd != -1) {
mas01cr@498 153 close(fd);
mas01cr@498 154 }
mas01cr@498 155 return NULL;
mas01cr@498 156 }