changeset 389:bdd6bf8d1e85 api-inversion

More careful audiodb_create() Now with actual freeing of allocated memory, yay (even when exiting with an error).
author mas01cr
date Mon, 24 Nov 2008 12:42:17 +0000
parents f6aa8c5cd865
children f20571eeb9a6
files create.cpp
diffstat 1 files changed, 57 insertions(+), 32 deletions(-) [+]
line wrap: on
line diff
--- a/create.cpp	Mon Nov 24 11:12:57 2008 +0000
+++ b/create.cpp	Mon Nov 24 12:42:17 2008 +0000
@@ -32,6 +32,8 @@
 extern "C" {
   adb_t *audiodb_create(const char *path, unsigned datasize, unsigned ntracks, unsigned datadim) {
     int fd;
+    adb_header_t *header = 0;
+    off_t databytes, auxbytes;
     if(datasize == 0) {
       datasize = O2_DEFAULT_DATASIZE;
     }
@@ -43,27 +45,40 @@
     }
 
     if ((fd = open(path, O_RDWR|O_CREAT|O_EXCL, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH)) < 0) {
-      return NULL;
+      goto error;
     }
     if (acquire_lock(fd, true)) {
-      return NULL;
+      goto error;
     }
-    dbTableHeaderT *dbH = new dbTableHeaderT();
+
+    header = (adb_header_t *) malloc(sizeof(adb_header_t));
+    if(!header) {
+      goto error;
+    }
     
     // Initialize header
-    dbH->magic = O2_MAGIC;
-    dbH->version = O2_FORMAT_VERSION;
-    dbH->numFiles = 0;
-    dbH->dim = 0;
-    dbH->flags = 0;
-    dbH->headerSize = O2_HEADERSIZE;
-    dbH->length = 0;
-    dbH->fileTableOffset = ALIGN_PAGE_UP(O2_HEADERSIZE);
-    dbH->trackTableOffset = ALIGN_PAGE_UP(dbH->fileTableOffset + O2_FILETABLE_ENTRY_SIZE*ntracks);
-    dbH->dataOffset = ALIGN_PAGE_UP(dbH->trackTableOffset + O2_TRACKTABLE_ENTRY_SIZE*ntracks);
+    header->magic = O2_MAGIC;
+    header->version = O2_FORMAT_VERSION;
+    header->numFiles = 0;
+    header->dim = 0;
+    header->flags = 0;
+    header->headerSize = O2_HEADERSIZE;
+    header->length = 0;
+    header->fileTableOffset = ALIGN_PAGE_UP(O2_HEADERSIZE);
+    header->trackTableOffset = ALIGN_PAGE_UP(header->fileTableOffset + O2_FILETABLE_ENTRY_SIZE*ntracks);
+    header->dataOffset = ALIGN_PAGE_UP(header->trackTableOffset + O2_TRACKTABLE_ENTRY_SIZE*ntracks);
     
-    off_t databytes = ((off_t) datasize) * 1024 * 1024;
-    off_t auxbytes = databytes / datadim;
+    databytes = ((off_t) datasize) * 1024 * 1024;
+    auxbytes = databytes / datadim;
+
+    /* FIXME: what's going on here?  There are two distinct
+       preprocessor constants (O2_LSH_N_POINT_BITS, LSH_N_POINT_BITS);
+       a third is presumably some default
+       (O2_DEFAULT_LSH_N_POINT_BITS), and then there's this magic 28
+       bits.  Should this really be part of the flags structure at
+       all?  Putting it elsewhere will of course break backwards
+       compatibility, unless 14 is the only value that's been used
+       anywhere... */
     
     // For backward-compatibility, Record the point-encoding parameter for LSH indexing in the adb header
     // If this value is 0 then it will be set to 14
@@ -72,34 +87,44 @@
 #error "AudioDB Compile ERROR: consistency check of O2_LSH_POINT_BITS failed (>15)"
 #endif
     
-    dbH->flags |= LSH_N_POINT_BITS << 28;
+    header->flags |= LSH_N_POINT_BITS << 28;
     
     // If database will fit in a single file the vectors are copied into the AudioDB instance
     // Else all the vectors are left on the FileSystem and we use the dataOffset as storage
     // for the location of the features, powers and times files (assuming that arbitrary keys are used for the fileTable)
     if(ntracks<O2_LARGE_ADB_NTRACKS && datasize<O2_LARGE_ADB_SIZE){
-      dbH->timesTableOffset = ALIGN_PAGE_UP(dbH->dataOffset + databytes);
-      dbH->powerTableOffset = ALIGN_PAGE_UP(dbH->timesTableOffset + 2*auxbytes);
-      dbH->l2normTableOffset = ALIGN_PAGE_UP(dbH->powerTableOffset + auxbytes);
-      dbH->dbSize = ALIGN_PAGE_UP(dbH->l2normTableOffset + auxbytes);
+      header->timesTableOffset = ALIGN_PAGE_UP(header->dataOffset + databytes);
+      header->powerTableOffset = ALIGN_PAGE_UP(header->timesTableOffset + 2*auxbytes);
+      header->l2normTableOffset = ALIGN_PAGE_UP(header->powerTableOffset + auxbytes);
+      header->dbSize = ALIGN_PAGE_UP(header->l2normTableOffset + auxbytes);
     } else { // Create LARGE_ADB, features and powers kept on filesystem 
-      dbH->flags |= O2_FLAG_LARGE_ADB;
-      dbH->timesTableOffset = ALIGN_PAGE_UP(dbH->dataOffset + O2_FILETABLE_ENTRY_SIZE*ntracks);
-      dbH->powerTableOffset = ALIGN_PAGE_UP(dbH->timesTableOffset + O2_FILETABLE_ENTRY_SIZE*ntracks);
-      dbH->l2normTableOffset = ALIGN_PAGE_UP(dbH->powerTableOffset + O2_FILETABLE_ENTRY_SIZE*ntracks);
-      dbH->dbSize = dbH->l2normTableOffset;
+      header->flags |= O2_FLAG_LARGE_ADB;
+      header->timesTableOffset = ALIGN_PAGE_UP(header->dataOffset + O2_FILETABLE_ENTRY_SIZE*ntracks);
+      header->powerTableOffset = ALIGN_PAGE_UP(header->timesTableOffset + O2_FILETABLE_ENTRY_SIZE*ntracks);
+      header->l2normTableOffset = ALIGN_PAGE_UP(header->powerTableOffset + O2_FILETABLE_ENTRY_SIZE*ntracks);
+      header->dbSize = header->l2normTableOffset;
     } 
     
-    write(fd, dbH, O2_HEADERSIZE);
+    if (write(fd, header, O2_HEADERSIZE) != O2_HEADERSIZE) {
+      goto error;
+    }
     
     // go to the location corresponding to the last byte
-    if (lseek (fd, dbH->dbSize - 1, SEEK_SET) == -1)
-      return NULL;
-    
+    if (lseek (fd, header->dbSize - 1, SEEK_SET) == -1) {
+      goto error;
+    }
+
     // write a dummy byte at the last location
-    if (write (fd, "", 1) != 1)
-      return NULL;
-    
+    if (write (fd, "", 1) != 1) {
+      goto error;
+    }
+
     return audiodb_open(path);
+
+  error:
+    if(header) {
+      free(header);
+    }
+    return NULL;
   }
 }