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