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

Reply via email to