Changeset: ea8080f307e4 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/ea8080f307e4
Modified Files:
gdk/gdk.h
gdk/gdk_bat.c
gdk/gdk_batop.c
gdk/gdk_bbp.c
gdk/gdk_string.c
Branch: ustr
Log Message:
Merge with zero-offset-is-nil branch.
diffs (truncated from 1135 to 300 lines):
diff --git a/gdk/gdk.h b/gdk/gdk.h
--- a/gdk/gdk.h
+++ b/gdk/gdk.h
@@ -906,7 +906,8 @@ static inline const void *
BUNtvar(const BATiter *bi, BUN p)
{
assert(bi->type && bi->vh);
- return bi->vh->base + VarHeapVal(bi->base, p, bi->width);
+ size_t off = VarHeapVal(bi->base, p, bi->width);
+ return off == 0 ? ATOMnilptr(bi->type) : bi->vh->base + off;
}
__attribute__((__pure__))
@@ -1117,23 +1118,27 @@ BATsettrivprop(BAT *b)
b->tmaxpos = 0;
}
b->tseqbase = sqbs;
- } else if (b->tvheap
- ? ATOMeq(b->ttype,
- b->tvheap->base +
VarHeapVal(Tloc(b, 0), 0, b->twidth),
- ATOMnilptr(b->ttype))
- : ATOMeq(b->ttype, Tloc(b, 0),
- ATOMnilptr(b->ttype))) {
- /* the only value is NIL */
- b->tminpos = BUN_NONE;
- b->tmaxpos = BUN_NONE;
- b->tnil = true;
- b->tnonil = false;
} else {
- /* the only value is both min and max */
- b->tminpos = 0;
- b->tmaxpos = 0;
- b->tnonil = true;
- b->tnil = false;
+ size_t off;
+ if (b->tvheap
+ ? ((off = VarHeapVal(Tloc(b, 0), 0,
b->twidth)) == 0 ||
+ ATOMeq(b->ttype,
+ b->tvheap->base + off,
+ ATOMnilptr(b->ttype)))
+ : ATOMeq(b->ttype, Tloc(b, 0),
+ ATOMnilptr(b->ttype))) {
+ /* the only value is NIL */
+ b->tminpos = BUN_NONE;
+ b->tmaxpos = BUN_NONE;
+ b->tnil = true;
+ b->tnonil = false;
+ } else {
+ /* the only value is both min and max */
+ b->tminpos = 0;
+ b->tmaxpos = 0;
+ b->tnonil = true;
+ b->tnil = false;
+ }
}
} else {
b->tsorted = false;
@@ -1143,11 +1148,24 @@ BATsettrivprop(BAT *b)
}
} else if (b->batCount == 2 && ATOMlinear(b->ttype)) {
int c;
- if (b->tvheap)
- c = ATOMcmp(b->ttype,
- b->tvheap->base + VarHeapVal(Tloc(b, 0), 0,
b->twidth),
- b->tvheap->base + VarHeapVal(Tloc(b, 0), 1,
b->twidth));
- else
+ if (b->tvheap) {
+ size_t off0 = VarHeapVal(Tloc(b, 0), 0, b->twidth);
+ size_t off1 = VarHeapVal(Tloc(b, 0), 1, b->twidth);
+ if (off0 == off1)
+ c = 0;
+ else if (off0 == 0)
+ c = ATOMeq(b->ttype,
+ b->tvheap->base + off1,
+ ATOMnilptr(b->ttype)) - 1;
+ else if (off1 == 0)
+ c = !ATOMeq(b->ttype,
+ b->tvheap->base + off0,
+ ATOMnilptr(b->ttype));
+ else
+ c = ATOMcmp(b->ttype,
+ b->tvheap->base + off0,
+ b->tvheap->base + off1);
+ } else
c = ATOMcmp(b->ttype, Tloc(b, 0), Tloc(b, 1));
b->tsorted = c <= 0;
b->tnosorted = !b->tsorted;
@@ -1233,7 +1251,8 @@ tfastins_nocheckVAR(BAT *b, BUN p, const
MT_lock_unset(&b->theaplock);
return rc;
}
- if (b->twidth < SIZEOF_VAR_T &&
+ if (d != 0 &&
+ b->twidth < SIZEOF_VAR_T &&
(b->twidth <= 2 ? d - GDK_VAROFFSET : d) >= ((size_t) 1 << (8 <<
b->tshift))) {
/* doesn't fit in current heap, upgrade it */
rc = GDKupgradevarheap(b, d, 0, MAX(p, b->batCount));
@@ -1244,10 +1263,14 @@ tfastins_nocheckVAR(BAT *b, BUN p, const
}
switch (b->twidth) {
case 1:
- ((uint8_t *) b->theap->base)[p] = (uint8_t) (d - GDK_VAROFFSET);
+ if (d != 0)
+ d -= GDK_VAROFFSET;
+ ((uint8_t *) b->theap->base)[p] = (uint8_t) d;
break;
case 2:
- ((uint16_t *) b->theap->base)[p] = (uint16_t) (d -
GDK_VAROFFSET);
+ if (d != 0)
+ d -= GDK_VAROFFSET;
+ ((uint16_t *) b->theap->base)[p] = (uint16_t) d;
break;
case 4:
((uint32_t *) b->theap->base)[p] = (uint32_t) d;
diff --git a/gdk/gdk_atoms.c b/gdk/gdk_atoms.c
--- a/gdk/gdk_atoms.c
+++ b/gdk/gdk_atoms.c
@@ -1982,7 +1982,8 @@ BLOBeq(const void *L, const void *R)
static void
BLOBdel(Heap *h, var_t *idx)
{
- HEAP_free(h, *idx);
+ if (*idx != 0)
+ HEAP_free(h, *idx);
}
static BUN
@@ -2053,6 +2054,8 @@ BLOBput(BAT *b, var_t *bun, const void *
const blob *val = VAL;
char *base = NULL;
+ if (is_blob_nil(val))
+ return *bun = 0;
*bun = HEAP_malloc(b, blobsize(val->nitems));
base = b->tvheap->base;
if (*bun != (var_t) -1) {
diff --git a/gdk/gdk_atoms.h b/gdk/gdk_atoms.h
--- a/gdk/gdk_atoms.h
+++ b/gdk/gdk_atoms.h
@@ -444,11 +444,14 @@ __attribute__((__pure__))
static inline size_t
VarHeapVal(const void *b, BUN p, int w)
{
+ size_t off;
switch (w) {
case 1:
- return (size_t) ((const uint8_t *) b)[p] + GDK_VAROFFSET;
+ off = (size_t) ((const uint8_t *) b)[p];
+ return off == 0 ? 0 : off + GDK_VAROFFSET;
case 2:
- return (size_t) ((const uint16_t *) b)[p] + GDK_VAROFFSET;
+ off = (size_t) ((const uint16_t *) b)[p];
+ return off == 0 ? 0 : off + GDK_VAROFFSET;
case 4:
return (size_t) ((const uint32_t *) b)[p];
#if SIZEOF_VAR_T == 8
diff --git a/gdk/gdk_bat.c b/gdk/gdk_bat.c
--- a/gdk/gdk_bat.c
+++ b/gdk/gdk_bat.c
@@ -1535,7 +1535,9 @@ BUNinplacemulti(BAT *b, const oid *posit
val = BUNtmsk(&bi, p);
} else if (b->tvheap) {
size_t off = VarHeapVal(bi.base, p, bi.width);
- if (off < bi.vhfree)
+ if (off == 0)
+ val = ATOMnilptr(bi.type);
+ else if (off < bi.vhfree)
val = bi.vh->base + off;
else
val = NULL; /* bad offset */
@@ -1617,10 +1619,14 @@ BUNinplacemulti(BAT *b, const oid *posit
_ptr = b->theap->base + p * b->twidth;
switch (b->twidth) {
case 1:
- _d = (var_t) * (uint8_t *) _ptr + GDK_VAROFFSET;
+ _d = (var_t) * (uint8_t *) _ptr;
+ if (_d != 0)
+ _d += GDK_VAROFFSET;
break;
case 2:
- _d = (var_t) * (uint16_t *) _ptr +
GDK_VAROFFSET;
+ _d = (var_t) * (uint16_t *) _ptr;
+ if (_d != 0)
+ _d += GDK_VAROFFSET;
break;
case 4:
_d = (var_t) * (uint32_t *) _ptr;
@@ -1640,7 +1646,7 @@ BUNinplacemulti(BAT *b, const oid *posit
goto bailout;
}
if (b->twidth < SIZEOF_VAR_T &&
- (b->twidth <= 2 ? _d - GDK_VAROFFSET : _d) >=
((size_t) 1 << (8 << b->tshift))) {
+ (b->twidth <= 2 && _d != 0 ? _d - GDK_VAROFFSET :
_d) >= ((size_t) 1 << (8 << b->tshift))) {
/* doesn't fit in current heap, upgrade it */
if (GDKupgradevarheap(b, _d, 0, bi.count) !=
GDK_SUCCEED) {
MT_lock_unset(&b->theaplock);
@@ -1661,10 +1667,14 @@ BUNinplacemulti(BAT *b, const oid *posit
_ptr = b->theap->base + p * b->twidth;
switch (b->twidth) {
case 1:
- * (uint8_t *) _ptr = (uint8_t) (_d -
GDK_VAROFFSET);
+ if (_d != 0)
+ _d -= GDK_VAROFFSET;
+ * (uint8_t *) _ptr = (uint8_t) _d;
break;
case 2:
- * (uint16_t *) _ptr = (uint16_t) (_d -
GDK_VAROFFSET);
+ if (_d != 0)
+ _d -= GDK_VAROFFSET;
+ * (uint16_t *) _ptr = (uint16_t) _d;
break;
case 4:
* (uint32_t *) _ptr = (uint32_t) _d;
diff --git a/gdk/gdk_batop.c b/gdk/gdk_batop.c
--- a/gdk/gdk_batop.c
+++ b/gdk/gdk_batop.c
@@ -52,41 +52,51 @@ unshare_varsized_heap(BAT *b)
Heap *oh = b->tvheap;
b->tvheap = h;
var_t o;
+ const void *nil = ATOMnilptr(b->ttype);
+ const void *v;
switch (b->twidth) {
case 1:
for (BUN i = 0; i < b->batCount; i++) {
- o = (var_t) ((uint8_t *)
b->theap->base)[i] + GDK_VAROFFSET;
- if (atomput(b, &o, oh->base + o) ==
(var_t) -1)
+ o = (var_t) ((uint8_t *)
b->theap->base)[i];
+ v = o == 0 ? nil : oh->base + o +
GDK_VAROFFSET;
+ if (atomput(b, &o, v) == (var_t) -1)
goto bailout;
- ((uint8_t *) b->theap->base)[i] =
(uint8_t) (o - GDK_VAROFFSET);
+ if (o != 0)
+ o -= GDK_VAROFFSET;
+ ((uint8_t *) b->theap->base)[i] =
(uint8_t) o;
}
break;
case 2:
for (BUN i = 0; i < b->batCount; i++) {
- o = (var_t) ((uint16_t *)
b->theap->base)[i] + GDK_VAROFFSET;
- if (atomput(b, &o, oh->base + o) ==
(var_t) -1)
+ o = (var_t) ((uint16_t *)
b->theap->base)[i];
+ v = o == 0 ? nil : oh->base + o +
GDK_VAROFFSET;
+ if (atomput(b, &o, v) == (var_t) -1)
goto bailout;
- ((uint16_t *) b->theap->base)[i] =
(uint16_t) (o - GDK_VAROFFSET);
+ if (o != 0)
+ o -= GDK_VAROFFSET;
+ ((uint16_t *) b->theap->base)[i] =
(uint16_t) o;
}
break;
-#if SIZEOF_VAR_T == 8
case 4:
for (BUN i = 0; i < b->batCount; i++) {
o = (var_t) ((uint32_t *)
b->theap->base)[i];
- if (atomput(b, &o, oh->base + o) ==
(var_t) -1)
+ v = o == 0 ? nil : oh->base + o;
+ if (atomput(b, &o, v) == (var_t) -1)
goto bailout;
((uint32_t *) b->theap->base)[i] =
(uint32_t) o;
}
break;
-#endif
- case SIZEOF_VAR_T:
+#if SIZEOF_VAR_T == 8
+ case 8:
for (BUN i = 0; i < b->batCount; i++) {
- o = ((var_t *) b->theap->base)[i];
- if (atomput(b, &o, oh->base + o) ==
(var_t) -1)
+ o = (var_t) ((uint64_t *)
b->theap->base)[i];
+ v = o == 0 ? nil : oh->base + o;
+ if (atomput(b, &o, v) == (var_t) -1)
goto bailout;
- ((var_t *) b->theap->base)[i] = o;
+ ((uint64_t *) b->theap->base)[i] =
(uint64_t) o;
}
break;
+#endif
default:
MT_UNREACHABLE();
}
@@ -227,7 +237,7 @@ insert_string_bat(BAT *b, BATiter *ni, s
}
/* if toff has the initial value of ~0, we insert strings
* individually, otherwise we only copy (insert) offsets */
- if (toff == ~(size_t) 0)
+ if (toff == ~(size_t) 0 || b->tvheap->free == GDK_VAROFFSET)
v = GDK_VAROFFSET;
else
v = b->tvheap->free - 1;
@@ -270,10 +280,14 @@ insert_string_bat(BAT *b, BATiter *ni, s
p = canditer_next(ci) - ni->b->hseqbase;
switch (ni->width) {
case 1:
- v = (var_t) tbp[p] + GDK_VAROFFSET;
+ v = (var_t) tbp[p];
+ if (v != 0)
+ v += GDK_VAROFFSET;
break;
case 2:
_______________________________________________
checkin-list mailing list -- [email protected]
To unsubscribe send an email to [email protected]