patches to realese cache for atomized values of nodes

classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

patches to realese cache for atomized values of nodes

Евгений-8


Index: eXist-1.0/src/org/exist/storage/dom/DOMFile.java
===================================================================
RCS file: /cvsroot/exist/eXist-1.0/src/org/exist/storage/dom/DOMFile.java,v
retrieving revision 1.7
diff -u -r1.7 DOMFile.java
--- eXist-1.0/src/org/exist/storage/dom/DOMFile.java 30 Sep 2005 09:43:47 -0000 1.7
+++ eXist-1.0/src/org/exist/storage/dom/DOMFile.java 12 Oct 2005 13:56:11 -0000
@@ -60,9 +60,12 @@
 import org.exist.util.Lockable;
 import org.exist.util.ReadOnlyException;
 import org.exist.util.hashtable.Object2LongIdentityHashMap;
+import org.exist.util.hashtable.Long2ObjectHashMap;
 import org.exist.util.sanity.SanityCheck;
 import org.exist.xquery.TerminatedException;
 import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
 
 /**
  * This is the main storage for XML nodes. Nodes are stored in document order.
@@ -151,16 +154,61 @@
 
  public final static long DATA_SYNC_PERIOD = 4200;
 
+    private Long2ObjectHashMap values = new Long2ObjectHashMap(); // cach for values  of nodes
+
  private final Cache dataCache;
 
+    private long mask(long m){
+        return m & 0xFFFFFFFF0000FFFFL;
+    }
+    
+    private String getValuesCache(long p){
+        return (String)values.get(mask(p));
+    }
+
+    private void putValuesCache(long p, String value){
+        values.put(mask(p),value);
+    }
+    
+    /**
+     * Clear cash values for node with address p
+     *
+     * @param p
+     */
+    private void clearValuesCache(long p){
+         values.remove(mask(p));
+    }
+    
+    private void clearValuesCache(NodeImpl node){
+        clearValuesCache(node.getInternalAddress());
+    }
+    
+    private void clearAncestorValuesCache(NodeImpl node){
+        Node parent = node.getParentNode();
+        while (parent!=null){
+            clearValuesCache((NodeImpl)parent);
+            parent = parent.getParentNode();
+        }
+    }
+    
+    private void clearChildrenValuesCache(NodeImpl node){
+        if (node.hasChildNodes()){
+            NodeList children = node.getChildNodes();
+            for (int i = 0; i < children.getLength(); i++){
+                NodeImpl n = (NodeImpl) children.item(i);
+                clearChildrenValuesCache(n);
+                clearValuesCache(n);
+            }
+        }
+    }
+    
  private BTreeFileHeader fileHeader;
 
  private Object owner = null;
 
  private Lock lock = null;
 
- private final Object2LongIdentityHashMap pages = new Object2LongIdentityHashMap(
- 64);
+ private final Object2LongIdentityHashMap pages = new Object2LongIdentityHashMap(64);
 
  private DocumentImpl currentDocument = null;
 
@@ -1425,7 +1473,7 @@
  }
  }
 
- /**
+     /**
  * Physically remove a node. The data of the node will be removed from the
  * page and the occupied space is freed.
  *
@@ -1436,6 +1484,7 @@
  }
 
  public void removeNode(Txn transaction, long p) {
+        clearValuesCache(p); //remove node's value from cahce
  RecordPos rec = findRecord(p);
  final int startOffset = rec.offset - 2;
  final DOMFilePageHeader ph = rec.page.getPageHeader();
@@ -1523,6 +1572,11 @@
  }
  }
 
+ public void remove(Txn transaction, Value key, NodeImpl node) {
+        clearAncestorValuesCache(node);
+        remove(transaction, key, node.getInternalAddress());
+    }
+    
  /**
  * Remove the specified page. The page is added to the list of free pages.
  *
@@ -1572,6 +1626,7 @@
  public void removeAll(Txn transaction, long p) {
 // StringBuffer debug = new StringBuffer();
 // debug.append("Removed pages: ");
+        clearValuesCache(p);
  long pnum = StorageAddress.pageFromPointer(p);
  while (-1 < pnum) {
 // debug.append(' ').append(pnum);
@@ -1603,6 +1658,11 @@
 // LOG.debug(debug.toString());
  }
 
+ public void removeAll(Txn transaction, NodeImpl node) {
+         clearChildrenValuesCache(node);
+         removeAll(transaction, node.getInternalAddress());
+    }
+    
  public String debugPages(DocumentImpl doc, boolean showPageContents) {
  StringBuffer buf = new StringBuffer();
  buf.append("Pages used by ").append(doc.getName());
@@ -1699,6 +1759,9 @@
  */
  public void update(Txn transaction, long p, byte[] value)
  throws ReadOnlyException {
+                
+        clearValuesCache(p);
+
  RecordPos rec = findRecord(p);
         
  short l = ByteConversion.byteToShort(rec.page.data, rec.offset);
@@ -1724,6 +1787,12 @@
  rec.page.setDirty(true);
  }
 
+ public void update(Txn transaction, NodeImpl node, byte[] value)
+ throws ReadOnlyException {
+        clearAncestorValuesCache(node);
+        update(transaction, node.getInternalAddress(), value);
+    }
+    
  /**
  * Retrieve the string value of the specified node.
  *
@@ -1737,6 +1806,14 @@
  address = findValue(this, proxy);
  if (address == BTree.KEY_NOT_FOUND)
  return null;
+            
+ String value;
+
+            value = getValuesCache(address); //get value from cache, if cached ..
+            if (value!=null)
+                return value;
+            // ... otherwise calculate value
+            
  final RecordPos rec = findRecord(address);
  SanityCheck.THROW_ASSERT(rec != null,
  "Node data could not be found! Page: "
@@ -1746,12 +1823,15 @@
  final ByteArrayOutputStream os = new ByteArrayOutputStream();
  getNodeValue(os, rec, true, addWhitespace);
  final byte[] data = os.toByteArray();
- String value;
+            
  try {
  value = new String(data, "UTF-8");
  } catch (UnsupportedEncodingException e) {
  value = new String(data);
  }
+            
+            putValuesCache(address,value); //add value in cache
+            
  return value;
  } catch (BTreeException e) {
  LOG.warn("btree error while reading node value", e);

Index: eXist-1.0/src/org/exist/storage/NativeBroker.java
===================================================================
RCS file: /cvsroot/exist/eXist-1.0/src/org/exist/storage/NativeBroker.java,v
retrieving revision 1.195
diff -u -r1.195 NativeBroker.java
--- eXist-1.0/src/org/exist/storage/NativeBroker.java 4 Oct 2005 11:10:51 -0000 1.195
+++ eXist-1.0/src/org/exist/storage/NativeBroker.java 12 Oct 2005 10:14:08 -0000
@@ -1495,7 +1495,8 @@
 //                e1.printStackTrace();
 //            }
  // remember this for later remove
-    final long firstChild = doc.getFirstChildAddress();
+//    final long firstChild = doc.getFirstChildAddress();
+    final NodeImpl firstChild = (NodeImpl)doc.getFirstChild();
     
  // dropping old structure index
  elementIndex.dropIndex(doc);
@@ -2098,7 +2099,8 @@
                             domDb.removeOverflowValue(transaction, ((BinaryDocument)doc).getPage());
                         } else {
                             NodeImpl node = (NodeImpl)doc.getFirstChild();
-                            domDb.removeAll(transaction, node.getInternalAddress());
+//                            domDb.removeAll(transaction, node.getInternalAddress());
+                            domDb.removeAll(transaction, node);
                         }
                         return null;
                     }
@@ -2152,7 +2154,8 @@
  new DOMTransaction(this, domDb) {
  public Object start() {
     NodeImpl node = (NodeImpl)document.getFirstChild();
- domDb.removeAll(transaction, node.getInternalAddress());
+// domDb.removeAll(transaction, node.getInternalAddress());
+ domDb.removeAll(transaction, node);
  return null;
  }
  }
@@ -2222,18 +2225,21 @@
  final long gid = node.getGID();
  final short nodeType = node.getNodeType();
 // final String nodeName = node.getNodeName();
+
  new DOMTransaction(this, domDb, Lock.WRITE_LOCK, doc) {
  public Object start() {
  final long address = node.getInternalAddress();
  if (address > -1)
- domDb.remove(transaction, new NodeRef(doc.getDocId(), node.getGID()), address);
+ domDb.remove(transaction, new NodeRef(doc.getDocId(), node.getGID()), node);
  else
  domDb.remove(transaction, new NodeRef(doc.getDocId(), node.getGID()));
  return null;
  }
  }
  .run();
+        
  NodeProxy tempProxy = new NodeProxy(doc, gid, node.getInternalAddress());
+
  QName qname;
  switch (nodeType) {
  case Node.ELEMENT_NODE :
@@ -2941,7 +2947,7 @@
  new DOMTransaction(this, domDb, Lock.WRITE_LOCK) {
  public Object start() throws ReadOnlyException {
  if (-1 < internalAddress)
- domDb.update(transaction, internalAddress, data);
+ domDb.update(transaction, node, data);
  else {
  domDb.update(transaction, new NodeRef(doc.getDocId(), node.getGID()), data);
  }
@@ -2950,6 +2956,7 @@
  }
  .run();
  ByteArrayPool.releaseByteArray(data);
+            
  } catch (Exception e) {
     Value oldVal = domDb.get(node.getInternalAddress());
     NodeImpl old =