Changeset: 08c6f015356d for MonetDB URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=08c6f015356d Modified Files: gdk/gdk_interprocess.c gdk/gdk_interprocess.h monetdb5/extras/pyapi/connection.c monetdb5/extras/pyapi/pyapi.c Branch: default Log Message:
Move logic for copying BATs into files into functions and 8-byte align the values. diffs (185 lines): diff --git a/gdk/gdk_interprocess.c b/gdk/gdk_interprocess.c --- a/gdk/gdk_interprocess.c +++ b/gdk/gdk_interprocess.c @@ -282,4 +282,73 @@ GDKreleasesem(int sem_id, str *msg) { return GDK_SUCCEED; } +// align to 8 bytes +#define align(sz) ((sz + 7) & ~7) + +size_t +GDKbatcopysize(BAT *bat, str colname) { + size_t size = 0; + + size += align(strlen(colname) + 1); //[COLNAME] + size += align(sizeof(BAT)); //[BAT] + size += align(bat->twidth * BATcount(bat)); //[DATA] + + if (bat->tvheap != NULL) { + size += align(sizeof(Heap)); //[VHEAP] + size += align(bat->tvheap->size); //[VHEAPDATA] + } + return size; +} + +size_t +GDKbatcopy(char *dest, BAT *bat, str colname) { + size_t batsize = bat->twidth * BATcount(bat); + size_t position = 0; + + //[COLNAME] + memcpy(dest + position, colname, strlen(colname) + 1); + position += align(strlen(colname) + 1); + //[BAT] + memcpy(dest + position, bat, sizeof(BAT)); + position += align(sizeof(BAT)); + //[DATA] + memcpy(dest + position, Tloc(bat, BUNfirst(bat)), batsize); + position += align(batsize); + if (bat->tvheap != NULL) { + //[VHEAP] + memcpy(dest + position, bat->tvheap, sizeof(Heap)); + position += align(sizeof(Heap)); + //[VHEAPDATA] + memcpy(dest + position, bat->tvheap->base, bat->tvheap->size); + position += align(bat->tvheap->size); + } + return position; +} + +size_t +GDKbatread(char *src, BAT **bat, str *colname) { + size_t position = 0; + BAT *b; + //load the data for this column from shared memory + //[COLNAME] + *colname = src + position; + position += align(strlen(*colname) + 1); + //[BAT] + b = (BAT*) (src + position); + position += align(sizeof(BAT)); + //[DATA] + b->theap.base = (void*)(src + position); + position += align(b->twidth * BATcount(b)); + if (b->tvheap != NULL) { + //[VHEAP] + b->tvheap = (Heap*) (src + position); + position += align(sizeof(Heap)); + //[VHEAPDATA] + b->tvheap->base = (void*) (src + position); + position += align(b->tvheap->size); + } + *bat = b; + return position; +} + #endif diff --git a/gdk/gdk_interprocess.h b/gdk/gdk_interprocess.h --- a/gdk/gdk_interprocess.h +++ b/gdk/gdk_interprocess.h @@ -52,9 +52,18 @@ gdk_export gdk_return GDKchangesemval_ti //! Destroy an interprocess semaphore gdk_export gdk_return GDKreleasesem(int sem_id, str *msg); -//str init_mmap_memory(size_t base_id, size_t id_offset, size_t maxsize, void ***return_ptr, size_t **return_size, char **single_ptr); -//str release_mmap_memory(void *ptr, size_t size, size_t id); -//str snprintf_mmap_file(str file, size_t max, size_t id); +/* + * Operations for copying a BAT into a memory mapped file + */ + +//! Returns the size of the buffer necessary to copy the BAT into +gdk_export size_t GDKbatcopysize(BAT *bat, str colname); +//! Copies a BAT into the given destination. Returns the amount of bytes copied (equiv. to GDKbatcopysize(bat)) +gdk_export size_t GDKbatcopy(char *dest, BAT *bat, str colname); +//! Reads a BAT from the given source (one that was copied into by GDKbatcopy) +gdk_export size_t GDKbatread(char *src, BAT **bat, str *colname); + + #endif #endif /* _GDK_INTERPROCES_H_ */ diff --git a/monetdb5/extras/pyapi/connection.c b/monetdb5/extras/pyapi/connection.c --- a/monetdb5/extras/pyapi/connection.c +++ b/monetdb5/extras/pyapi/connection.c @@ -116,27 +116,9 @@ static PyObject * for(i = 0; i < self->query_ptr->nr_cols; i++) { BAT *b; - char *colname; + str colname; PyInput input; - - //load the data for this column from shared memory - //[COLNAME] - colname = ptr + position; - position += strlen(colname) + 1; - //[BAT] - b = (BAT*) (ptr + position); - position += sizeof(BAT); - //[DATA] - b->theap.base = (void*)(ptr + position); - position += b->twidth * BATcount(b); - if (b->tvheap != NULL) { - //[VHEAP] - b->tvheap = (Heap*) (ptr + position); - position += sizeof(Heap); - //[VHEAPDATA] - b->tvheap->base = (void*) (ptr + position); - position += b->tvheap->size; - } + position += GDKbatread(ptr + position, &b, &colname); //initialize the PyInput structure input.bat = b; input.count = BATcount(b); diff --git a/monetdb5/extras/pyapi/pyapi.c b/monetdb5/extras/pyapi/pyapi.c --- a/monetdb5/extras/pyapi/pyapi.c +++ b/monetdb5/extras/pyapi/pyapi.c @@ -762,17 +762,7 @@ str PyAPIeval(Client cntxt, MalBlkPtr mb for (i = 0; i < output->nr_cols; i++) { res_col col = output->cols[i]; BAT* b = BATdescriptor(col.b); - size_t batsize = b->twidth * BATcount(b); - char *colname = col.name; - - size += strlen(colname) + 1; //[COLNAME] - size += sizeof(BAT); //[BAT] - size += batsize; //[DATA] - - if (b->tvheap != NULL) { - size += sizeof(Heap); //[VHEAP] - size += b->tvheap->size; //[VHEAPDATA] - } + size += GDKbatcopysize(b, col.name); BBPunfix(b->batCacheid); } @@ -794,26 +784,7 @@ str PyAPIeval(Client cntxt, MalBlkPtr mb for (i = 0; i < output->nr_cols; i++) { res_col col = output->cols[i]; BAT* b = BATdescriptor(col.b); - char *colname = col.name; - size_t batsize = b->twidth * BATcount(b); - - //[COLNAME] - memcpy(result_ptr + position, colname, strlen(colname) + 1); - position += strlen(colname) + 1; - //[BAT] - memcpy(result_ptr + position, b, sizeof(BAT)); - position += sizeof(BAT); - //[DATA] - memcpy(result_ptr + position, Tloc(b, BUNfirst(b)), batsize); - position += batsize; - if (b->tvheap != NULL) { - //[VHEAP] - memcpy(result_ptr + position, b->tvheap, sizeof(Heap)); - position += sizeof(Heap); - //[VHEAPDATA] - memcpy(result_ptr + position, b->tvheap->base, b->tvheap->size); - position += b->tvheap->size; - } + result_ptr += GDKbatcopy(result_ptr + position, b, col.name); BBPunfix(b->batCacheid); } //detach the main process from this piece of shared memory so the child process can delete it _______________________________________________ checkin-list mailing list checkin-list@monetdb.org https://www.monetdb.org/mailman/listinfo/checkin-list