Changeset: e1b64497d900 for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=e1b64497d900
Modified Files:
        sql/backends/monet5/UDF/udf.c
Branch: Apr2012
Log Message:

UDFBATfuse: move type-specific implementation of core algorithm into separate 
function


diffs (255 lines):

diff --git a/sql/backends/monet5/UDF/udf.c b/sql/backends/monet5/UDF/udf.c
--- a/sql/backends/monet5/UDF/udf.c
+++ b/sql/backends/monet5/UDF/udf.c
@@ -146,7 +146,7 @@ UDFBATreverse_(BAT **ret, BAT *left)
        return MAL_SUCCEED;
 }
 
-/* MAL wrapper */           
+/* MAL wrapper */
 str
 UDFBATreverse(bat *ret, bat *bid)
 {
@@ -178,11 +178,12 @@ UDFBATreverse(bat *ret, bat *bid)
 
 /* scalar fuse */
 
-/* using C macro for convenient type-expansion */
+/* use C macro to conveniently define type-specific functions */
 #define UDFfuse_scalar_impl(in,uin,out,shift)                          \
 /* fuse two (shift-byte) in values into one (2*shift-byte) out value */        
\
 /* actual implementation */                                            \
-static str UDFfuse_##in##_##out##_ ( out *ret , in one , in two )      \
+static str                                                             \
+UDFfuse_##in##_##out##_ ( out *ret , in one , in two )                 \
 {                                                                      \
        /* assert calling sanity */                                     \
        assert(ret != NULL);                                            \
@@ -197,7 +198,8 @@ static str UDFfuse_##in##_##out##_ ( out
        return MAL_SUCCEED;                                             \
 }                                                                      \
 /* MAL wrapper */                                                      \
-str UDFfuse_##in##_##out ( out *ret , in *one , in *two )              \
+str                                                                    \
+UDFfuse_##in##_##out ( out *ret , in *one , in *two )                  \
 {                                                                      \
        /* assert calling sanity */                                     \
        assert(ret != NULL && one != NULL && two != NULL);              \
@@ -205,6 +207,7 @@ str UDFfuse_##in##_##out ( out *ret , in
        return UDFfuse_##in##_##out##_ ( ret, *one, *two );             \
 }
 
+/* call C macro to define type-specific functions */
 UDFfuse_scalar_impl(bte, unsigned char,  sht,  8)
 UDFfuse_scalar_impl(sht, unsigned short, int, 16)
 UDFfuse_scalar_impl(int, unsigned int,   lng, 32)
@@ -216,12 +219,56 @@ UDFfuse_scalar_impl(int, unsigned int,  
  * accessing value arrays directly.
  */
 
+/* type-specific core algorithm */
+/* use C macro to conveniently define type-specific functions */
+#define UDFBATfuse_impl(in,uin,out,shift)                              \
+static str                                                             \
+UDFBATfuse_##in##_##out ( BAT *bres, BAT *bone, BAT *btwo, BUN n,      \
+                            bit *two_tail_sorted_unsigned )            \
+{                                                                      \
+       in *one = NULL, *two = NULL;                                    \
+       out *res = NULL;                                                \
+       BUN i;                                                          \
+                                                                       \
+       /* assert calling sanity */                                     \
+       assert(bres != NULL && bone != NULL && btwo != NULL);           \
+       assert(BATcapacity(bres) >= n);                                 \
+       assert(BATcount(bone) >= n && BATcount(btwo) >= n);             \
+       assert(bone->ttype == TYPE_##in && btwo->ttype == TYPE_##in);   \
+       assert(bres->ttype == TYPE_##out);                              \
+                                                                       \
+       /* get direct access to the tail arrays */                      \
+       one = (in *) Tloc(bone, BUNfirst(bone));                        \
+       two = (in *) Tloc(btwo, BUNfirst(btwo));                        \
+       res = (out*) Tloc(bres, BUNfirst(bres));                        \
+       /* iterate over all values/tuples and do the work */            \
+       for (i = 0; i < n; i++)                                         \
+               if (one[i] == in##_nil || two[i] == in##_nil)           \
+                       /* NULL/nil in => NULL/nil out */               \
+                       res[i] = out##_nil;                             \
+               else                                                    \
+                       /* do the work; watch out for sign bits */      \
+                       res[i] = ((out) (uin) one[i] << shift) | (uin) two[i]; \
+                                                                       \
+       *two_tail_sorted_unsigned =                                     \
+               BATtordered(btwo)&1 && (two[0] >= 0 || two[n-1] < 0);   \
+                                                                       \
+       return MAL_SUCCEED;                                             \
+}
+
+/* call C macro to define type-specific functions */
+UDFBATfuse_impl(bte, unsigned char,  sht,  8)
+UDFBATfuse_impl(sht, unsigned short, int, 16)
+UDFBATfuse_impl(int, unsigned int,   lng, 32)
+
 /* actual implementation */
 static str
 UDFBATfuse_(BAT **ret, BAT *bone, BAT *btwo)
 {
        BAT *bres = NULL;
        bit two_tail_sorted_unsigned = FALSE;
+       BUN n;
+       str msg = NULL;
 
        /* assert calling sanity */
        assert(ret != NULL);
@@ -238,6 +285,7 @@ UDFBATfuse_(BAT **ret, BAT *bone, BAT *b
                throw(MAL, "batudf.fuse",
                      "heads of input BATs must be aligned");
        }
+       n = BATcount(bone);
 
        /* check tail types */
        if (bone->ttype != btwo->ttype) {
@@ -245,64 +293,41 @@ UDFBATfuse_(BAT **ret, BAT *bone, BAT *b
                      "tails of input BATs must be identical");
        }
 
+       /* allocate result BAT */
+       switch (bone->ttype) {
+       case TYPE_bte:
+               bres = BATnew(TYPE_void, TYPE_sht, n);
+               break;
+       case TYPE_sht:
+               bres = BATnew(TYPE_void, TYPE_int, n);
+               break;
+       case TYPE_int:
+               bres = BATnew(TYPE_void, TYPE_lng, n);
+               break;
+       default:
+               throw(MAL, "batudf.fuse",
+                     "tails of input BATs must be one of {bte, sht, int}");
+       }
+       if (bres == NULL)
+               throw(MAL, "batudf.fuse", MAL_MALLOC_FAIL);
+
        /* advice on sequential scan */
        BATaccessBegin(bone, USE_TAIL, MMAP_SEQUENTIAL);
        BATaccessBegin(btwo, USE_TAIL, MMAP_SEQUENTIAL);
 
-/* using C macro for convenient type-expansion */
-#define UDFBATfuse_TYPE(in,uin,out,shift)                              \
-do {   /* type-specific core algorithm */                              \
-       in *one = NULL, *two = NULL;                                    \
-       out *res = NULL;                                                \
-       BUN i, n = BATcount(bone);                                      \
-                                                                       \
-       /* allocate result BAT */                                       \
-       bres = BATnew(TYPE_void, TYPE_##out, n);                        \
-       if (bres == NULL) {                                             \
-               BBPreleaseref(bone->batCacheid);                        \
-               BBPreleaseref(btwo->batCacheid);                        \
-               throw(MAL, "batudf.fuse", MAL_MALLOC_FAIL);             \
-       }                                                               \
-                                                                       \
-       /* get direct access to the tail arrays */                      \
-       one = (in *) Tloc(bone, BUNfirst(bone));                        \
-       two = (in *) Tloc(btwo, BUNfirst(btwo));                        \
-       res = (out*) Tloc(bres, BUNfirst(bres));                        \
-                                                                       \
-       /* is tail of right/second BAT sorted,                          \
-        * also when cast to unsigned type,                             \
-        * i.e., are the values either all >= 0 or all < 0? */          \
-       two_tail_sorted_unsigned = BATtordered(btwo) & 1 &&             \
-               (two[0] >= 0 || two[n - 1] < 0);                        \
-                                                                       \
-       /* iterate over all values/tuples and do the work */            \
-       for (i = 0; i < n; i++)                                         \
-               if (one[i] == in##_nil || two[i] == in##_nil)           \
-                       /* NULL/nil in => NULL/nil out */               \
-                       res[i] = out##_nil;                             \
-               else                                                    \
-                       /* do the work; watch out for sign bits */      \
-                       res[i] = ((out) (uin) one[i] << shift) | (uin) two[i]; \
-                                                                       \
-       /* set number of tuples in result BAT */                        \
-       BATsetcount(bres, n);                                           \
-} while (0)
-
-       /* type expansion for core algorithm */
+       /* call type-specific core algorithm */
        switch (bone->ttype) {
        case TYPE_bte:
-               UDFBATfuse_TYPE(bte, unsigned char, sht, 8);
+               msg = UDFBATfuse_bte_sht ( bres, bone, btwo, n, 
&two_tail_sorted_unsigned );
                break;
-
        case TYPE_sht:
-               UDFBATfuse_TYPE(sht, unsigned short, int, 16);
+               msg = UDFBATfuse_sht_int ( bres, bone, btwo, n, 
&two_tail_sorted_unsigned );
                break;
-
        case TYPE_int:
-               UDFBATfuse_TYPE(int, unsigned int, lng, 32);
+               msg = UDFBATfuse_int_lng ( bres, bone, btwo, n, 
&two_tail_sorted_unsigned );
                break;
-
        default:
+               BBPreleaseref(bres->batCacheid);
                throw(MAL, "batudf.fuse",
                      "tails of input BATs must be one of {bte, sht, int}");
        }
@@ -310,29 +335,36 @@ do {      /* type-specific core algorithm */      
        BATaccessEnd(bone, USE_TAIL, MMAP_SEQUENTIAL);
        BATaccessEnd(btwo, USE_TAIL, MMAP_SEQUENTIAL);
 
-       /* set result properties */
-       bres->hdense = TRUE;              /* result head is dense */
-       BATseqbase(bres, bone->hseqbase); /* result head has same seqbase as 
input */
-       bres->hsorted = GDK_SORTED;       /* result head is sorted */
-       BATkey(bres, TRUE);               /* result head is key (unique) */
+       if (msg != MAL_SUCCEED) {
+               BBPreleaseref(bres->batCacheid);
+       } else {
+               /* set number of tuples in result BAT */
+               BATsetcount(bres, n);
 
-       /* Result tail is sorted, if the left/first input tail is
-        * sorted and key (unique), or if the left/first input tail is
-        * sorted and the second/right input tail is sorted and the
-        * second/right tail values are either all >= 0 or all < 0;
-        * otherwise, we cannot tell.
-        */
-       if (BATtordered(bone) & 1
-           && (BATtkey(bone) || two_tail_sorted_unsigned))
-               bres->tsorted = GDK_SORTED;
-       else
-               bres->tsorted = 0;
-       /* result tail is key (unique), iff both input tails are */
-       BATkey(BATmirror(bres), BATtkey(bone) || BATtkey(btwo));
+               /* set result properties */
+               bres->hdense = TRUE;              /* result head is dense */
+               BATseqbase(bres, bone->hseqbase); /* result head has same 
seqbase as input */
+               bres->hsorted = GDK_SORTED;       /* result head is sorted */
+               BATkey(bres, TRUE);               /* result head is key 
(unique) */
 
-       *ret = bres;
+               /* Result tail is sorted, if the left/first input tail is
+                * sorted and key (unique), or if the left/first input tail is
+                * sorted and the second/right input tail is sorted and the
+                * second/right tail values are either all >= 0 or all < 0;
+                * otherwise, we cannot tell.
+                */
+               if (BATtordered(bone) & 1
+                   && (BATtkey(bone) || two_tail_sorted_unsigned))
+                       bres->tsorted = GDK_SORTED;
+               else
+                       bres->tsorted = 0;
+               /* result tail is key (unique), iff both input tails are */
+               BATkey(BATmirror(bres), BATtkey(bone) || BATtkey(btwo));
 
-       return MAL_SUCCEED;
+               *ret = bres;
+       }
+
+       return msg;
 }
 
 /* MAL wrapper */
_______________________________________________
Checkin-list mailing list
[email protected]
http://mail.monetdb.org/mailman/listinfo/checkin-list

Reply via email to