Changeset: 972267dfe5c1 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=972267dfe5c1
Modified Files:
        clients/Tests/exports.stable.out
        gdk/ChangeLog
        gdk/gdk.h
        gdk/gdk_bat.c
Branch: default
Log Message:

Implemented function BUNappendmulti.


diffs (165 lines):

diff --git a/clients/Tests/exports.stable.out b/clients/Tests/exports.stable.out
--- a/clients/Tests/exports.stable.out
+++ b/clients/Tests/exports.stable.out
@@ -221,6 +221,7 @@ gdk_return BBPsync(int cnt, bat *restric
 int BBPunfix(bat b);
 void BBPunlock(void);
 gdk_return BUNappend(BAT *b, const void *right, bool force) 
__attribute__((__warn_unused_result__));
+gdk_return BUNappendmulti(BAT *b, const void *values, BUN count, bool force) 
__attribute__((__warn_unused_result__));
 gdk_return BUNdelete(BAT *b, oid o) __attribute__((__warn_unused_result__));
 BUN BUNfnd(BAT *b, const void *right);
 gdk_return BUNinplace(BAT *b, BUN p, const void *right, bool force) 
__attribute__((__warn_unused_result__));
diff --git a/gdk/ChangeLog b/gdk/ChangeLog
--- a/gdk/ChangeLog
+++ b/gdk/ChangeLog
@@ -1,6 +1,10 @@
 # ChangeLog file for GDK
 # This file is updated with Maddlog
 
+* Mon Mar 15 2021 Sjoerd Mullender <sjo...@acm.org>
+- Implemented a function BUNappendmulti which appends an array of values
+  to a BAT.  It is a generalization of the function BUNappend.
+
 * Thu Feb 25 2021 Sjoerd Mullender <sjo...@acm.org>
 - Changed the interface of the atom read function.  It now requires an
   extra pointer to a size_t value that gives the current size of the
diff --git a/gdk/gdk.h b/gdk/gdk.h
--- a/gdk/gdk.h
+++ b/gdk/gdk.h
@@ -952,6 +952,8 @@ gdk_export gdk_return GDKupgradevarheap(
        __attribute__((__warn_unused_result__));
 gdk_export gdk_return BUNappend(BAT *b, const void *right, bool force)
        __attribute__((__warn_unused_result__));
+gdk_export gdk_return BUNappendmulti(BAT *b, const void *values, BUN count, 
bool force)
+       __attribute__((__warn_unused_result__));
 gdk_export gdk_return BATappend(BAT *b, BAT *n, BAT *s, bool force)
        __attribute__((__warn_unused_result__));
 
diff --git a/gdk/gdk_bat.c b/gdk/gdk_bat.c
--- a/gdk/gdk_bat.c
+++ b/gdk/gdk_bat.c
@@ -1122,38 +1122,42 @@ setcolprops(BAT *b, const void *x)
        }
 }
 
-/*
- * @+ BUNappend
- * The BUNappend function can be used to add a single value to void
- * and oid headed bats. The new head value will be a unique number,
- * (max(bat)+1).
- */
+/* Append an array of values of length count to the bat.  For
+ * fixed-sized values, `values' is an array of values, for
+ * variable-sized values, `values' is an array of pointers to values. */
 gdk_return
-BUNappend(BAT *b, const void *t, bool force)
+BUNappendmulti(BAT *b, const void *values, BUN count, bool force)
 {
        BUN p;
-       size_t tsize = 0;
 
        BATcheck(b, GDK_FAIL);
 
        assert(!VIEWtparent(b));
 
+       if (count == 0)
+               return GDK_SUCCEED;
+
        p = BUNlast(b);         /* insert at end */
-       if (p == BUN_MAX || b->batCount == BUN_MAX) {
+       if (p == BUN_MAX || BATcount(b) + count >= BUN_MAX) {
                GDKerror("bat too large\n");
                return GDK_FAIL;
        }
 
        ALIGNapp(b, force, GDK_FAIL);
        b->batDirtydesc = true;
-       if (b->thash && b->tvheap)
-               tsize = b->tvheap->size;
 
        if (b->ttype == TYPE_void && BATtdense(b)) {
-               if (b->batCount == 0) {
-                       b->tseqbase = * (const oid *) t;
-               } else if (is_oid_nil(* (oid *) t) ||
-                          b->tseqbase + b->batCount != *(const oid *) t) {
+               const oid *ovals = values;
+               bool dense = b->batCount == 0 || b->tseqbase + 1 == ovals[0];
+               for (BUN i = 1; dense && i < count; i++) {
+                       dense = ovals[i - 1] + 1 == ovals[i];
+               }
+               if (dense) {
+                       if (b->batCount == 0)
+                               b->tseqbase = ovals[0];
+                       BATsetcount(b, BATcount(b) + count);
+                       return GDK_SUCCEED;
+               } else {
                        /* we need to materialize b; allocate enough capacity */
                        b->batCapacity = BATcount(b) + 1;
                        if (BATmaterialize(b) != GDK_SUCCEED)
@@ -1165,21 +1169,31 @@ BUNappend(BAT *b, const void *t, bool fo
                return GDK_FAIL;
        }
 
-       setcolprops(b, t);
-
-       if (b->ttype != TYPE_void) {
-               if (bunfastapp(b, t) != GDK_SUCCEED)
-                       return GDK_FAIL;
-               b->theap->dirty = true;
-       } else {
-               BATsetcount(b, b->batCount + 1);
+       if (BATcount(b) + count > BATcapacity(b)) {
+               gdk_return rc = BATextend(b, BATgrows(b));
+               if (rc != GDK_SUCCEED)
+                       return rc;
        }
 
+       BATrmprop(b, GDK_NUNIQUE);
+       BATrmprop(b, GDK_UNIQUE_ESTIMATE);
+       for (BUN i = 0; i < count; i++) {
+               void *t = b->ttype && b->tvarsized ? ((void **) values)[i] :
+                       (void *) ((char *) values + i * Tsize(b));
+               setcolprops(b, t);
+               gdk_return rc = bunfastapp_nocheck(b, b->batCount, t, Tsize(b));
+               if (rc != GDK_SUCCEED)
+                       return rc;
+               if (b->thash) {
+                       HASHins(b, p, t);
+               }
+       }
+
+       if (b->thash)
+               BATsetprop(b, GDK_NUNIQUE, TYPE_oid, &(oid){b->thash->nunique});
 
        IMPSdestroy(b); /* no support for inserts in imprints yet */
        OIDXdestroy(b);
-       BATrmprop(b, GDK_NUNIQUE);
-       BATrmprop(b, GDK_UNIQUE_ESTIMATE);
 #if 0          /* enable if we have more properties than just min/max */
        PROPrec *prop;
        do {
@@ -1192,17 +1206,16 @@ BUNappend(BAT *b, const void *t, bool fo
                        }
        } while (prop);
 #endif
-       if (b->thash) {
-               HASHins(b, p, t);
-               if (b->thash)
-                       BATsetprop(b, GDK_NUNIQUE,
-                                  TYPE_oid, &(oid){b->thash->nunique});
-               if (tsize && tsize != b->tvheap->size)
-                       HEAPwarm(b->tvheap);
-       }
        return GDK_SUCCEED;
 }
 
+/* Append a single value to the bat. */
+gdk_return
+BUNappend(BAT *b, const void *t, bool force)
+{
+       return BUNappendmulti(b, b->ttype && b->tvarsized ? (const void *) &t : 
(const void *) t, 1, force);
+}
+
 gdk_return
 BUNdelete(BAT *b, oid o)
 {
_______________________________________________
checkin-list mailing list
checkin-list@monetdb.org
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to