Update of /cvsroot/monetdb/pathfinder/runtime
In directory sc8-pr-cvs16.sourceforge.net:/tmp/cvs-serv18184/runtime

Modified Files:
      Tag: xquery-decomposition
        Makefile.ag ll_upwards.mx pf_support.mx xrpc_client.mx 
        xrpc_server.mx 
Added Files:
      Tag: xquery-decomposition
        xrpc_projection.mx 
Log Message:
check in unfinished code just in case...

- added a new built-in function pf:projected-put, which project a
  document and serialize it on desk
- done: projection function
- todo: serialize projected document



Index: pf_support.mx
===================================================================
RCS file: /cvsroot/monetdb/pathfinder/runtime/pf_support.mx,v
retrieving revision 1.277.2.1
retrieving revision 1.277.2.2
diff -u -d -r1.277.2.1 -r1.277.2.2
--- pf_support.mx       18 Feb 2008 16:21:40 -0000      1.277.2.1
+++ pf_support.mx       20 Feb 2008 22:45:07 -0000      1.277.2.2
@@ -82,7 +82,18 @@
                             void = xquery_print_result_file;
  "C interface to Workset result print routine, but print to a file"
 
-
[EMAIL PROTECTED] XML projection function (xrpc_projection.mx)
[EMAIL PROTECTED]
+.COMMAND projected_put(str options, str file,
+                      BAT[void,oid] used_item, 
+                      BAT[void,int] used_kind, 
+                      BAT[void,oid] returned_item,
+                      BAT[void,int] returned_kind,
+                      BAT[void,bat] ws,
+                      BAT[void,lng] int_values, BAT[void,dbl] dbl_values,
+                      BAT[void,dbl] dec_values, BAT[void,str] str_values) :
+                            void = CMDprojected_put;
+ "C interface to project a document and print to a file"
 
 @- Multi Join
 @m
@@ -719,6 +730,46 @@
                    const str_values);
 }
 
+PROC fn_projected_put(
+            str options, BAT[void,str] uri,
+            BAT[void,oid] used_item, BAT[void,int] used_kind,
+            BAT[void,oid] returned_item, BAT[void,int] returned_kind,
+            BAT[oid,bat] ws,
+            BAT[void,lng] int_values, BAT[void,dbl] dbl_values,
+            BAT[void,dbl] dec_values, BAT[void,str] str_values) : void
+{
+    var protocol := [search](uri, "://");
+    var sel := protocol.uselect(0,int_nil).hmark([EMAIL 
PROTECTED]).leftfetchjoin(uri);
+    var isfile := [or]([startsWith](sel, "file://"), [startsWith](sel, 
"FILE://"));
+    var filepath := protocol.uselect(-1).hmark([EMAIL 
PROTECTED]).leftfetchjoin(uri).access(BAT_WRITE);
+
+    isfile := isfile.uselect(true).hmark([EMAIL PROTECTED]).leftfetchjoin(sel);
+    sel := isfile.copy().access(BAT_WRITE).append(filepath).access(BAT_READ);
+    filepath.append([string](isfile,7));
+
+    if (count(sel) != count(uri)) { # we only support file url's for the moment
+       var nonfileurl := tdiff(uri, sel);
+       ERROR("fn_put: URI '%s' not recognized (only file URLs are supported; 
%d such errors).", wrong.fetch(0), count(nonfileurl));
+    }
+    var absolute := [or](filepath.[startsWith]("/"), 
filepath.[startsWith]("\\")).uselect(true).mirror().leftfetchjoin(sel);
+    if (count(absolute) > 0) {
+       ERROR("fn_put: file URI '%s' must be a relative path (%d such 
errors).", absolute.fetch(0), count(absolute));
+    }
+    var backwards := 
filepath.[search]("..").uselect(0,int_nil).mirror().leftfetchjoin(sel);
+    if (count(backwards) > 0) {
+       ERROR("fn_put: file URI '%s' must is not allowed to contain '..' (%d 
such errors).", backwards.fetch(0), count(backwards));
+    }
+
+    if(search(options, "xml-noroot") = -1) {
+        options := "xml-noroot-" + options;
+    }
+
+    [projected_put](const options, sel, const used_item, const used_kind,
+            const returned_item, const returned_kind,
+            const ws, const int_values, const dbl_values, const
+            dec_values, const str_values);
+}
+
 # print whitespaces (used for indenting)
 PROC pws (int shift) : void
 {
@@ -4985,6 +5036,14 @@
 #include <monet_interpreter.h>
 #include <monettime.h>
 
+/* for ll_upwards and xrpc_projection */
+#define PF_SIBLING_PROBES 64
+
+/* for ll_upwards and xrpc_projection */
+pf_support_export oid
+speculate_skip(oid pre, oid dst, oid skip, int budget, unsigned int* pre_size, 
unsigned char* pre_level);
+
+
 #endif
 @c
 

Index: xrpc_client.mx
===================================================================
RCS file: /cvsroot/monetdb/pathfinder/runtime/xrpc_client.mx,v
retrieving revision 1.41.2.1
retrieving revision 1.41.2.2
diff -u -d -r1.41.2.1 -r1.41.2.2
--- xrpc_client.mx      16 Feb 2008 01:02:21 -0000      1.41.2.1
+++ xrpc_client.mx      20 Feb 2008 22:45:09 -0000      1.41.2.2
@@ -487,6 +487,7 @@
 #include "serialize.h"
 #include "xrpc_common.h"
 #include "xrpc_client.h"
+#include "xrpc_projection.h"
 
 #define errCheck(iterc, argc, ws,                                      \
             fvid, fiter, fitem, fkind,                                 \
@@ -945,8 +946,92 @@
     lng time_xrpcClnt2Serv = 0;
     size_t bytes_sent = 0;
 
+    /* temporary code */
+    BAT *size_bat = NULL, *level_bat = NULL, *used_bat = NULL, *returned_bat = 
NULL;
+    BAT *res_bat = NULL, *res_pre = NULL, *res_size = NULL;
+    int size;
+    char level;
+    oid pre;
+    /* end temporary code */
+
     errCheck(iterc, argc, ws, fun_vid, fun_iter, fun_item, fun_kind,
             int_values, dbl_values, dec_values, str_values);
+    
+    /* temporary code */
+    /*     col           -2
+     *      |
+     *     doc           -1
+     *      |
+     *      a             0
+     *     /  \
+     *    b     f         1
+     *    |    / \
+     *    c   g   h       2
+     *   / \     / \
+     *  d   e   i   j     3
+     */
+    size_bat = BATnew(TYPE_void, TYPE_int, 12);
+    level_bat = BATnew(TYPE_void, TYPE_chr, 12);
+    used_bat = BATnew(TYPE_void, TYPE_oid, 4);
+    returned_bat = BATnew(TYPE_void, TYPE_oid, 1);
+    BATseqbase(size_bat, 0);
+    BATseqbase(level_bat, 0);
+    BATseqbase(used_bat, 0);
+    BATseqbase(returned_bat, 0);
+
+    size = 11; BUNappend(size_bat, (ptr)&size, TRUE);
+    size = 10; BUNappend(size_bat, (ptr)&size, TRUE);
+    size =  9; BUNappend(size_bat, (ptr)&size, TRUE);
+    size =  3; BUNappend(size_bat, (ptr)&size, TRUE);
+    size =  2; BUNappend(size_bat, (ptr)&size, TRUE);
+    size =  0; BUNappend(size_bat, (ptr)&size, TRUE);
+    size =  0; BUNappend(size_bat, (ptr)&size, TRUE);
+    size =  4; BUNappend(size_bat, (ptr)&size, TRUE);
+    size =  0; BUNappend(size_bat, (ptr)&size, TRUE);
+    size =  2; BUNappend(size_bat, (ptr)&size, TRUE);
+    size =  0; BUNappend(size_bat, (ptr)&size, TRUE);
+    size =  0; BUNappend(size_bat, (ptr)&size, TRUE);
+
+    level = -2; BUNappend(level_bat, (ptr)&level, TRUE);
+    level = -1; BUNappend(level_bat, (ptr)&level, TRUE);
+    level =  0; BUNappend(level_bat, (ptr)&level, TRUE);
+    level =  1; BUNappend(level_bat, (ptr)&level, TRUE);
+    level =  2; BUNappend(level_bat, (ptr)&level, TRUE);
+    level =  3; BUNappend(level_bat, (ptr)&level, TRUE);
+    level =  3; BUNappend(level_bat, (ptr)&level, TRUE);
+    level =  1; BUNappend(level_bat, (ptr)&level, TRUE);
+    level =  2; BUNappend(level_bat, (ptr)&level, TRUE);
+    level =  2; BUNappend(level_bat, (ptr)&level, TRUE);
+    level =  3; BUNappend(level_bat, (ptr)&level, TRUE);
+    level =  3; BUNappend(level_bat, (ptr)&level, TRUE);
+    assert(BATcount(size_bat) == BATcount(level_bat));
+        
+    pre =  4; BUNappend(used_bat, (ptr)&pre, TRUE); /* used: c */
+    pre =  7; BUNappend(used_bat, (ptr)&pre, TRUE); /* used: f */
+    pre =  3; BUNappend(returned_bat, (ptr)&pre, TRUE); /* returned: b */
+    pre =  8; BUNappend(returned_bat, (ptr)&pre, TRUE); /* returned: g */
+
+    res_bat = xrpc_projection(used_bat, returned_bat, size_bat, level_bat);
+    if(res_bat){
+        res_pre = (BAT*) Tloc(res_bat, BUNfirst(res_bat));
+        res_size = (BAT*) Tloc(res_bat, BUNlast(res_bat));
+        printf("res_pre\n");
+        BATprint(res_pre);
+        printf("res_size\n");
+        BATprint(res_size);
+
+        BBPreclaim(res_pre);
+        BBPreclaim(res_size);
+        BBPreclaim(res_bat);
+    }
+
+    BBPreclaim(size_bat);
+    BBPreclaim(level_bat);
+    BBPreclaim(used_bat);
+    BBPreclaim(returned_bat);
+    return GDK_FAIL;
+    /* end temporary code */
+
 
     if ((sock = setup_connection(dst, &port)) < 0) {
         return GDK_FAIL;

Index: ll_upwards.mx
===================================================================
RCS file: /cvsroot/monetdb/pathfinder/runtime/ll_upwards.mx,v
retrieving revision 1.27
retrieving revision 1.27.2.1
diff -u -d -r1.27 -r1.27.2.1
--- ll_upwards.mx       11 Jan 2008 10:47:19 -0000      1.27
+++ ll_upwards.mx       20 Feb 2008 22:45:06 -0000      1.27.2.1
@@ -88,25 +88,27 @@
 is limited, but is huge on multiple iterations, the new loop-lifted 
 algorithms for the upwards XPath axes seem a profitable addition for the 
 pathfinder runtime.
+
 @c
 #include "pf_config.h"
 #include <gdk.h>
 #include "shredder.h" /* for XML_DEPTH_MAX */
+#include "pf_support.h" /* for PF_SIBLING_PROBES and speculate_skip */
 
 static char LL_UPWARDS_PARENT[] = "parent";
 static char LL_UPWARDS_ANCESTOR[] = "ancestor";
 static char LL_UPWARDS_ANCESTOR_SELF[] = "ancestor-or-self";
 
 typedef struct {
- oid iter;
- oid pre; 
+    oid iter;
+    oid pre; 
 } duple;
 
 static INLINE oid 
 skipholes(oid pre, unsigned int *pre_size) {
-     while(pre_size[pre] & (1<<31)) 
-         pre += 1 + (pre_size[pre] & ~(1<<31)); /* skip over holes */
-     return pre; 
+    while(pre_size[pre] & (1<<31)) 
+        pre += 1 + (pre_size[pre] & ~(1<<31)); /* skip over holes */
+    return pre; 
 }
 
 @= found_parent
@@ -151,11 +153,11 @@
 @= upwards_core
 static int 
 [EMAIL PROTECTED](                            /* OUTPUT: */
-       oid *result_iter,
+        oid *result_iter,
         oid *result_pre, 
-       oid result_size,   /* - pre-allocated result array */
+        oid result_size,                  /* - pre-allocated result array */
         oid* bounds, oid *bounds_t,
-       oid** iter_stack,    /* - per iter bound */ 
+        oid** iter_stack,                 /* - per iter bound */ 
                                           /* DOCUMENT: */
         unsigned int* pre_size,           /* - pre_size column */
         unsigned char* pre_level,         /* - pre_level column */
@@ -171,11 +173,11 @@
     int depth = 0;  
 
     *stack++ = oid_nil; /* bogus parent, filtered out later */
-   (void) bounds_t;
-   (void) result_pre;
-   (void) result_size;
-   (void) min_iter;
-   (void) iter_stack;
+    (void) bounds_t;
+    (void) result_pre;
+    (void) result_size;
+    (void) min_iter;
+    (void) iter_stack;
 
     /* if the collection node is passed in, skip it */
     while(cur < context_size && context[cur].pre == 0) cur++;
@@ -199,7 +201,7 @@
             /* next context node is in the descendants: go find it */
             stack[depth++] = pre;
             pre = skipholes(pre+1, pre_size);
-           if (depth == XML_DEPTH_MAX || pre > limit) break; /* SANITY */
+            if (depth == XML_DEPTH_MAX || pre > limit) break; /* SANITY */
 
         } else if (depth == 0 || context[cur].pre <= stack[depth-1] + 
pre_size[stack[depth-1]]) {
             oid off = pre;
@@ -209,29 +211,28 @@
             /* in the branch that is on the stack, but in some sibling that we 
need to find */
             while(pre + pre_size[pre] < context[cur].pre) {
                 pre = skipholes(pre + pre_size[pre] + 1, pre_size); /* skip 
from sibling to sibling */
-               if (pre > limit) break; /* SANITY */
-               if (++cnt == budget) {
+                if (pre > limit) break; /* SANITY */
+                if (++cnt == budget) {
                     oid old = pre;
                     pre = speculate_skip(pre, context[cur].pre, pre-off, 
budget, pre_size, pre_level); 
                     if (pre == old) { 
-                       budget += budget; /* skip failed: wait longer next time 
*/
+                        budget += budget; /* skip failed: wait longer next 
time */
                     }
                     off = pre; cnt = 0;
                 }
             }
-           if (depth == 0)
-                   root = pre;
+            if (depth == 0)
+                root = pre;
         } else {
 
             /* pop the stack */
             pre = stack[--depth];
         }
-   }
-   return (cur == context_size);
+    }
+    return (cur == context_size);
 }
 
 @c
-#define PF_SIBLING_PROBES 64
 
 /* If an XML is regularly structured (contains "list" or "table" like data) 
such that we have
  * a subtree with very many siblings, the upwards steps will have to touch all 
the preceding
@@ -243,7 +244,7 @@
  * to skip siblings. To recognize such speculative siblings, we also need the 
level column.
  * We take care not to waste more time speculating than we already did 
traversing preceding siblings. 
  */
-static oid
+oid
 speculate_skip(oid pre, oid dst, oid skip, int budget, unsigned int* pre_size, 
unsigned char* pre_level) {
     skip = skip << 6;
     if (pre + skip < dst) {
@@ -318,64 +319,64 @@
 
     /* gather the context nodes and analyze them (order, min/max iter)  */
 @= ll_upwards_min_max
-               if (context[i].iter < min_iter) min_iter = context[i].iter;
-               if (context[i].iter > max_iter) max_iter = context[i].iter;
+    if (context[i].iter < min_iter) min_iter = context[i].iter;
+    if (context[i].iter > max_iter) max_iter = context[i].iter;
 @
 @= ll_upwards_copy
-           while(p < q) {
-                context[i].iter = @1;
-                context[i].pre  = @2;
-                @3
-               i++; p++; r++;
-            }
+       while(p < q) {
+        context[i].iter = @1;
+        context[i].pre  = @2;
+        @3
+            i++; p++; r++;
+    }
 @
 @c
     if (p < q) {
-       if (!(BATtordered(iter_bat)&1)) {
-           if (BATtdense(iter_bat) && BATtdense(ctx_bat)) {
-               oid iter = iter_bat->tseqbase;
-               oid pre  = ctx_bat->tseqbase;
-               @:ll_upwards_copy(iter++, pre++, @:ll_upwards_min_max@)@
-           } else
-           if (BATtdense(iter_bat) && ctx_bat->ttype == TYPE_oid) {
-               oid iter = iter_bat->tseqbase;
-               @:ll_upwards_copy(iter++, *(oid*) Tloc(ctx_bat,r), 
@:ll_upwards_min_max@)@
-           } else
-           if (iter_bat->ttype == TYPE_oid && BATtdense(ctx_bat)) {
-               oid pre  = ctx_bat->tseqbase;
-               @:ll_upwards_copy(*(oid*) Tloc(iter_bat,p), pre++, 
@:ll_upwards_min_max@)@
-           } else
-           if (iter_bat->ttype == TYPE_oid  && ctx_bat->ttype == TYPE_oid) {
-               @:ll_upwards_copy(*(oid*) Tloc(iter_bat,p), *(oid*) 
Tloc(ctx_bat,r), @:ll_upwards_min_max@)@
-           } else {
-               assert(0); /* should never happen */
-           }
+        if (!(BATtordered(iter_bat)&1)) {
+            if (BATtdense(iter_bat) && BATtdense(ctx_bat)) {
+                oid iter = iter_bat->tseqbase;
+                oid pre  = ctx_bat->tseqbase;
+                @:ll_upwards_copy(iter++, pre++, @:ll_upwards_min_max@)@
+            } else
+            if (BATtdense(iter_bat) && ctx_bat->ttype == TYPE_oid) {
+                oid iter = iter_bat->tseqbase;
+                @:ll_upwards_copy(iter++, *(oid*) Tloc(ctx_bat,r), 
@:ll_upwards_min_max@)@
+            } else
+            if (iter_bat->ttype == TYPE_oid && BATtdense(ctx_bat)) {
+                oid pre  = ctx_bat->tseqbase;
+                @:ll_upwards_copy(*(oid*) Tloc(iter_bat,p), pre++, 
@:ll_upwards_min_max@)@
+            } else
+               if (iter_bat->ttype == TYPE_oid  && ctx_bat->ttype == TYPE_oid) 
{
+                @:ll_upwards_copy(*(oid*) Tloc(iter_bat,p), *(oid*) 
Tloc(ctx_bat,r), @:ll_upwards_min_max@)@
+            } else {
+                assert(0); /* should never happen */
+            }
         } else {
             /* ordered iters, so we know min and max */
-           if (BATtdense(iter_bat) && BATtdense(ctx_bat)) {
-               oid iter = iter_bat->tseqbase;
-               oid pre  = ctx_bat->tseqbase;
-               @:ll_upwards_copy(iter++, pre++,)@
-           } else
-           if (BATtdense(iter_bat) && ctx_bat->ttype == TYPE_oid) {
-               oid iter = iter_bat->tseqbase;
-               @:ll_upwards_copy(iter++, *(oid*) Tloc(ctx_bat,r),)@
-           } else
-           if (iter_bat->ttype == TYPE_oid && BATtdense(ctx_bat)) {
-               oid pre  = ctx_bat->tseqbase;
-               @:ll_upwards_copy(*(oid*) Tloc(iter_bat,p), pre++,)@
-           } else
-           if (iter_bat->ttype == TYPE_oid && ctx_bat->ttype == TYPE_oid) {
-               @:ll_upwards_copy(*(oid*) Tloc(iter_bat,p), *(oid*) 
Tloc(ctx_bat,r),)@
-           } else {
-               assert(0); /* should never happen */
-           }
+            if (BATtdense(iter_bat) && BATtdense(ctx_bat)) {
+                oid iter = iter_bat->tseqbase;
+                oid pre  = ctx_bat->tseqbase;
+                @:ll_upwards_copy(iter++, pre++,)@
+            } else
+            if (BATtdense(iter_bat) && ctx_bat->ttype == TYPE_oid) {
+                oid iter = iter_bat->tseqbase;
+                @:ll_upwards_copy(iter++, *(oid*) Tloc(ctx_bat,r),)@
+            } else
+               if (iter_bat->ttype == TYPE_oid && BATtdense(ctx_bat)) {
+                oid pre  = ctx_bat->tseqbase;
+                @:ll_upwards_copy(*(oid*) Tloc(iter_bat,p), pre++,)@
+            } else
+               if (iter_bat->ttype == TYPE_oid && ctx_bat->ttype == TYPE_oid) {
+                @:ll_upwards_copy(*(oid*) Tloc(iter_bat,p), *(oid*) 
Tloc(ctx_bat,r),)@
+            } else {
+                assert(0); /* should never happen */
+            }
             min_iter = context[0].iter;
             max_iter = context[i-1].iter;
         }
         niters += max_iter - min_iter; /* the size of the per-iter lookup 
arrays */
     }
-    
+
     /* prune is a temporary array of duples, one duple per iter
      * - duple.pre  contains the pre-bound for pruning the previous node
      * - duple.iter is (mis)used to contain the position in context[] of
@@ -436,9 +437,9 @@
         oid *iter_stack[XML_DEPTH_MAX];
         oid *buf = (oid*) 
GDKmalloc(MAX(1,(m=XML_DEPTH_MAX*niters))*sizeof(oid)); 
         if (buf) {
-             /* initialize it, filled will all nil */
-             for(i=0; i<(size_t) XML_DEPTH_MAX; i++) iter_stack[i] = buf + 
i*niters;
-             for(i=0; i<m; i++) buf[i] = oid_nil;
+            /* initialize it, filled will all nil */
+            for(i=0; i<(size_t) XML_DEPTH_MAX; i++) iter_stack[i] = buf + 
i*niters;
+            for(i=0; i<m; i++) buf[i] = oid_nil;
 
             /* bounds will contain offsets into the result for each iter */
             for(i=0; i<n; i++) 
@@ -449,13 +450,13 @@
             bn = BATnew(TYPE_oid, TYPE_oid, n);
             if (bn) {
                 if (ll_upwards_parent(
-                    context_result_iter = (oid*) Hloc(bn, BUNfirst(bn)),
-                    context_result_pre  = (oid*) Tloc(bn, BUNfirst(bn)),
-                   n, 
-                    bounds, NULL, iter_stack+1, 
-                    pre_size, pre_level,
-                    BATcount(size_bat), 
-                    min_iter, context, n))
+                            context_result_iter = (oid*) Hloc(bn, 
BUNfirst(bn)),
+                            context_result_pre  = (oid*) Tloc(bn, 
BUNfirst(bn)),
+                            n, 
+                            bounds, NULL, iter_stack+1, 
+                            pre_size, pre_level,
+                            BATcount(size_bat), 
+                            min_iter, context, n))
                 {
                     /* filter out duplicates and non-existing fragment roots 
(represented by oid_nils) */
                     for(m=i=0; i<n; i++) {
@@ -468,7 +469,7 @@
                     status = GDK_SUCCEED;
 
                     /* for each context node, parent gives back 1 or 0 results 
*/ 
-                   if (iter_bat->tkey) BATkey(bn, TRUE);
+                    if (iter_bat->tkey) BATkey(bn, TRUE);
                 } else  {
                     GDKerror("%s: illegal data in size column or context 
list.\n", axis);
                 }
@@ -476,16 +477,16 @@
             GDKfree(buf);
         }
     } else if ( (context_result_pre=GDKzalloc(MAX(1,n)*sizeof(oid))) != NULL &&
-               (context_result_iter=GDKzalloc(MAX(1,n)*sizeof(oid))) != NULL ) 
{
+            (context_result_iter=GDKzalloc(MAX(1,n)*sizeof(oid))) != NULL ) {
         /* in first pass, bounds contains a partitioning bound (=0 < root) */
         if (ll_upwards_ancestor_cnt(
-                 context_result_iter, 
-                 context_result_pre, 
-                n, 
-                 bounds, NULL, NULL,
-                 pre_size, pre_level,
-                 BATcount(size_bat), 
-                 min_iter, context, n))
+                    context_result_iter, 
+                    context_result_pre, 
+                    n, 
+                    bounds, NULL, NULL,
+                    pre_size, pre_level,
+                    BATcount(size_bat), 
+                    min_iter, context, n))
         {
             /* count the hits per-iter, by examining hitcnt 
(context_result_iter) of each context node.
              * while doing so, put in context_result_pre the absolute position 
of self in the result 
@@ -521,16 +522,16 @@
                         result_iter[pos] = context[i].iter;
                     }
                 }
-               if (ll_upwards_ancestor_gen(
-                        context_result_iter, 
-                        context_result_pre, 
-                       m,
-                        (oid*) Hloc(bn, BUNfirst(bn)), /* HACK, pass result as 
bounds */ 
-                        (oid*) Tloc(bn, BUNfirst(bn)), /* HACK, pass result as 
bounds */ 
-                       NULL,
-                        pre_size, pre_level,
-                        BATcount(size_bat), 
-                        min_iter, context, n)) 
+                if (ll_upwards_ancestor_gen(
+                            context_result_iter, 
+                            context_result_pre, 
+                            m,
+                            (oid*) Hloc(bn, BUNfirst(bn)), /* HACK, pass 
result as bounds */ 
+                            (oid*) Tloc(bn, BUNfirst(bn)), /* HACK, pass 
result as bounds */ 
+                            NULL,
+                            pre_size, pre_level,
+                            BATcount(size_bat), 
+                            min_iter, context, n)) 
                 {
                     status = GDK_SUCCEED;
                 } else {
@@ -557,9 +558,9 @@
         bn->tsorted = 0;
         if (niters == 1) {
             bn->tsorted = 1;
-           BATkey(BATmirror(bn), 1);
+            BATkey(BATmirror(bn), 1);
         }
-       *ret = bn;
+        *ret = bn;
     } else if (bn) {
         BBPreclaim(bn);
     }

Index: Makefile.ag
===================================================================
RCS file: /cvsroot/monetdb/pathfinder/runtime/Makefile.ag,v
retrieving revision 1.83.2.1
retrieving revision 1.83.2.2
diff -u -d -r1.83.2.1 -r1.83.2.2
--- Makefile.ag 16 Feb 2008 01:02:20 -0000      1.83.2.1
+++ Makefile.ag 20 Feb 2008 22:45:06 -0000      1.83.2.2
@@ -54,7 +54,9 @@
         SOURCES = \
                 pf_support.mx \
                 shredder.mx 
+                               
         LIBS = \
+                          libxrpc_projection \
                 libserialize libpf $(PF_LIBS) \
                 $(MONETDB_LIBS) -lbat -lstream $(MONETDB4_LIBS) -lmonet 
$(PTHREAD_LIBS) \
                 $(MONETDB4_MODS) -l_lock -l_monettime -l_streams -l_builtin 
-l_ascii_io -l_algebra -l_constant
@@ -92,10 +94,15 @@
                 ../compiler/libcompiler2 \
                 ../compiler/sql/libsql \
                 ../compiler/xmlimport/libxmlimport \
-               ../compiler/utils/libstringutils \
-                $(PF_LIBS) \
-                $(MONETDB_LIBS) -lbat -lstream $(MONETDB4_LIBS) -lmonet 
$(PTHREAD_LIBS) \
-                $(MONETDB4_MODS) -l_streams -l_builtin -l_ascii_io -l_algebra 
-l_sys -l_constant -l_mapi 
+                               ../compiler/utils/libstringutils \
+                               $(PF_LIBS) \
+                               $(MONETDB_LIBS) -lbat -lstream $(MONETDB4_LIBS) 
-lmonet $(PTHREAD_LIBS) \
+                               $(MONETDB4_MODS) -l_streams -l_builtin 
-l_ascii_io -l_algebra -l_sys -l_constant -l_mapi 
+}
+
+lib_xrpc_projection = {
+               NOINST
+               SOURCES = xrpc_projection.mx
 }
 
 lib__xrpc_client = {
@@ -116,22 +123,22 @@
                                  xrpc_common.mx \
                                  xrpc_server.mx
         LIBS = \
-                ../compiler/libcompiler1 \
-                ../compiler/schema/libschema \
-                ../compiler/debug/libdebug \
-                ../compiler/parser/libparser \
-                ../compiler/semantics/libsemantics \
-                ../compiler/core/libcore \
-                ../compiler/algebra/libalgebra \
-                ../compiler/algebra/map/libmap \
-                ../compiler/algebra/prop/libprop \
-                ../compiler/algebra/opt/libopt \
-                ../compiler/mil/libmil \
-                ../compiler/mem/libmem_embedded \
-                ../compiler/libcompiler2 \
-                ../compiler/sql/libsql \
-                ../compiler/xmlimport/libxmlimport \
-               ../compiler/utils/libstringutils \
+                          ../compiler/libcompiler1 \
+                          ../compiler/schema/libschema \
+                          ../compiler/debug/libdebug \
+                          ../compiler/parser/libparser \
+                          ../compiler/semantics/libsemantics \
+                          ../compiler/core/libcore \
+                          ../compiler/algebra/libalgebra \
+                          ../compiler/algebra/map/libmap \
+                          ../compiler/algebra/prop/libprop \
+                          ../compiler/algebra/opt/libopt \
+                          ../compiler/mil/libmil \
+                          ../compiler/mem/libmem_embedded \
+                          ../compiler/libcompiler2 \
+                          ../compiler/sql/libsql \
+                          ../compiler/xmlimport/libxmlimport \
+                          ../compiler/utils/libstringutils \
                           $(PF_LIBS) $(SOCKET_LIBS) ./lib_pf_support 
./lib_pathfinder \
                           $(MONETDB_LIBS) -lbat -lstream $(MONETDB4_LIBS) 
-lmonet $(PTHREAD_LIBS) \
                           $(MONETDB4_MODS) -l_mapi -l_streams -l_builtin 
-l_ascii_io

--- NEW FILE: xrpc_projection.mx ---
@' Copyright Notice:
@' -----------------
@'
@' The contents of this file are subject to the Pathfinder Public License
@' Version 1.1 (the "License"); you may not use this file except in
@' compliance with the License.  You may obtain a copy of the License at
@' http://monetdb.cwi.nl/Legal/PathfinderLicense-1.1.html
@'
@' Software distributed under the License is distributed on an "AS IS"
@' basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.  See
@' the License for the specific language governing rights and limitations
@' under the License.
@'
@' The Original Code is the Pathfinder system.
@'
@' The Original Code has initially been developed by the Database &
@' Information Systems Group at the University of Konstanz, Germany and
@' is now maintained by the Database Systems Group at the Technische
@' Universitaet Muenchen, Germany.  Portions created by the University of
@' Konstanz and the Technische Universitaet Muenchen are Copyright (C)
@' 2000-2005 University of Konstanz and (C) 2005-2008 Technische
@' Universitaet Muenchen, respectively.  All Rights Reserved.
@'
@' $Id: xrpc_projection.mx,v 1.1.2.1 2008/02/20 22:45:10 yingying Exp $
@f xrpc_projection
@a Ying Zhang
@t Implements the xrpc_projection function, shared by the XRPC server and XRPC 
client

@h
#ifndef XRPC_PROJECTION_H
#define XRPC_PROJECTION_H

/* For XRPC client/server to access this function directly */
BAT *
xrpc_projection(
        BAT *used_bat,      /* - [void,oid] bat, PRE-s of used nodes */
        BAT *returned_bat,  /* - [void,oid] bat, PRE-s of returned nodes */
                            /* DOCUMENT: */
        BAT *size_bat,      /* - [void,int] bat, doc representation with holes 
*/ 
        BAT *level_bat);    /* - [void,chr] bat, doc representation with holes 
*/ 

#endif /* XRPC_PROJECTION_H */

@c
#include "pf_config.h"
#include "pf_support.h" /* for PF_SIBLING_PROBES and speculate_skip() */
#include "shredder.h" /* for XML_DEPTH_MAX */
#include "xrpc_common.h"
#include "xrpc_projection.h"

#define USED 0
#define RETURNED 1

typedef struct {
    oid pre;
    bte knd;
} projecting;

typedef struct {
    oid depth;
    oid cap;
    oid *pre;
    oid *off;
} stack;

static INLINE oid 
skipholes(oid pre, unsigned int *pre_size) {
    while(pre_size[pre] & (1<<31)) 
        pre += 1 + (pre_size[pre] & ~(1<<31)); /* skip over holes */
    return pre; 
}

static INLINE int
push(stack *stk, oid pre) {
    if (stk->depth == stk->cap) {
        ptr p = GDKrealloc(stk->pre, stk->cap*2);
        if(p == NULL) {
            GDKerror("xrpc_projection: stack full.\n");
            return GDK_FAIL;
        }
        stk->pre = (oid*)p;
        p = GDKrealloc(stk->off, stk->cap*2);
        if(p == NULL) {
            GDKerror("xrpc_projection: stack full.\n");
            return GDK_FAIL;
        }
        stk->off = (oid*)p;
        stk->cap *= stk->cap;
    }
    stk->pre[stk->depth] = pre;
    stk->depth++;
    return GDK_SUCCEED;
}

static INLINE oid
pop(stack *stk) {
    if(stk->depth == 0) return oid_nil;
    oid pre = stk->pre[stk->depth -1];
    stk->off[stk->depth - 1] = oid_nil;
    stk->depth--;
    return pre;
}

BAT *
xrpc_projection(
        BAT *used_bat,     /* - [void,oid] bat, PRE-s of used nodes */
        BAT *returned_bat, /* - [void,oid] bat, PRE-s of returned nodes */
                           /* DOCUMENT: */
        BAT *size_bat,     /* - [void,int] bat, doc representation with holes 
*/ 
        BAT *level_bat)    /* - [void,chr] bat, doc representation with holes 
*/ 
{
    oid i = 0, j = 0, k = 0;
    oid cur = 0, pre = 1; /* document root */
    oid *used_pre, *returned_pre;
    oid used_cnt = oid_nil, returned_cnt = oid_nil, rescnt = oid_nil;
    unsigned int *pre_size = NULL;
    unsigned char *pre_level = NULL;
    /* level of lowest/highest used/returned node, needed to estimate
     * result size and stack depth.  */
    int minlevel = UCHAR_MAX, maxlevel = 0;
    int inc = 0, inc2 = 0, newsize = 0;
    stack stk;
    projecting *context = NULL;
    oid context_size = 0, ctx = oid_nil, sbl = oid_nil;
    BAT *res = NULL, *res_pre = NULL, *res_size = NULL;
    BATiter bi;

    ERRORcheck(!used_bat,
            "xrpc_projection: used_bat may no be NULL.\n");
    ERRORcheck(!returned_bat,
            "xrpc_projection: returned_bat may no be NULL.\n");
    ERRORcheck(!(BATtordered(used_bat) & 1),
            "xrpc_projection: used_bat must be ordered on tail.\n");
    ERRORcheck(!(BATtordered(returned_bat) & 1),
            "xrpc_projection: returned nodes bat must be ordered on tail.\n");
    ERRORcheck((!size_bat || size_bat->hseqbase || !BAThdense(size_bat)),
            "xrpc_projection: illegal size_bat passed in.\n");
    ERRORcheck((!level_bat || level_bat->hseqbase || !BAThdense(level_bat)),
            "xrpc_projection: illegal level bat passed in.\n");

    pre_size = (unsigned int*) Tloc(size_bat, BUNfirst(size_bat));
    pre_level = (unsigned char*) Tloc(level_bat, BUNfirst(level_bat));

    used_pre = (oid*) Tloc(used_bat, BUNfirst(used_bat));
    returned_pre = (oid*) Tloc(returned_bat, BUNfirst(returned_bat));
    used_cnt = BATcount(used_bat);
    returned_cnt = BATcount(returned_bat);
    rescnt = used_cnt + returned_cnt; /* estimation of #nodes in 
xrpc_projection result */

    /* Merge used-nodes and returned-node into one 'context' list.
     * Nodes in 'context' are sorted by their PRE and has a 'knd' to
     * indicate if a node USED or RETURNED.
     *
     * When building the 'context' list, i) do pruning if a (used/returned)
     * node is included by another node, and ii) calculate maxlevel and
     * minlevel of all 'context' nodes. */
    context = (projecting*) GDKmalloc(rescnt * sizeof(projecting));
    if(context == NULL) return NULL;
    i = j = k = 0;
    while(j < returned_cnt){
        ctx = returned_pre[j++];
        sbl = ctx + pre_size[ctx] + 1; /* next sibling of ctx */

        while(used_pre[i] < ctx) { /* copy used_node before ctx */
            minlevel = pre_level[used_pre[i]] < minlevel ? pre_level[ctx] : 
minlevel;
            maxlevel = pre_level[used_pre[i]] > maxlevel ? pre_level[ctx] : 
maxlevel;
            context[k].pre = used_pre[i++];
            context[k++].knd = USED;
        }
        context[k].pre = ctx;
        context[k++].knd = RETURNED;
        rescnt += pre_size[ctx];
        minlevel = pre_level[ctx] < minlevel ? pre_level[ctx] : minlevel;
        maxlevel = pre_level[ctx] > maxlevel ? pre_level[ctx] : maxlevel;

        /* For each returned-node N, prune */
        /* i) if a used-node is (a descendant of) N */
        while(ctx <= used_pre[i] && used_pre[i] < sbl) i++;
        /* ii) if a subsequent returned-node is a descendant of N */
        while(ctx < returned_pre[j] && returned_pre[j] < sbl) j++;
    }
    while(i < used_cnt){ /* add remaining used-nodes to our list */
        minlevel = pre_level[used_pre[i]] < minlevel ? pre_level[ctx] : 
minlevel;
        maxlevel = pre_level[used_pre[i]] > maxlevel ? pre_level[ctx] : 
maxlevel;
        context[k].pre = used_pre[i++];
        context[k++].knd = USED;
    }
    context[k].pre = oid_nil;
    context_size = k;
    /* 'context' now holds a list of sorted PRE numbers of used- and
     * returned-nodes, which really need to be handled */

    /* preparing results BATs */
    rescnt += (maxlevel * context_size); /* estimation: space for ancestors */
    res_pre = BATnew(TYPE_void, TYPE_oid, rescnt);
    res_size = BATnew(TYPE_void, TYPE_int, rescnt);
    if(res_pre == NULL || res_size == NULL) {
        GDKfree(context);
        if(res_pre) BBPreclaim(res_pre);
        if(res_size) BBPreclaim(res_size);
        return NULL;
    }
    res_pre = BATseqbase(res_pre, 0);
    res_pre = BATsetaccess(res_pre, BAT_APPEND);
    res_size = BATseqbase(res_size, 0);

    k = maxlevel + 1;
    stk.pre = GDKmalloc(k * sizeof(oid));
    stk.off = GDKmalloc(k * sizeof(oid));
    if(stk.pre == NULL || stk.off == NULL){
        GDKfree(context);
        BBPreclaim(res_pre);
        BBPreclaim(res_size);
        if(stk.pre) GDKfree(stk.pre);
        if(stk.off) GDKfree(stk.off);
        return NULL;
    }
    for(i = 0; i < k; i++) stk.pre[i] = stk.off[i] = oid_nil;
    stk.depth = 0;
    stk.cap = k;

    /* if the collection node is passed in, skip it */
    cur = 0;
    while(cur < context_size && context[cur].pre == 0) cur++;

    /* we perform a forwards scan with skipping, that carries out an *optimal* 
     * depth-first DOM tree traversal (where we visit nodes only if needed)
     */
    oid limit = BATcount(size_bat);
    while(cur < context_size) { /* while still context nodes active */

        if (context[cur].pre == pre) { /* found a context node */
            inc = context[cur].knd == USED ? 1 : pre_size[context[cur].pre] + 1;
            /* process nodes on stack bottom-up! */
            bi = bat_iterator(res_size);
            for(i = 0; i < stk.depth; i++){
                if(stk.off[i] == oid_nil){ /* not written to output yet */
                    inc2 = stk.depth - i - 1 + inc;
                    BUNappend(res_pre, (ptr)&(stk.pre[i]), FALSE);
                    BUNappend(res_size, (ptr)&inc2, FALSE);
                    stk.off[i] = BATcount(res_pre) - 1;
                } else { /* already in output, update 'size' */
                    newsize = *(int*)BUNtloc(bi, BUNfnd(res_size, 
&(stk.off[i]))) + inc;
                    BUNreplace(res_size, (ptr)&(stk.off[i]), (ptr)&newsize, 
FALSE); 
                }
            }

            if(context[cur].knd == USED){
                /* copy context node */
                inc = 0;
                BUNappend(res_pre, (ptr)&pre, FALSE);
                BUNappend(res_size, (ptr)&inc, FALSE); /* size = 0 */
                if (context[cur + 1].pre < (pre + pre_size[pre] + 1)){
                    /* next context node is in the subtree of pre (i.e.
                     * current context node), push pre to stack */
                    push(&stk, pre);
                    /* since this pre is already written to output,
                     * remember its offset in output */
                    stk.off[stk.depth-1] = BATcount(res_pre) - 1;
                    pre = skipholes(pre+1, pre_size);
                }
            } else {
                /* copy all descendants */
                for (i = context[cur].pre; i <= context[cur].pre + 
pre_size[context[cur].pre]; i++){
                    BUNappend(res_pre, (ptr)&i, FALSE);
                    BUNappend(res_size, (ptr)&pre_size[i], FALSE);
                }
                /* we can skip the subtree of context[cur] */
                pre += pre_size[pre] + 1;
            }
            cur++;
        } else if (context[cur].pre <= pre + pre_size[pre]) {
            /* next context node is in the descendants: go find it */
            if(push(&stk, pre) == GDK_FAIL) break; /* should not happen */
            pre = skipholes(pre+1, pre_size);
            if (stk.depth == XML_DEPTH_MAX || pre > limit) break; /* SANITY */
        } else if (stk.depth == 0 || context[cur].pre <= stk.pre[stk.depth-1] + 
pre_size[stk.pre[stk.depth-1]]) {
            oid off = pre;
            int budget = PF_SIBLING_PROBES;
            int cnt = 0;

            /* in the branch that is on the stack, but in some sibling
             * that we need to find */
            while(pre + pre_size[pre] < context[cur].pre) {
                pre = skipholes(pre + pre_size[pre] + 1, pre_size); /* skip 
from sibling to sibling */
                if (pre > limit) break; /* SANITY */
                if (++cnt == budget) {
                    oid old = pre;
                    pre = speculate_skip(pre, context[cur].pre, pre-off, 
budget, pre_size, pre_level); 
                    if (pre == old) { 
                        budget += budget; /* skip failed: wait longer next time 
*/
                    }
                    off = pre; cnt = 0;
                }
            }
        } else {
            pre = pop(&stk);
        }
    }

    if (cur == context_size) {
        res = BATnew(TYPE_void, TYPE_bat, 2);
        if (res == NULL)
            goto bunins_failed;
        res = BATseqbase(res, 0);
        bunfastins(res, NULL, &res_pre->batCacheid);
        BBPunfix(res_pre->batCacheid);
        bunfastins(res, NULL, &res_size->batCacheid);
        BBPunfix(res_size->batCacheid);
    } else {
        BBPreclaim(res_pre);
        BBPreclaim(res_size);
    }
    GDKfree(context);
    GDKfree(stk.pre);
    GDKfree(stk.off);
    return res;

/* required by bunfastins macro */
bunins_failed:
    BBPreclaim(res_pre);
    BBPreclaim(res_size);
    GDKfree(context);
    GDKfree(stk.pre);
    GDKfree(stk.off);
    return NULL;
}

int CMDprojected_put(
        str options,
        str file,
        BAT *used_item,
        BAT *used_kind,
        BAT *returned_item,
        BAT *returned_kind,
        BAT *ws,
        BAT *int_values,
        BAT *dbl_values,
        BAT *dec_values,
        BAT *str_values)
{
    (void) options;
    (void) file;
    (void) used_item;
    (void) used_kind;
    (void) returned_item;
    (void) returned_kind;
    (void) ws;
    (void) int_values;
    (void) dbl_values;
    (void) dec_values;
    (void) str_values;

    GDKerror("CMDprojected_put: not implemented yet.\n");
    return GDK_FAIL;
}

Index: xrpc_server.mx
===================================================================
RCS file: /cvsroot/monetdb/pathfinder/runtime/xrpc_server.mx,v
retrieving revision 1.58.2.1
retrieving revision 1.58.2.2
diff -u -d -r1.58.2.1 -r1.58.2.2
--- xrpc_server.mx      16 Feb 2008 01:02:21 -0000      1.58.2.1
+++ xrpc_server.mx      20 Feb 2008 22:45:10 -0000      1.58.2.2
@@ -161,6 +161,7 @@
 #include "xrpc_common.h"
 #include "xrpc_server.h"
 #include "shttpd.h"
+#include "xrpc_projection.h"
 
 extern int xrpc_port;
 static int rpcd_running = 0;


-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
Monetdb-pf-checkins mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/monetdb-pf-checkins

Reply via email to