annotate open.cpp @ 498:342822c2d49a

Merge api-inversion branch (-r656:771, but I don't expect to return to that branch) into the trunk. I expect there to be minor performance regressions (e.g. in the SOAP server index cacheing, which I have forcibly removed) and minor unplugged memory leaks (e.g. in audioDB::query(), where I don't free up the datum). I hope that these leaks and performance regressions can be plugged in short order. I also expect that some (but maybe not all) of the issues currently addressed in the memory-leaks branch are superseded or fixed by this merge. There remains much work to be done; go forth and do it.
author mas01cr
date Sat, 10 Jan 2009 16:47:57 +0000
parents
children cc2b97d020b1
rev   line source
mas01cr@498 1 #include "audioDB.h"
mas01cr@498 2 extern "C" {
mas01cr@498 3 #include "audioDB_API.h"
mas01cr@498 4 #include "audioDB-internals.h"
mas01cr@498 5 }
mas01cr@498 6
mas01cr@498 7 static bool audiodb_check_header(adb_header_t *header) {
mas01cr@498 8 /* FIXME: use syslog() or write to stderr or something to give the
mas01cr@498 9 poor user some diagnostics. */
mas01cr@498 10 if(header->magic == O2_OLD_MAGIC) {
mas01cr@498 11 return false;
mas01cr@498 12 }
mas01cr@498 13 if(header->magic != O2_MAGIC) {
mas01cr@498 14 return false;
mas01cr@498 15 }
mas01cr@498 16 if(header->version != O2_FORMAT_VERSION) {
mas01cr@498 17 return false;
mas01cr@498 18 }
mas01cr@498 19 if(header->headerSize != O2_HEADERSIZE) {
mas01cr@498 20 return false;
mas01cr@498 21 }
mas01cr@498 22 return true;
mas01cr@498 23 }
mas01cr@498 24
mas01cr@498 25 static int audiodb_collect_keys(adb_t *adb) {
mas01cr@498 26 char *key_table = 0;
mas01cr@498 27 size_t key_table_length = 0;
mas01cr@498 28
mas01cr@498 29 if(adb->header->length > 0) {
mas01cr@498 30 unsigned nfiles = adb->header->numFiles;
mas01cr@498 31 key_table_length = ALIGN_PAGE_UP(nfiles * O2_FILETABLE_ENTRY_SIZE);
mas01cr@498 32 mmap_or_goto_error(char *, key_table, adb->header->fileTableOffset, key_table_length);
mas01cr@498 33 for (unsigned int k = 0; k < nfiles; k++) {
mas01cr@498 34 adb->keys->push_back(key_table + k*O2_FILETABLE_ENTRY_SIZE);
mas01cr@498 35 (*adb->keymap)[(key_table + k*O2_FILETABLE_ENTRY_SIZE)] = k;
mas01cr@498 36 }
mas01cr@498 37 munmap(key_table, key_table_length);
mas01cr@498 38 }
mas01cr@498 39
mas01cr@498 40 return 0;
mas01cr@498 41
mas01cr@498 42 error:
mas01cr@498 43 maybe_munmap(key_table, key_table_length);
mas01cr@498 44 return 1;
mas01cr@498 45 }
mas01cr@498 46
mas01cr@498 47 static int audiodb_collect_track_lengths(adb_t *adb) {
mas01cr@498 48 uint32_t *track_table = 0;
mas01cr@498 49 size_t track_table_length = 0;
mas01cr@498 50 if(adb->header->length > 0) {
mas01cr@498 51 unsigned nfiles = adb->header->numFiles;
mas01cr@498 52 track_table_length = ALIGN_PAGE_UP(nfiles * O2_TRACKTABLE_ENTRY_SIZE);
mas01cr@498 53 mmap_or_goto_error(uint32_t *, track_table, adb->header->trackTableOffset, track_table_length);
mas01cr@498 54 off_t offset = 0;
mas01cr@498 55 for (unsigned int k = 0; k < nfiles; k++) {
mas01cr@498 56 uint32_t track_length = track_table[k];
mas01cr@498 57 adb->track_lengths->push_back(track_length);
mas01cr@498 58 adb->track_offsets->push_back(offset);
mas01cr@498 59 offset += track_length * adb->header->dim * sizeof(double);
mas01cr@498 60 }
mas01cr@498 61 munmap(track_table, track_table_length);
mas01cr@498 62 }
mas01cr@498 63
mas01cr@498 64 return 0;
mas01cr@498 65
mas01cr@498 66 error:
mas01cr@498 67 maybe_munmap(track_table, track_table_length);
mas01cr@498 68 return 1;
mas01cr@498 69 }
mas01cr@498 70
mas01cr@498 71 adb_t *audiodb_open(const char *path, int flags) {
mas01cr@498 72 adb_t *adb = 0;
mas01cr@498 73 int fd = -1;
mas01cr@498 74
mas01cr@498 75 flags &= (O_RDONLY|O_RDWR);
mas01cr@498 76 fd = open(path, flags);
mas01cr@498 77 if(fd == -1) {
mas01cr@498 78 goto error;
mas01cr@498 79 }
mas01cr@498 80 if(acquire_lock(fd, flags == O_RDWR)) {
mas01cr@498 81 goto error;
mas01cr@498 82 }
mas01cr@498 83
mas01cr@498 84 adb = (adb_t *) calloc(1, sizeof(adb_t));
mas01cr@498 85 if(!adb) {
mas01cr@498 86 goto error;
mas01cr@498 87 }
mas01cr@498 88 adb->fd = fd;
mas01cr@498 89 adb->flags = flags;
mas01cr@498 90 adb->path = (char *) malloc(1+strlen(path));
mas01cr@498 91 if(!(adb->path)) {
mas01cr@498 92 goto error;
mas01cr@498 93 }
mas01cr@498 94 strcpy(adb->path, path);
mas01cr@498 95
mas01cr@498 96 adb->header = (adb_header_t *) malloc(sizeof(adb_header_t));
mas01cr@498 97 if(!(adb->header)) {
mas01cr@498 98 goto error;
mas01cr@498 99 }
mas01cr@498 100 if(read(fd, (char *) adb->header, O2_HEADERSIZE) != O2_HEADERSIZE) {
mas01cr@498 101 goto error;
mas01cr@498 102 }
mas01cr@498 103 if(!audiodb_check_header(adb->header)) {
mas01cr@498 104 goto error;
mas01cr@498 105 }
mas01cr@498 106
mas01cr@498 107 adb->keys = new std::vector<std::string>;
mas01cr@498 108 if(!adb->keys) {
mas01cr@498 109 goto error;
mas01cr@498 110 }
mas01cr@498 111 adb->keymap = new std::map<std::string,uint32_t>;
mas01cr@498 112 if(!adb->keymap) {
mas01cr@498 113 goto error;
mas01cr@498 114 }
mas01cr@498 115 if(audiodb_collect_keys(adb)) {
mas01cr@498 116 goto error;
mas01cr@498 117 }
mas01cr@498 118 adb->track_lengths = new std::vector<uint32_t>;
mas01cr@498 119 if(!adb->track_lengths) {
mas01cr@498 120 goto error;
mas01cr@498 121 }
mas01cr@498 122 adb->track_lengths->reserve(adb->header->numFiles);
mas01cr@498 123 adb->track_offsets = new std::vector<off_t>;
mas01cr@498 124 if(!adb->track_offsets) {
mas01cr@498 125 goto error;
mas01cr@498 126 }
mas01cr@498 127 adb->track_offsets->reserve(adb->header->numFiles);
mas01cr@498 128 if(audiodb_collect_track_lengths(adb)) {
mas01cr@498 129 goto error;
mas01cr@498 130 }
mas01cr@498 131 adb->cached_lsh = 0;
mas01cr@498 132 return adb;
mas01cr@498 133
mas01cr@498 134 error:
mas01cr@498 135 if(adb) {
mas01cr@498 136 if(adb->header) {
mas01cr@498 137 free(adb->header);
mas01cr@498 138 }
mas01cr@498 139 if(adb->path) {
mas01cr@498 140 free(adb->path);
mas01cr@498 141 }
mas01cr@498 142 if(adb->keys) {
mas01cr@498 143 delete adb->keys;
mas01cr@498 144 }
mas01cr@498 145 if(adb->keymap) {
mas01cr@498 146 delete adb->keymap;
mas01cr@498 147 }
mas01cr@498 148 if(adb->track_lengths) {
mas01cr@498 149 delete adb->track_lengths;
mas01cr@498 150 }
mas01cr@498 151 free(adb);
mas01cr@498 152 }
mas01cr@498 153 if(fd != -1) {
mas01cr@498 154 close(fd);
mas01cr@498 155 }
mas01cr@498 156 return NULL;
mas01cr@498 157 }