Update of /cvsroot/monetdb/pathfinder/runtime
In directory sc8-pr-cvs16.sourceforge.net:/tmp/cvs-serv13571/runtime
Modified Files:
pf_support.mx
Log Message:
propagated changes of Thursday Jan 03 2008
from the XQuery_0-20 branch to the development trunk
Index: pf_support.mx
===================================================================
RCS file: /cvsroot/monetdb/pathfinder/runtime/pf_support.mx,v
retrieving revision 1.274
retrieving revision 1.275
diff -u -d -r1.274 -r1.275
--- pf_support.mx 2 Jan 2008 14:20:46 -0000 1.274
+++ pf_support.mx 3 Jan 2008 16:11:21 -0000 1.275
@@ -3429,7 +3429,7 @@
var insertcont := batcont.fetch(idx);
var insertitem := $t;
- if (not(isnil(ws.fetch(PRE_KIND).find(insertcont).find(insertitem)))) {
# don't insert holes
+ if (not(isnil(ws.fetch(PRE_KIND).find(insertcont).find(insertitem)))) {
# do not insert holes
# insertsize - size of item to be inserted
# doccont - container of document-to-be-modified
var insertsize := ws.fetch(PRE_SIZE).find(insertcont).find(insertitem)
+ 1;
@@ -3517,21 +3517,14 @@
var docinsertbefore_newpre := oid(lng(docinsertafter_newpre) + 1);
var docinsertbefore_rid := antiswizzle(docinsertbefore_newpre,
map_pid_update);
- # the start of the page on which the new element is to be inserted
- var pageno := oid(lng(docinsertbefore_newpre) >> REMAP_PAGE_BITS);
- # the physical page id
- var pageid := map_pid_update.reverse().find(pageno);
- # the rid of the first element on the page
- var pagebase := oid(lng(pageid) << REMAP_PAGE_BITS);
- var pagelast := oid(lng(pagebase) + REMAP_PAGE_MASK);
- var isoldpage := false;
- if (map_pid.exist(pageid)) {
- isoldpage := not(isnil(map_pid.find(pageid)));
- }
-
if (docinsertcmd = lng(UPDATE_REPLACECONTENT)) {
var size;
extend_protect(ws, doccont);
+ var pageid := oid(lng(docinsertbefore_rid) >> REMAP_PAGE_BITS);
+ var isoldpage := false;
+ if (map_pid.exist(pageid)) {
+ isoldpage := not(isnil(map_pid.find(pageid)));
+ }
if (isoldpage) {
if (rid_size_update.exist(docinsertafter_rid)) {
size := rid_size_update.find(docinsertafter_rid);
@@ -3575,53 +3568,70 @@
# figure out the number of holes on the page on which the new
# element is to be inserted (we use the PRE_KIND table for this,
# holes are indicated with NIL)
- var rid_kind_page;
- if (isoldpage) {
- rid_kind_page := pre_kind.reverse().select(swizzle(pagebase,
map_pid), swizzle(pagelast, map_pid)).reverse().seqbase(pagebase);
- var rid_kind_page_update :=
rid_kind_update.reverse().select(pagebase, pagelast).reverse();
- rid_kind_page :=
rid_kind_page.copy().access(BAT_WRITE).key(true).myupdate(rid_kind_page_update);
- # record that this page gets changed (new pages don't need to be
recorded)
- ws.fetch(MODIFIED_PAGE).insert(doccont, pageid);
- } else {
- rid_kind_page := rid_kind.reverse().select(pagebase,
pagelast).reverse();
- }
- var holeatend; # size of hole at end of page
- {
- var rid_kind_page_used := rid_kind_page.tmark([EMAIL
PROTECTED]).uselect(chr_nil, chr_nil);
- if (rid_kind_page_used.count() > 0) {
- holeatend := int(REMAP_PAGE_MASK -
lng(max(reverse(rid_kind_page_used))));
+ var holeatend := 0; # size of hole at end of page
+ var holeatstart := 0; # size of hole at start of next page
+ if (int(docinsertbefore_newpre) < docsize) {
+ var rid_kind_page;
+ # the start of the page on which the new element is to be inserted
(the page exists)
+ var pageno := oid(lng(docinsertbefore_newpre) >> REMAP_PAGE_BITS);
+ # the physical page id
+ var pageid := map_pid_update.reverse().find(pageno);
+ # the rid of the first element on the page
+ var pagebase := oid(lng(pageid) << REMAP_PAGE_BITS);
+ var pagelast := oid(lng(pagebase) + REMAP_PAGE_MASK);
+ var isoldpage := false;
+ if (map_pid.exist(pageid)) {
+ isoldpage := not(isnil(map_pid.find(pageid)));
+ }
+
+ if (isoldpage) {
+ rid_kind_page := pre_kind.reverse().select(swizzle(pagebase,
map_pid), swizzle(pagelast, map_pid)).reverse().seqbase(pagebase);
+ var rid_kind_page_update :=
rid_kind_update.reverse().select(pagebase, pagelast).reverse();
+ rid_kind_page :=
rid_kind_page.copy().access(BAT_WRITE).key(true).myupdate(rid_kind_page_update);
+ # record that this page gets changed (new pages do not need to
be recorded)
+ ws.fetch(MODIFIED_PAGE).insert(doccont, pageid);
} else {
- holeatend := int(REMAP_PAGE_SIZE);
+ rid_kind_page := rid_kind.reverse().select(pagebase,
pagelast).reverse();
}
- }
- var holeatstart := 0;
- # if we're inserting at the position of the hole at the end
- # of the page and there's not enough space, also look at any
- # hole at the start of the next
- if ((((int(docinsertbefore_rid) + holeatend) and REMAP_PAGE_BITS) =
0) and (insertsize > holeatend)) {
- # not enough space on the current page, see if there is space at
the
- # start of the next
- var nxtpgno := oid(lng(pageno) + 1);
- if ((int(nxtpgno) << REMAP_PAGE_BITS) < docsize) {
- var nxtpgid := map_pid_update.reverse().find(nxtpgno);
- var nxtisoldpg := false;
- if (map_pid.exist(nxtpgid)) {
- nxtisoldpg := not(isnil(map_pid.find(nxtpgid)));
+ {
+ var rid_kind_page_used := rid_kind_page.tmark([EMAIL
PROTECTED]).uselect(chr_nil, chr_nil);
+ if (rid_kind_page_used.count() > 0) {
+ holeatend := int(REMAP_PAGE_MASK -
lng(max(reverse(rid_kind_page_used))));
+ } else {
+ holeatend := int(REMAP_PAGE_SIZE);
}
- var sz;
- if (nxtisoldpg) {
- if (rid_size_update.exist(oid(lng(nxtpgid) <<
REMAP_PAGE_BITS))) {
- sz := rid_size_update.find(oid(lng(nxtpgid) <<
REMAP_PAGE_BITS));
+ }
+ # if we are inserting at the position of the hole at the end
+ # of the page and there is not enough space, also look at any
+ # hole at the start of the next
+ if ((((int(docinsertbefore_rid) + holeatend) and REMAP_PAGE_BITS)
= 0) and (insertsize > holeatend)) {
+ # not enough space on the current page, see if there is space at
the
+ # start of the next
+ var nxtpgno := oid(lng(pageno) + 1);
+ if ((int(nxtpgno) << REMAP_PAGE_BITS) < docsize) {
+ var nxtpgid := map_pid_update.reverse().find(nxtpgno);
+ var nxtisoldpg := false;
+ if (map_pid.exist(nxtpgid)) {
+ nxtisoldpg := not(isnil(map_pid.find(nxtpgid)));
+ }
+ var sz;
+ if (nxtisoldpg) {
+ if (rid_size_update.exist(oid(lng(nxtpgid) <<
REMAP_PAGE_BITS))) {
+ sz := rid_size_update.find(oid(lng(nxtpgid) <<
REMAP_PAGE_BITS));
+ } else {
+ sz := pre_size.find(oid(lng(nxtpgno) << REMAP_PAGE_BITS));
+ }
} else {
- sz := pre_size.find(oid(lng(nxtpgno) << REMAP_PAGE_BITS));
+ sz := rid_size.find(oid(lng(nxtpgid) << REMAP_PAGE_BITS));
+ }
+ if (isnil(niland(sz, int_nil))) {
+ holeatstart := niland(sz, INT_MAX) + 1;
}
- } else {
- sz := rid_size.find(oid(lng(nxtpgid) << REMAP_PAGE_BITS));
- }
- if (isnil(niland(sz, int_nil))) {
- holeatstart := niland(sz, INT_MAX) + 1;
}
}
+ } else if (int(docinsertbefore_newpre) = docsize) {
+ # special case: insert at end of document, so the hole is the rest
of the page
+ holeatend := int((REMAP_PAGE_SIZE - (lng(docsize) and
REMAP_PAGE_MASK)) and REMAP_PAGE_MASK);
}
if (insertsize > holeatend + holeatstart) {
# not enough space on the current page and the start of the next
page
@@ -3632,7 +3642,7 @@
# number of new pages needed (we need to insert insertsize, we
# have holeatend available; round up to whole number of pages)
var npages := ((insertsize - holeatend) + int(REMAP_PAGE_MASK)) >>
REMAP_PAGE_BITS;
- # the size of the hole we're going to insert
+ # the size of the hole we are going to insert
# we move the bit after the insert point to the last inserted page
var shiftsize := npages << REMAP_PAGE_BITS;
@@ -3646,6 +3656,20 @@
}
new_page.insert(newpages.reverse().project(doccont).reverse());
var cpstart_rid, cpsize, cpwhere_rid, newholeatend;
+ # insert new pages before current if there is no hole at
+ # the end, we need to insert into the first half of the
+ # page, and we are not inserting on the first page
+ var pageno := oid(lng(docinsertbefore_newpre) >> REMAP_PAGE_BITS);
+ var isoldpage := false;
+ # the physical page id
+ var pageid;
+ if (int(docinsertbefore_newpre) < docsize) {
+ # inserting into existing page, figure out whether it is an old
one
+ pageid := map_pid_update.reverse().find(pageno);
+ if (map_pid.exist(pageid)) {
+ isoldpage := not(isnil(map_pid.find(pageid)));
+ }
+ }
if ((holeatend = 0) and (datasize > int(REMAP_PAGE_SIZE / 2)) and
(pageno > [EMAIL PROTECTED])) {
# insert new pages before current
newpages := newpages.seqbase(pageno);
@@ -3654,8 +3678,14 @@
docinsertafter_rid := antiswizzle(docinsertafter_newpre,
map_pid_update);
docinsertbefore_rid := antiswizzle(docinsertbefore_newpre,
map_pid_update);
# we need to copy the initial part of the current page to the
first new page
- cpstart_rid := oid(lng(pageid) << REMAP_PAGE_BITS);
- cpsize := int(REMAP_PAGE_SIZE) - datasize;
+ if (int(docinsertbefore_newpre) < docsize) {
+ cpstart_rid := oid(lng(pageid) << REMAP_PAGE_BITS);
+ cpsize := int(REMAP_PAGE_SIZE) - datasize;
+ } else {
+ # we are adding to the end of the document: nothing to copy
+ cpstart_rid := [EMAIL PROTECTED];
+ cpsize := 0;
+ }
cpwhere_rid := oid(lng(newpages.fetch(0)) << REMAP_PAGE_BITS);
newholeatend := holeatend;
} else {
@@ -3677,7 +3707,7 @@
}
if (cpwhere_rid > pgstart) {
- # fix up hole at start of last page since it doesn't
+ # fix up hole at start of last page since it does not
# extend to the end of the page anymore (this will be
# overwritten again)
extend_protect(ws, doccont);
@@ -3770,14 +3800,14 @@
}
}
- # We've inserted new pages and copied the data on the rest
+ # We have inserted new pages and copied the data on the rest
# of the page to the last inserted page. Now increase the
# sizes of all ancestors. Note that no holes can cross the
# insert point (docinsertafter_newpre points to a non-hole
# element)
# Note, that even though the sizes of the moved data are not
# yet consistent with the new situation, that is not a
- # problem, since we're only looking at sizes of data before
+ # problem, since we are only looking at sizes of data before
# the insertion point.
var ancestors_oldpre := new(void,oid).seqbase([EMAIL
PROTECTED]).append([EMAIL
PROTECTED]).append(ll_ancestor_or_self(new(void,oid).seqbase([EMAIL
PROTECTED]).append([EMAIL PROTECTED]), new(void,oid).seqbase([EMAIL
PROTECTED]).append(docinsertafter_oldpre), pre_size, pre_level));
var ancestors_nid := ancestors_oldpre.join(pre_nid);
@@ -3819,13 +3849,6 @@
}
# register which ancestors are being changed
ancestor_nid.insert(new_size.project(doccont).reverse().join(ancestors_nid));
-
- # recalculate isoldpage (and pageid) after having inserted the new
pages
- pageid := map_pid_update.reverse().find(pageno);
- isoldpage := false;
- if (map_pid.exist(pageid)) {
- isoldpage := not(isnil(map_pid.find(pageid)));
- }
} else {
# the inserted data fits on the current page but we may have to
# move data around to make a hole big ineough in the right place
@@ -3835,10 +3858,26 @@
{
var rid := docinsertbefore_rid;
var pre := docinsertbefore_newpre;
+ var pagelast := [EMAIL PROTECTED];
+ var isoldpage := false;
+ var loop := true;
if (int(pre) >= docsize) {
+ # note that the document cannot end at a page boundary
+ # (there would not be a hole to insert into, so we
+ # would not get here)
holesize := int(REMAP_PAGE_SIZE - (lng(docsize) and
REMAP_PAGE_MASK));
+ loop := false;
+ } else {
+ var pageno := oid(lng(docinsertbefore_newpre) >>
REMAP_PAGE_BITS);
+ # the physical page id
+ var pageid := map_pid_update.reverse().find(pageno);
+ # the rid of the first element on the page
+ var pagebase := oid(lng(pageid) << REMAP_PAGE_BITS);
+ pagelast := oid(lng(pagebase) + REMAP_PAGE_MASK);
+ if (map_pid.exist(pageid)) {
+ isoldpage := not(isnil(map_pid.find(pageid)));
+ }
}
- var loop := true;
while (loop and (int(pre) < docsize) and (rid <= pagelast)) {
var s := 0;
if (isoldpage) {
@@ -3854,7 +3893,7 @@
extend_unprotect(ws, doccont);
}
if (isnil(niland(s, int_nil))) {
- # we're looking at a hole
+ # we are looking at a hole
var h := niland(s, INT_MAX) + 1;
holesize :+= h;
pre := oid(lng(pre) + h);
@@ -3868,7 +3907,7 @@
holesize :+= (int(pagelast) - int(rid)) + 1;
}
}
- # note: holeatstart = 0 if the insert point isn't at the start of
the hole at the end of the page
+ # note: holeatstart = 0 if the insert point is not at the start of
the hole at the end of the page
if ((holesize + holeatstart) < insertsize) {
# not enough space in the right place
movedata(ws, doccont, oid(lng(docinsertbefore_newpre) +
holesize), int(REMAP_PAGE_SIZE - ((lng(docinsertbefore_newpre) and
REMAP_PAGE_MASK) + holesize + holeatend)), insertsize - holesize);
@@ -3956,7 +3995,7 @@
# if (debug) printf("leveldiff %d\n", leveldiff);
if (insert_pre_kind.find(insertitem) = TEXT) {
- # if we're inserting a text node, we may have to merge
+ # if we are inserting a text node, we may have to merge
# consecutive text nodes
# we remember the position in a hacky place
# note, insertsize == 1 in this case
@@ -3971,9 +4010,9 @@
while (insertsize > 0) {
# docinsertpoint_rid is the RID for the new data
var docinsertpoint_rid := antiswizzle(docinsertpoint,
map_pid_update);
- # recalculate isoldpage for this iteration
- pageid := oid(lng(docinsertpoint_rid) >> REMAP_PAGE_BITS);
- isoldpage := false;
+ # recalculate isoldpage for each iteration
+ var pageid := oid(lng(docinsertpoint_rid) >> REMAP_PAGE_BITS);
+ var isoldpage := false;
if (map_pid.exist(pageid)) {
isoldpage := not(isnil(map_pid.find(pageid)));
}
@@ -4185,8 +4224,8 @@
}
while (delsize >= 0) {
var rid := oid((lng(newpre) and REMAP_PAGE_MASK) or (lng(pageid) <<
REMAP_PAGE_BITS));
- var nsize; # new size we're going to write (may join with consecutive hole)
- var pgsize; # size of hole we're dealing with this iteration (does not
cross page boundary)
+ var nsize; # new size we are going to write (may join with consecutive
hole)
+ var pgsize; # size of hole we are dealing with this iteration (does not
cross page boundary)
if (oid(lng(newpre) + delsize) >= next_pagebase) {
# new hole extends into next page
nsize := (int(next_pagebase) - int(newpre)) - 1;
@@ -4241,7 +4280,7 @@
update_data := [swizzle](pre_nid.reverse().select(oldpre,
oid(lng(oldpre) + pgsize)), pid_map).hmark(rid);
update_data.access(BAT_WRITE).myupdate(rid_nid_update.reverse().select(rid,
oid(lng(rid) + pgsize)).reverse());
} else {
- # we're deleting a new node, so there is no data about it (or its
descendants) in pre_nid
+ # we are deleting a new node, so there is no data about it (or its
descendants) in pre_nid
update_data := rid_nid_update.reverse().select(rid, oid(lng(rid) +
pgsize)).reverse().sort();
}
} else {
@@ -4254,8 +4293,8 @@
# into NID_QN_{INS,DEL} tables for our convenience.
# Since previous work in this transaction may have added nodes we
# are going to delete, some of the nodes may already appear in
- # NID_QN_INS, so we need to remove them. That's easy, however, since
- # we can remove all entries that contain NIDs of nodes we're deleting.
+ # NID_QN_INS, so we need to remove them. That is easy, however, since
+ # we can remove all entries that contain NIDs of nodes we are deleting.
# Harder is figuring out which NID/QN combinations of original nodes
# are being deleted.
# Note that update_data contains RID/NID values of nodes being
@@ -4332,13 +4371,13 @@
var del_page := ws.fetch(DEL_PAGE);
del_page.insert(cont, pageid);
# use the *before* version of map_pid_update (not that this is
- # particularly important: we're dealing with ancestors which
+ # particularly important: we are dealing with ancestors which
# necessarily come before the to-be-deleted page)
var pid_map_update := map_pid_update.select(oid_nil,
oid_nil).reverse().sort().tmark([EMAIL PROTECTED]);
# now update map_pid_update
map_pid_update.replace([oid]([-]([int](map_pid_update.select(pageno,
oid_nil, false, true)), 1)), true);
map_pid_update.replace(pageid, oid_nil, true);
- # figure out which ancestors' sizes need to adjusted
+ # figure out which ancestor sizes need to adjusted
var ancestors_newrid := [swizzle](ancestors_newpre, pid_map_update);
var ancestors_isnewpage :=
[isnil](outerjoin([oid]([>>]([lng](ancestors_newrid), REMAP_PAGE_BITS)),
map_pid));
var ancestors_nid;
@@ -4520,7 +4559,7 @@
var rid_nid := ws.fetch(_RID_NID).find(cont);
var rid_nid_update := ws.fetch(RID_NID_UPDATE).find(cont);
- # record where we're deleting a node
+ # record where we are deleting a node
{
var pid_map_update := map_pid_update.select(oid_nil,
oid_nil).reverse().sort().tmark([EMAIL PROTECTED]);
var docsize; # current size of document
-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2005.
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