Changeset: 3c2bf1acbc06 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=3c2bf1acbc06
Modified Files:
gdk/gdk_batop.c
sql/storage/bat/bat_storage.c
Branch: default
Log Message:
Merge with Nov2019 branch.
diffs (266 lines):
diff --git a/gdk/gdk_batop.c b/gdk/gdk_batop.c
--- a/gdk/gdk_batop.c
+++ b/gdk/gdk_batop.c
@@ -839,27 +839,247 @@ BATdel(BAT *b, BAT *d)
gdk_return
BATreplace(BAT *b, BAT *p, BAT *n, bool force)
{
- BUN r, s;
- BATiter nvi = bat_iterator(n);
- oid hseqend;
-
- if (b == NULL || b->ttype == TYPE_void ||
- p == NULL || n == NULL || BATcount(n) == 0) {
+ if (b == NULL || b->ttype == TYPE_void || p == NULL || n == NULL) {
+ return GDK_SUCCEED;
+ }
+ if (BATcount(p) != BATcount(n)) {
+ GDKerror("BATreplace: update BATs not the same size\n");
+ return GDK_FAIL;
+ }
+ if (ATOMtype(p->ttype) != TYPE_oid) {
+ GDKerror("BATreplace: positions BAT not type OID\n");
+ return GDK_FAIL;
+ }
+ if (BATcount(n) == 0) {
return GDK_SUCCEED;
}
- hseqend = b->hseqbase + BATcount(b);
- BATloop(n, r, s) {
- oid updid = BUNtoid(p, r);
- const void *val = BUNtail(nvi, r);
+ if (!force && (b->batRestricted != BAT_WRITE || b->batSharecnt > 0)) {
+ GDKerror("BATreplace: access denied to %s, aborting.\n",
+ BATgetId(b));
+ return GDK_FAIL;
+ }
+
+ HASHdestroy(b);
+ OIDXdestroy(b);
+ IMPSdestroy(b);
+
+ b->tsorted = b->trevsorted = false;
+ b->tnosorted = b->tnorevsorted = 0;
+ b->tkey = false;
+ b->tnokey[0] = b->tnokey[1] = 0;
+
+ const PROPrec *maxprop = BATgetprop(b, GDK_MAX_VALUE);
+ const PROPrec *minprop = BATgetprop(b, GDK_MIN_VALUE);
+ int (*atomcmp)(const void *, const void *) = ATOMcompare(b->ttype);
+ const void *nil = ATOMnilptr(b->ttype);
+ oid hseqend = b->hseqbase + BATcount(b);
+ BATiter bi = bat_iterator(b);
+ BATiter ni = bat_iterator(n);
+ bool anynil = false;
+
+ b->theap.dirty = true;
+ if (b->tvarsized) {
+ b->tvheap->dirty = true;
+ for (BUN i = 0, j = BATcount(p); i < j; i++) {
+ oid updid = BUNtoid(p, i);
+
+ if (updid < b->hseqbase || updid >= hseqend) {
+ GDKerror("BATreplace: id out of range\n");
+ return GDK_FAIL;
+ }
+ updid -= b->hseqbase;
+ if (!force && updid < b->batInserted) {
+ GDKerror("BATreplace: updating committed
value\n");
+ return GDK_FAIL;
+ }
+
+ const void *old = BUNtvar(bi, updid);
+ const void *new = BUNtvar(ni, i);
+ bool isnil = atomcmp(new, nil) == 0;
+ anynil |= isnil;
+ if (b->tnil &&
+ !anynil &&
+ atomcmp(old, nil) == 0) {
+ /* if old value is nil and no new
+ * value is, we're not sure anymore
+ * about the nil property, so we must
+ * clear it */
+ b->tnil = false;
+ }
+ b->tnonil &= !isnil;
+ b->tnil |= isnil;
+ if (maxprop) {
+ if (!isnil &&
+ atomcmp(VALptr(&maxprop->v), new) < 0) {
+ /* new value is larger than
+ * previous largest */
+ BATsetprop(b, GDK_MAX_VALUE, b->ttype,
new);
+ maxprop = BATgetprop(b, GDK_MAX_VALUE);
+ } else if (atomcmp(VALptr(&maxprop->v), old) ==
0 &&
+ atomcmp(new, old) != 0) {
+ /* old value is equal to
+ * largest and new value is
+ * smaller, so we don't know
+ * anymore which is the
+ * largest */
+ BATrmprop(b, GDK_MAX_VALUE);
+ maxprop = NULL;
+ }
+ }
+ if (minprop) {
+ if (!isnil &&
+ atomcmp(VALptr(&minprop->v), new) > 0) {
+ /* new value is smaller than
+ * previous smallest */
+ BATsetprop(b, GDK_MIN_VALUE, b->ttype,
new);
+ minprop = BATgetprop(b, GDK_MIN_VALUE);
+ } else if (atomcmp(VALptr(&minprop->v), old) ==
0 &&
+ atomcmp(new, old) != 0) {
+ /* old value is equal to
+ * smallest and new value is
+ * larger, so we don't know
+ * anymore which is the
+ * smallest */
+ BATrmprop(b, GDK_MIN_VALUE);
+ minprop = NULL;
+ }
+ }
- if (updid < b->hseqbase || updid >= hseqend) {
- GDKerror("BATreplace: id out of range\n");
- return GDK_FAIL;
+ var_t d;
+ switch (b->twidth) {
+ case 1:
+ d = (var_t) ((uint8_t *) b->theap.base)[updid]
+ GDK_VAROFFSET;
+ break;
+ case 2:
+ d = (var_t) ((uint16_t *) b->theap.base)[updid]
+ GDK_VAROFFSET;
+ break;
+ case 4:
+ d = (var_t) ((uint32_t *) b->theap.base)[updid];
+ break;
+#if SIZEOF_VAR_T == 8
+ case 8:
+ d = (var_t) ((uint64_t *) b->theap.base)[updid];
+ break;
+#endif
+ }
+ ATOMreplaceVAR(b->ttype, b->tvheap, &d, new);
+ if (b->twidth < SIZEOF_VAR_T &&
+ (b->twidth <= 2 ? d - GDK_VAROFFSET : d) >=
((size_t) 1 << (8 * b->twidth))) {
+ /* doesn't fit in current heap, upgrade it */
+ if (GDKupgradevarheap(b, d, false,
b->batRestricted == BAT_READ) != GDK_SUCCEED)
+ goto bunins_failed;
+ }
+ switch (b->twidth) {
+ case 1:
+ ((uint8_t *) b->theap.base)[updid] = (uint8_t)
(d - GDK_VAROFFSET);
+ break;
+ case 2:
+ ((uint16_t *) b->theap.base)[updid] =
(uint16_t) (d - GDK_VAROFFSET);
+ break;
+ case 4:
+ ((uint32_t *) b->theap.base)[updid] =
(uint32_t) d;
+ break;
+#if SIZEOF_VAR_T == 8
+ case 8:
+ ((uint64_t *) b->theap.base)[updid] =
(uint64_t) d;
+ break;
+#endif
+ }
}
- if (BUNinplace(b, updid - b->hseqbase, val, force) !=
GDK_SUCCEED)
- return GDK_FAIL;
+ } else {
+ for (BUN i = 0, j = BATcount(p); i < j; i++) {
+ oid updid = BUNtoid(p, i);
+
+ if (updid < b->hseqbase || updid >= hseqend) {
+ GDKerror("BATreplace: id out of range\n");
+ return GDK_FAIL;
+ }
+ updid -= b->hseqbase;
+ if (!force && updid < b->batInserted) {
+ GDKerror("BATreplace: updating committed
value\n");
+ return GDK_FAIL;
+ }
+
+ const void *old = BUNtloc(bi, updid);
+ const void *new = BUNtail(ni, i);
+ bool isnil = atomcmp(new, nil) == 0;
+ anynil |= isnil;
+ if (b->tnil &&
+ !anynil &&
+ atomcmp(old, nil) == 0) {
+ /* if old value is nil and no new
+ * value is, we're not sure anymore
+ * about the nil property, so we must
+ * clear it */
+ b->tnil = false;
+ }
+ b->tnonil &= !isnil;
+ b->tnil |= isnil;
+ if (maxprop) {
+ if (!isnil &&
+ atomcmp(VALptr(&maxprop->v), new) < 0) {
+ /* new value is larger than
+ * previous largest */
+ BATsetprop(b, GDK_MAX_VALUE, b->ttype,
new);
+ maxprop = BATgetprop(b, GDK_MAX_VALUE);
+ } else if (atomcmp(VALptr(&maxprop->v), old) ==
0 &&
+ atomcmp(new, old) != 0) {
+ /* old value is equal to
+ * largest and new value is
+ * smaller, so we don't know
+ * anymore which is the
+ * largest */
+ BATrmprop(b, GDK_MAX_VALUE);
+ maxprop = NULL;
+ }
+ }
+ if (minprop) {
+ if (!isnil &&
+ atomcmp(VALptr(&minprop->v), new) > 0) {
+ /* new value is smaller than
+ * previous smallest */
+ BATsetprop(b, GDK_MIN_VALUE, b->ttype,
new);
+ minprop = BATgetprop(b, GDK_MIN_VALUE);
+ } else if (atomcmp(VALptr(&minprop->v), old) ==
0 &&
+ atomcmp(new, old) != 0) {
+ /* old value is equal to
+ * smallest and new value is
+ * larger, so we don't know
+ * anymore which is the
+ * smallest */
+ BATrmprop(b, GDK_MIN_VALUE);
+ minprop = NULL;
+ }
+ }
+
+ switch (b->twidth) {
+ case 1:
+ ((bte *) b->theap.base)[updid] = * (bte *) new;
+ break;
+ case 2:
+ ((sht *) b->theap.base)[updid] = * (sht *) new;
+ break;
+ case 4:
+ ((int *) b->theap.base)[updid] = * (int *) new;
+ break;
+ case 8:
+ ((lng *) b->theap.base)[updid] = * (lng *) new;
+ break;
+#ifdef HAVE_HGE
+ case 16:
+ ((hge *) b->theap.base)[updid] = * (hge *) new;
+ break;
+#endif
+ default:
+ memcpy(BUNtloc(bi, updid), new,
ATOMsize(b->ttype));
+ break;
+ }
+ }
}
return GDK_SUCCEED;
+
+ bunins_failed:
+ return GDK_FAIL;
}
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list