Changeset: 2e7daf0b4acd for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=2e7daf0b4acd
Modified Files:
gdk/gdk.h
gdk/gdk_bat.c
gdk/gdk_batop.c
gdk/gdk_bbp.c
gdk/gdk_group.c
gdk/gdk_hash.c
gdk/gdk_hash.h
gdk/gdk_heap.c
gdk/gdk_imprints.c
gdk/gdk_private.h
gdk/gdk_unique.c
monetdb5/mal/mal_resource.h
monetdb5/modules/kernel/status.c
sql/backends/monet5/sql.c
Branch: default
Log Message:
Reduce number of mallocs.
Since hash and imprints *always* come with a Heap structure, we might
as well include the heap into the Hash/Imprints structure instead of
allocating it separately.
diffs (truncated from 853 to 300 lines):
diff --git a/gdk/gdk.h b/gdk/gdk.h
--- a/gdk/gdk.h
+++ b/gdk/gdk.h
@@ -621,7 +621,7 @@ typedef struct {
BUN mask; /* number of hash buckets-1 (power of 2) */
void *Hash; /* hash table */
void *Link; /* collision list */
- Heap *heap; /* heap where the hash is stored */
+ Heap heap; /* heap where the hash is stored */
} Hash;
typedef struct Imprints Imprints;
diff --git a/gdk/gdk_bat.c b/gdk/gdk_bat.c
--- a/gdk/gdk_bat.c
+++ b/gdk/gdk_bat.c
@@ -1410,7 +1410,7 @@ BATvmsize(BAT *b, int dirty)
if (b->batDirty || (b->batPersistence != TRANSIENT &&
!b->batCopiedtodisk))
dirty = 0;
return (!dirty || b->theap.dirty ? HEAPvmsize(&b->theap) : 0) +
- ((!dirty || b->theap.dirty) && b->thash && b->thash != (Hash *)
1 ? HEAPvmsize(b->thash->heap) : 0) +
+ ((!dirty || b->theap.dirty) && b->thash && b->thash != (Hash *)
1 ? HEAPvmsize(&b->thash->heap) : 0) +
(b->tvheap && (!dirty || b->tvheap->dirty) ?
HEAPvmsize(b->tvheap) : 0);
}
@@ -1423,7 +1423,7 @@ BATmemsize(BAT *b, int dirty)
dirty = 0;
return (!dirty || b->batDirtydesc ? sizeof(BAT) : 0) +
(!dirty || b->theap.dirty ? HEAPmemsize(&b->theap) : 0) +
- ((!dirty || b->theap.dirty) && b->thash && b->thash != (Hash *)
1 ? HEAPmemsize(b->thash->heap) : 0) +
+ ((!dirty || b->theap.dirty) && b->thash && b->thash != (Hash *)
1 ? HEAPmemsize(&b->thash->heap) : 0) +
(b->tvheap && (!dirty || b->tvheap->dirty) ?
HEAPmemsize(b->tvheap) : 0);
}
@@ -2169,17 +2169,16 @@ BATassertProps(BAT *b)
/* we need to check for uniqueness the hard
* way (i.e. using a hash table) */
const char *nme = BBP_physical(b->batCacheid);
- Heap *hp;
Hash *hs = NULL;
BUN mask;
- if ((hp = GDKzalloc(sizeof(Heap))) == NULL) {
+ if ((hs = GDKzalloc(sizeof(Hash))) == NULL) {
fprintf(stderr,
"#BATassertProps: cannot allocate "
"hash table\n");
goto abort_check;
}
- snprintf(hp->filename, sizeof(hp->filename),
+ snprintf(hs->heap.filename, sizeof(hs->heap.filename),
"%s.hash%d", nme, THRgettid());
if (ATOMsize(b->ttype) == 1)
mask = (BUN) 1 << 8;
@@ -2187,11 +2186,11 @@ BATassertProps(BAT *b)
mask = (BUN) 1 << 16;
else
mask = HASHmask(b->batCount);
- if ((hp->farmid = BBPselectfarm(TRANSIENT, b->ttype,
+ if ((hs->heap.farmid = BBPselectfarm(TRANSIENT,
b->ttype,
hashheap)) < 0 ||
- (hs = HASHnew(hp, b->ttype, BUNlast(b),
- mask, BUN_NONE)) == NULL) {
- GDKfree(hp);
+ HASHnew(hs, b->ttype, BUNlast(b),
+ mask, BUN_NONE) != GDK_SUCCEED) {
+ GDKfree(hs);
fprintf(stderr,
"#BATassertProps: cannot allocate "
"hash table\n");
@@ -2214,8 +2213,7 @@ BATassertProps(BAT *b)
if (cmp == 0)
seennil = 1;
}
- HEAPfree(hp, 1);
- GDKfree(hp);
+ HEAPfree(&hs->heap, 1);
GDKfree(hs);
}
abort_check:
diff --git a/gdk/gdk_batop.c b/gdk/gdk_batop.c
--- a/gdk/gdk_batop.c
+++ b/gdk/gdk_batop.c
@@ -1100,7 +1100,6 @@ BATkeyed(BAT *b)
const char *nme;
BUN prb;
BUN mask;
- Heap *hp = NULL;
GDKclrerr(); /* not interested in BAThash errors */
nme = BBP_physical(b->batCacheid);
@@ -1115,13 +1114,11 @@ BATkeyed(BAT *b)
if (mask < ((BUN) 1 << 16))
mask = (BUN) 1 << 16;
}
- if ((hp = GDKzalloc(sizeof(Heap))) == NULL ||
- snprintf(hp->filename, sizeof(hp->filename),
+ if ((hs = GDKzalloc(sizeof(Hash))) == NULL ||
+ snprintf(hs->heap.filename,
sizeof(hs->heap.filename),
"%s.hash%d", nme, THRgettid()) < 0 ||
- (hs = HASHnew(hp, b->ttype, BUNlast(b), mask,
BUN_NONE)) == NULL) {
- if (hp) {
- GDKfree(hp);
- }
+ HASHnew(hs, b->ttype, BUNlast(b), mask, BUN_NONE)
!= GDK_SUCCEED) {
+ GDKfree(hs);
/* err on the side of caution: not keyed */
goto doreturn;
}
@@ -1144,8 +1141,7 @@ BATkeyed(BAT *b)
HASHput(hs, prb, p);
}
doreturn_free:
- HEAPfree(hp, 1);
- GDKfree(hp);
+ HEAPfree(&hs->heap, 1);
GDKfree(hs);
if (p == q) {
/* we completed the complete scan: no
diff --git a/gdk/gdk_bbp.c b/gdk/gdk_bbp.c
--- a/gdk/gdk_bbp.c
+++ b/gdk/gdk_bbp.c
@@ -2058,14 +2058,14 @@ BBPdump(void)
if (b->thash && b->thash != (Hash *) -1) {
fprintf(stderr,
" Thash=[" SZFMT "," SZFMT "]",
- HEAPmemsize(b->thash->heap),
- HEAPvmsize(b->thash->heap));
+ HEAPmemsize(&b->thash->heap),
+ HEAPvmsize(&b->thash->heap));
if (BBP_logical(i) && BBP_logical(i)[0] == '.') {
- cmem += HEAPmemsize(b->thash->heap);
- cvm += HEAPvmsize(b->thash->heap);
+ cmem += HEAPmemsize(&b->thash->heap);
+ cvm += HEAPvmsize(&b->thash->heap);
} else {
- mem += HEAPmemsize(b->thash->heap);
- vm += HEAPvmsize(b->thash->heap);
+ mem += HEAPmemsize(&b->thash->heap);
+ vm += HEAPvmsize(&b->thash->heap);
}
}
fprintf(stderr, " role: %s, persistence: %s\n",
diff --git a/gdk/gdk_group.c b/gdk/gdk_group.c
--- a/gdk/gdk_group.c
+++ b/gdk/gdk_group.c
@@ -1084,7 +1084,6 @@ BATgroup_internal(BAT **groups, BAT **ex
} else {
bit gc = g && (BATordered(g) || BATordered_rev(g));
const char *nme;
- Heap *hp = NULL;
BUN prb;
int bits;
BUN mask;
@@ -1113,16 +1112,14 @@ BATgroup_internal(BAT **groups, BAT **ex
/* mask is a power of two, so pop(mask - 1) tells us
* which power of two */
bits = 8 * SIZEOF_OID - pop(mask - 1);
- if ((hp = GDKzalloc(sizeof(Heap))) == NULL ||
- (hp->farmid = BBPselectfarm(TRANSIENT, b->ttype, hashheap))
< 0 ||
- snprintf(hp->filename, sizeof(hp->filename),
+ if ((hs = GDKzalloc(sizeof(Hash))) == NULL ||
+ (hs->heap.farmid = BBPselectfarm(TRANSIENT, b->ttype,
hashheap)) < 0 ||
+ snprintf(hs->heap.filename, sizeof(hs->heap.filename),
"%s.hash%d", nme, THRgettid()) < 0 ||
- (hs = HASHnew(hp, b->ttype, BUNlast(b),
- mask, BUN_NONE)) == NULL) {
- if (hp) {
- GDKfree(hp);
- }
- hp = NULL;
+ HASHnew(hs, b->ttype, BUNlast(b),
+ mask, BUN_NONE) != GDK_SUCCEED) {
+ GDKfree(hs);
+ hs = NULL;
GDKerror("BATgroup: cannot allocate hash table\n");
goto error;
}
@@ -1210,8 +1207,7 @@ BATgroup_internal(BAT **groups, BAT **ex
GRP_create_partial_hash_table_any();
}
- HEAPfree(hp, 1);
- GDKfree(hp);
+ HEAPfree(&hs->heap, 1);
GDKfree(hs);
}
if (extents) {
@@ -1247,6 +1243,10 @@ BATgroup_internal(BAT **groups, BAT **ex
*groups = gn;
return GDK_SUCCEED;
error:
+ if (hs != NULL && hs != b->thash) {
+ HEAPfree(&hs->heap, 1);
+ GDKfree(hs);
+ }
if (gn)
BBPunfix(gn->batCacheid);
if (en)
diff --git a/gdk/gdk_hash.c b/gdk/gdk_hash.c
--- a/gdk/gdk_hash.c
+++ b/gdk/gdk_hash.c
@@ -90,18 +90,15 @@ HASHclear(Hash *h)
#define HASH_VERSION 1
#define HASH_HEADER_SIZE 5 /* nr of size_t fields in header */
-Hash *
-HASHnew(Heap *hp, int tpe, BUN size, BUN mask, BUN count)
+gdk_return
+HASHnew(Hash *h, int tpe, BUN size, BUN mask, BUN count)
{
- Hash *h = NULL;
+ Heap *hp = &h->heap;
int width = HASHwidth(size);
if (HEAPalloc(hp, mask + size + HASH_HEADER_SIZE * SIZEOF_SIZE_T /
width, width) != GDK_SUCCEED)
- return NULL;
- hp->free = (mask + size) * width + HASH_HEADER_SIZE * SIZEOF_SIZE_T;
- h = GDKmalloc(sizeof(Hash));
- if (h == NULL)
- return NULL;
+ return GDK_FAIL;
+ h->heap.free = (mask + size) * width + HASH_HEADER_SIZE * SIZEOF_SIZE_T;
h->lim = size;
h->mask = mask - 1;
h->width = width;
@@ -120,18 +117,17 @@ HASHnew(Heap *hp, int tpe, BUN size, BUN
default:
assert(0);
}
- h->Link = hp->base + HASH_HEADER_SIZE * SIZEOF_SIZE_T;
+ h->Link = h->heap.base + HASH_HEADER_SIZE * SIZEOF_SIZE_T;
h->Hash = (void *) ((char *) h->Link + h->lim * width);
h->type = tpe;
- h->heap = hp;
HASHclear(h); /* zero the mask */
- ((size_t *) hp->base)[0] = HASH_VERSION;
- ((size_t *) hp->base)[1] = size;
- ((size_t *) hp->base)[2] = mask;
- ((size_t *) hp->base)[3] = width;
- ((size_t *) hp->base)[4] = count;
+ ((size_t *) h->heap.base)[0] = HASH_VERSION;
+ ((size_t *) h->heap.base)[1] = size;
+ ((size_t *) h->heap.base)[2] = mask;
+ ((size_t *) h->heap.base)[3] = width;
+ ((size_t *) h->heap.base)[4] = count;
ALGODEBUG fprintf(stderr, "#HASHnew: create hash(size " BUNFMT ", mask
" BUNFMT ", width %d, nil " BUNFMT ", total " BUNFMT " bytes);\n", size, mask,
width, h->nil, (size + mask) * width);
- return h;
+ return GDK_SUCCEED;
}
#define starthash(TYPE)
\
@@ -200,22 +196,21 @@ BATcheckhash(BAT *b)
ALGODEBUG t = GDKusec() - t;
if (b->thash == (Hash *) 1) {
Hash *h;
- Heap *hp;
const char *nme = BBP_physical(b->batCacheid);
int fd;
b->thash = NULL;
- if ((hp = GDKzalloc(sizeof(*hp))) != NULL &&
- (hp->farmid = BBPselectfarm(b->batRole, b->ttype,
hashheap)) >= 0) {
- snprintf(hp->filename, sizeof(hp->filename),
"%s.thash", nme);
+ if ((h = GDKzalloc(sizeof(*h))) != NULL &&
+ (h->heap.farmid = BBPselectfarm(b->batRole, b->ttype,
hashheap)) >= 0) {
+ snprintf(h->heap.filename, sizeof(h->heap.filename),
+ "%s.thash", nme);
/* check whether a persisted hash can be found */
- if ((fd = GDKfdlocate(hp->farmid, nme, "rb+", "thash"))
>= 0) {
+ if ((fd = GDKfdlocate(h->heap.farmid, nme, "rb+",
"thash")) >= 0) {
size_t hdata[HASH_HEADER_SIZE];
struct stat st;
- if ((h = GDKmalloc(sizeof(*h))) != NULL &&
- read(fd, hdata, sizeof(hdata)) ==
sizeof(hdata) &&
+ if (read(fd, hdata, sizeof(hdata)) ==
sizeof(hdata) &&
hdata[0] == (
#ifdef PERSISTENTHASH
((size_t) 1 << 24) |
@@ -223,12 +218,11 @@ BATcheckhash(BAT *b)
HASH_VERSION) &&
hdata[4] == (size_t) BATcount(b) &&
fstat(fd, &st) == 0 &&
- st.st_size >= (off_t) (hp->size = hp->free
= (hdata[1] + hdata[2]) * hdata[3] + HASH_HEADER_SIZE * SIZEOF_SIZE_T) &&
- HEAPload(hp, nme, "thash", 0) ==
GDK_SUCCEED) {
+ st.st_size >= (off_t) (h->heap.size =
h->heap.free = (hdata[1] + hdata[2]) * hdata[3] + HASH_HEADER_SIZE *
SIZEOF_SIZE_T) &&
+ HEAPload(&h->heap, nme, "thash", 0) ==
GDK_SUCCEED) {
h->lim = (BUN) hdata[1];
h->type = ATOMtype(b->ttype);
h->mask = (BUN) (hdata[2] - 1);
- h->heap = hp;
h->width = (int) hdata[3];
switch (h->width) {
case BUN2:
@@ -245,23 +239,22 @@ BATcheckhash(BAT *b)
default:
assert(0);
}
- h->Link = hp->base + HASH_HEADER_SIZE *
SIZEOF_SIZE_T;
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list