Changeset: 94bd4ac58a90 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/94bd4ac58a90
Modified Files:
        gdk/gdk_batop.c
Branch: Mar2025
Log Message:

Added some special casing in case multiple identical values are updated.
If multiple identical values (same pointer into source vheap) are
updated in a row, we recognize that and will reuse the offset from the
first in the row without going through the whole process we normally
use to insert a value.
Also, we reduce the number of comparisons when checking whether the
new value is now the new smallest/largest value: if it was the same
value as the previous, we already know the answer.  And when we've
updated the smallest/largest value, we know a subsequent
to-be-replaced value cannot be the smallest/largest, so we can skip
that comparison as well.


diffs (83 lines):

diff --git a/gdk/gdk_batop.c b/gdk/gdk_batop.c
--- a/gdk/gdk_batop.c
+++ b/gdk/gdk_batop.c
@@ -1323,6 +1323,11 @@ BATappend_or_update(BAT *b, BAT *p, cons
        bool locked = false;
 
        if (b->tvheap) {
+               const void *prevnew = NULL;
+               var_t prevoff = 0;
+               const bool hasdel = BATatoms[b->ttype].atomDel != NULL;
+               bool minupdated = false;
+               bool maxupdated = false;
                for (BUN i = 0; i < ni.count; i++) {
                        oid updid;
                        if (positions) {
@@ -1399,13 +1404,22 @@ BATappend_or_update(BAT *b, BAT *p, cons
                        b->tnil |= isnil;
                        MT_lock_unset(&b->theaplock);
                        if (bi.maxpos != BUN_NONE) {
+                               /* if new value is the same as the
+                                * previous new value, we've already
+                                * dealt with it; if we've already
+                                * updated the maxpos, it cannot be the
+                                * same as the old value, so we can skip
+                                * that check */
                                if (!isnil &&
+                                   (prevnew == NULL || prevnew != new) &&
                                    atomcmp(BUNtvar(bi, bi.maxpos), new) < 0) {
                                        /* new value is larger than
                                         * previous largest */
                                        bi.maxpos = updid;
+                                       maxupdated = true;
                                } else if (old == NULL ||
-                                          (atomcmp(BUNtvar(bi, bi.maxpos), 
old) == 0 &&
+                                          (!maxupdated &&
+                                           atomcmp(BUNtvar(bi, bi.maxpos), 
old) == 0 &&
                                            atomcmp(new, old) != 0)) {
                                        /* old value is equal to
                                         * largest and new value is
@@ -1417,12 +1431,15 @@ BATappend_or_update(BAT *b, BAT *p, cons
                        }
                        if (bi.minpos != BUN_NONE) {
                                if (!isnil &&
+                                   (prevnew == NULL || prevnew != new) &&
                                    atomcmp(BUNtvar(bi, bi.minpos), new) > 0) {
                                        /* new value is smaller than
                                         * previous smallest */
                                        bi.minpos = updid;
+                                       minupdated = true;
                                } else if (old == NULL ||
-                                          (atomcmp(BUNtvar(bi, bi.minpos), 
old) == 0 &&
+                                          (!minupdated &&
+                                           atomcmp(BUNtvar(bi, bi.minpos), 
old) == 0 &&
                                            atomcmp(new, old) != 0)) {
                                        /* old value is equal to
                                         * smallest and new value is
@@ -1463,7 +1480,16 @@ BATappend_or_update(BAT *b, BAT *p, cons
                                MT_UNREACHABLE();
                        }
                        MT_lock_set(&b->theaplock);
-                       gdk_return rc = ATOMreplaceVAR(b, &d, new);
+                       gdk_return rc = GDK_SUCCEED;
+                       bool skip = false;
+                       if (new == prevnew && !hasdel) {
+                               d = prevoff;
+                               skip = true;
+                       } else {
+                               rc = ATOMreplaceVAR(b, &d, new);
+                               prevnew = new;
+                               prevoff = d;
+                       }
                        MT_lock_unset(&b->theaplock);
                        if (rc != GDK_SUCCEED) {
                                goto bailout;
@@ -1478,7 +1504,7 @@ BATappend_or_update(BAT *b, BAT *p, cons
                        /* in case ATOMreplaceVAR and/or
                         * GDKupgradevarheap replaces a heap, we need to
                         * reinitialize the iterator */
-                       {
+                       if (!skip) {
                                /* save and restore minpos/maxpos */
                                BUN minpos = bi.minpos;
                                BUN maxpos = bi.maxpos;
_______________________________________________
checkin-list mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to