mas01cr@401
|
1 #include "audioDB.h"
|
mas01cr@401
|
2 extern "C" {
|
mas01cr@401
|
3 #include "audioDB_API.h"
|
mas01cr@401
|
4 #include "audioDB-internals.h"
|
mas01cr@401
|
5 }
|
mas01cr@401
|
6
|
mas01cr@401
|
7 static int audiodb_l2norm_existing(adb_t *adb) {
|
mas01cr@401
|
8 double *data_buffer, *l2norm_buffer;
|
mas01cr@401
|
9 double *dp, *lp;
|
mas01cr@401
|
10 adb_header_t *header = adb->header;
|
mas01cr@401
|
11 size_t data_buffer_size = ALIGN_PAGE_UP(header->length);
|
mas01cr@401
|
12 size_t nvectors = header->length / (sizeof(double) * header->dim);
|
mas01cr@401
|
13 /* FIXME: this map of the vector data will lose if we ever turn the
|
mas01cr@401
|
14 * l2norm flag on when we have already inserted a large number of
|
mas01cr@401
|
15 * vectors, as the mmap() will fail. "Don't do that, then" is one
|
mas01cr@401
|
16 * possible answer. */
|
mas01cr@401
|
17 mmap_or_goto_error(double *, data_buffer, header->dataOffset, data_buffer_size);
|
mas01cr@401
|
18 l2norm_buffer = (double *) malloc(nvectors * sizeof(double));
|
mas01cr@401
|
19 if(!l2norm_buffer) {
|
mas01cr@401
|
20 goto error;
|
mas01cr@401
|
21 }
|
mas01cr@401
|
22
|
mas01cr@401
|
23 dp = data_buffer;
|
mas01cr@401
|
24 lp = l2norm_buffer;
|
mas01cr@401
|
25 for(size_t i = 0; i < nvectors; i++) {
|
mas01cr@401
|
26 *lp = 0;
|
mas01cr@401
|
27 for(unsigned int k = 0; k < header->dim; k++) {
|
mas01cr@401
|
28 *lp += (*dp)*(*dp);
|
mas01cr@401
|
29 dp++;
|
mas01cr@401
|
30 }
|
mas01cr@401
|
31 lp++;
|
mas01cr@401
|
32 }
|
mas01cr@401
|
33
|
mas01cr@401
|
34 if(lseek(adb->fd, adb->header->l2normTableOffset, SEEK_SET) == (off_t) -1) {
|
mas01cr@401
|
35 goto error;
|
mas01cr@401
|
36 }
|
mas01cr@410
|
37 write_or_goto_error(adb->fd, l2norm_buffer, nvectors * sizeof(double));
|
mas01cr@401
|
38
|
mas01cr@401
|
39 munmap(data_buffer, data_buffer_size);
|
mas01cr@401
|
40 free(l2norm_buffer);
|
mas01cr@401
|
41
|
mas01cr@401
|
42 return 0;
|
mas01cr@401
|
43
|
mas01cr@401
|
44 error:
|
mas01cr@401
|
45 maybe_munmap(data_buffer, data_buffer_size);
|
mas01cr@401
|
46 if(l2norm_buffer) {
|
mas01cr@401
|
47 free(l2norm_buffer);
|
mas01cr@401
|
48 }
|
mas01cr@401
|
49 return 1;
|
mas01cr@401
|
50 }
|
mas01cr@401
|
51
|
mas01cr@401
|
52 int audiodb_l2norm(adb_t *adb) {
|
mas01cr@401
|
53 adb_header_t *header = adb->header;
|
mas01cr@403
|
54 if(!(adb->flags & O_RDWR)) {
|
mas01cr@403
|
55 return 1;
|
mas01cr@403
|
56 }
|
mas01cr@401
|
57 if(header->flags & O2_FLAG_L2NORM) {
|
mas01cr@401
|
58 /* non-error code for forthcoming backwards-compatibility
|
mas01cr@401
|
59 * reasons */
|
mas01cr@401
|
60 return 0;
|
mas01cr@401
|
61 }
|
mas01cr@401
|
62 if((!(header->flags & O2_FLAG_LARGE_ADB)) && (header->length > 0)) {
|
mas01cr@401
|
63 if(audiodb_l2norm_existing(adb)) {
|
mas01cr@401
|
64 goto error;
|
mas01cr@401
|
65 }
|
mas01cr@401
|
66 }
|
mas01cr@401
|
67 adb->header->flags |= O2_FLAG_L2NORM;
|
mas01cr@401
|
68 return audiodb_sync_header(adb);
|
mas01cr@401
|
69
|
mas01cr@401
|
70 error:
|
mas01cr@401
|
71 return 1;
|
mas01cr@401
|
72 }
|