You are viewing a plain text version of this content. The canonical link for it is here.
Posted to xindice-dev@xml.apache.org by vg...@apache.org on 2006/11/10 01:32:22 UTC

svn commit: r473150 - in /xml/xindice/trunk/java: src/org/apache/xindice/core/filer/ tests/src/org/apache/xindice/core/filer/ tests/src/org/apache/xindice/core/query/

Author: vgritsenko
Date: Thu Nov  9 16:32:21 2006
New Revision: 473150

URL: http://svn.apache.org/viewvc?view=rev&rev=473150
Log:
Fix bug in unlinkPages for BTreeFiler - Paged.unlinkPages had HashFiler specific code.
Optimize for loops in BTree.

Added:
    xml/xindice/trunk/java/tests/src/org/apache/xindice/core/query/IndexedQueryTest.java   (with props)
Modified:
    xml/xindice/trunk/java/src/org/apache/xindice/core/filer/BTree.java
    xml/xindice/trunk/java/src/org/apache/xindice/core/filer/HashFiler.java
    xml/xindice/trunk/java/src/org/apache/xindice/core/filer/Paged.java
    xml/xindice/trunk/java/tests/src/org/apache/xindice/core/filer/BTreeFilerTest.java
    xml/xindice/trunk/java/tests/src/org/apache/xindice/core/filer/FilerTestBase.java

Modified: xml/xindice/trunk/java/src/org/apache/xindice/core/filer/BTree.java
URL: http://svn.apache.org/viewvc/xml/xindice/trunk/java/src/org/apache/xindice/core/filer/BTree.java?view=diff&rev=473150&r1=473149&r2=473150
==============================================================================
--- xml/xindice/trunk/java/src/org/apache/xindice/core/filer/BTree.java (original)
+++ xml/xindice/trunk/java/src/org/apache/xindice/core/filer/BTree.java Thu Nov  9 16:32:21 2006
@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  *
- * CVS $Id$
+ * $Id$
  */
 
 package org.apache.xindice.core.filer;
@@ -650,7 +650,7 @@
         /**
          * Do we need to split this node after adding one more value?
          */
-        private final boolean needSplit(Value value) {
+        private boolean needSplit(Value value) {
             // Do NOT split if just 4 key/values are in the node.
             return this.values.length > 4 &&
                    // CurrLength + one Long pointer + value length + one short
@@ -769,6 +769,7 @@
         public synchronized void query(IndexQuery query, BTreeCallback callback) throws IOException, BTreeException {
             if (query != null && query.getOperator() != IndexQuery.ANY) {
                 Value[] qvals = query.getValues();
+                int n;
                 int leftIdx = Arrays.binarySearch(values, qvals[0]);
                 int rightIdx = qvals.length > 1 ? Arrays.binarySearch(values, qvals[qvals.length - 1]) : leftIdx;
 
@@ -871,8 +872,9 @@
                                 if (rightIdx < 0) {
                                     rightIdx = -(rightIdx + 1);
                                 }
-                                for (int i = 0; i < ptrs.length; i++) { // FIXME: VG: Optimize this loop
-                                    if (i >= leftIdx && i <= rightIdx && query.testValue(values[i])) {
+                                n = Math.min(rightIdx + 1, ptrs.length);
+                                for (int i = leftIdx; i < n; i++){
+                                    if (query.testValue(values[i])) {
                                         callback.indexInfo(values[i], ptrs[i]);
                                     }
                                 }
@@ -881,6 +883,7 @@
                             case IndexQuery.NBWX:
                             case IndexQuery.NBW:
                             case IndexQuery.NSW:
+                                // FIXME: Looks like operators are not used now. Need query optimizer?
                                 if (leftIdx < 0) {
                                     leftIdx = -(leftIdx + 1);
                                 }
@@ -899,8 +902,9 @@
                                 if (leftIdx < 0) {
                                     leftIdx = -(leftIdx + 1);
                                 }
-                                for (int i = 0; i < ptrs.length; i++) {
-                                    if (i <= leftIdx && query.testValue(values[i])) {
+                                n = Math.min(leftIdx + 1, ptrs.length);
+                                for (int i = 0; i <= n; i++) {
+                                    if (query.testValue(values[i])) {
                                         callback.indexInfo(values[i], ptrs[i]);
                                     }
                                 }
@@ -912,8 +916,8 @@
                                     rightIdx = -(rightIdx + 1);
                                 }
 
-                                for (int i = 0; i < ptrs.length; i++) {
-                                    if (i >= rightIdx && query.testValue(values[i])) {
+                                for (int i = rightIdx; i < ptrs.length; i++) {
+                                    if (query.testValue(values[i])) {
                                         callback.indexInfo(values[i], ptrs[i]);
                                     }
                                 }

Modified: xml/xindice/trunk/java/src/org/apache/xindice/core/filer/HashFiler.java
URL: http://svn.apache.org/viewvc/xml/xindice/trunk/java/src/org/apache/xindice/core/filer/HashFiler.java?view=diff&rev=473150&r1=473149&r2=473150
==============================================================================
--- xml/xindice/trunk/java/src/org/apache/xindice/core/filer/HashFiler.java (original)
+++ xml/xindice/trunk/java/src/org/apache/xindice/core/filer/HashFiler.java Thu Nov  9 16:32:21 2006
@@ -232,6 +232,31 @@
         return true;
     }
 
+    /**
+     * Mark pages in primary store as 'DELETED', and let Paged handle all
+     * overflow pages.
+     */
+    protected void unlinkPages(Page page) throws IOException {
+        // Handle the page if it's in primary space by setting its status to
+        // DELETED and freeing any overflow pages linked to it.
+        if (page.getPageNum().longValue() < fileHeader.getPageCount()) {
+            long nextPage = page.getPageHeader().getNextPage();
+            page.getPageHeader().setStatus(DELETED);
+            page.getPageHeader().setNextPage(NO_PAGE);
+            page.write();
+
+            // If there are no chained pages, we are done.
+            if (nextPage == NO_PAGE) {
+                return;
+            }
+
+            // Free the chained pages from the page that was just removed
+            page = getPage(nextPage);
+        }
+
+        super.unlinkPages(page);
+    }
+
     public boolean deleteRecord(Key key) throws DBException {
         if (key == null || key.getLength() == 0) {
             return false;
@@ -291,10 +316,6 @@
     public RecordSet getRecordSet() throws DBException {
         checkOpened();
         return new HashFilerRecordSet();
-    }
-
-    public void flush() throws DBException {
-        super.flush();
     }
 
     /**

Modified: xml/xindice/trunk/java/src/org/apache/xindice/core/filer/Paged.java
URL: http://svn.apache.org/viewvc/xml/xindice/trunk/java/src/org/apache/xindice/core/filer/Paged.java?view=diff&rev=473150&r1=473149&r2=473150
==============================================================================
--- xml/xindice/trunk/java/src/org/apache/xindice/core/filer/Paged.java (original)
+++ xml/xindice/trunk/java/src/org/apache/xindice/core/filer/Paged.java Thu Nov  9 16:32:21 2006
@@ -476,50 +476,32 @@
      * @param page The starting Page to unlink
      * @throws IOException if an Exception occurs
      */
-    protected final void unlinkPages(Page page) throws IOException {
-        // Handle the page if it's in primary space by setting its status to
-        // DELETED and freeing any overflow pages linked to it.
-        if (page.pageNum.longValue() < fileHeader.pageCount) {
-            long nextPage = page.header.nextPage;
-            page.header.setStatus(DELETED);
-            page.header.setNextPage(NO_PAGE);
-            page.write();
-
-            // See if there are any chained pages from the page that was just removed
-            if (nextPage == NO_PAGE) {
-                page = null;
-            } else {
-                page = getPage(nextPage);
-            }
+    protected void unlinkPages(Page page) throws IOException {
+        // Add any overflow pages to the list of free pages.
+        // Get the first and last page in the chain.
+        long firstPage = page.pageNum.longValue();
+        while (page.header.nextPage != NO_PAGE) {
+            page = getPage(page.header.nextPage);
         }
+        long lastPage = page.pageNum.longValue();
 
-        // Add any overflow pages to the list of free pages.
-        if (page != null) {
-            // Get the first and last page in the chain.
-            long firstPage = page.pageNum.longValue();
-            while (page.header.nextPage != NO_PAGE) {
-                page = getPage(page.header.nextPage);
+        // Free the chain
+        synchronized (fileHeader) {
+            // If there are already some free pages, add the start of the chain
+            // to the list of free pages.
+            if (fileHeader.lastFreePage != NO_PAGE) {
+                Page p = getPage(fileHeader.lastFreePage);
+                p.header.setNextPage(firstPage);
+                p.write();
             }
-            long lastPage = page.pageNum.longValue();
 
-            // Free the chain
-            synchronized (fileHeader) {
-                // If there are already some free pages, add the start of the chain
-                // to the list of free pages.
-                if (fileHeader.lastFreePage != NO_PAGE) {
-                    Page p = getPage(fileHeader.lastFreePage);
-                    p.header.setNextPage(firstPage);
-                    p.write();
-                }
-
-                // Otherwise set the chain as the list of free pages.
-                if (fileHeader.firstFreePage == NO_PAGE) {
-                    fileHeader.setFirstFreePage(firstPage);
-                }
-
-                // Add a reference to the end of the chain.
-                fileHeader.setLastFreePage(lastPage);
+            // Otherwise set the chain as the list of free pages.
+            if (fileHeader.firstFreePage == NO_PAGE) {
+                fileHeader.setFirstFreePage(firstPage);
             }
+
+            // Add a reference to the end of the chain.
+            fileHeader.setLastFreePage(lastPage);
         }
     }
 

Modified: xml/xindice/trunk/java/tests/src/org/apache/xindice/core/filer/BTreeFilerTest.java
URL: http://svn.apache.org/viewvc/xml/xindice/trunk/java/tests/src/org/apache/xindice/core/filer/BTreeFilerTest.java?view=diff&rev=473150&r1=473149&r2=473150
==============================================================================
--- xml/xindice/trunk/java/tests/src/org/apache/xindice/core/filer/BTreeFilerTest.java (original)
+++ xml/xindice/trunk/java/tests/src/org/apache/xindice/core/filer/BTreeFilerTest.java Thu Nov  9 16:32:21 2006
@@ -13,18 +13,38 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  *
- * CVS $Id$
+ * $Id$
  */
 
 package org.apache.xindice.core.filer;
 
+import org.apache.xindice.core.data.Key;
+
 /**
- * @version CVS $Revision$, $Date$
+ *
+ * @version $Revision$, $Date$
  * @author <a href="mailto:vgritsenko@apache.org">Vadim Gritsenko</a>
  */
 public class BTreeFilerTest extends FilerTestBase {
 
     public BTreeFilerTest(String name) {
         super(name, new BTreeFiler());
+    }
+
+    /**
+     * Test to see if BTreeFiler reuses deleted pages.  
+     */
+    public void testFreePages() throws Exception {
+        long count = ((BTreeFiler) filer).getFileHeader().getTotalCount();
+        int iterations = 10;
+
+        Key key = new Key("key");
+        for (int i = 0; i < iterations; i++) {
+            assertTrue(filer.writeRecord(key, TEST_VALUE));
+            assertTrue(filer.deleteRecord(key));
+        }
+
+        // Check that file did not grow (much)
+        assertTrue(count + 1 >= ((BTreeFiler) filer).getFileHeader().getTotalCount());
     }
 }

Modified: xml/xindice/trunk/java/tests/src/org/apache/xindice/core/filer/FilerTestBase.java
URL: http://svn.apache.org/viewvc/xml/xindice/trunk/java/tests/src/org/apache/xindice/core/filer/FilerTestBase.java?view=diff&rev=473150&r1=473149&r2=473150
==============================================================================
--- xml/xindice/trunk/java/tests/src/org/apache/xindice/core/filer/FilerTestBase.java (original)
+++ xml/xindice/trunk/java/tests/src/org/apache/xindice/core/filer/FilerTestBase.java Thu Nov  9 16:32:21 2006
@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  *
- * CVS $Id$
+ * $Id$
  */
 
 package org.apache.xindice.core.filer;
@@ -34,7 +34,7 @@
 /**
  * Base class for filer test cases
  *
- * @version CVS $Revision$, $Date$
+ * @version $Revision$, $Date$
  * @author <a href="mailto:kstaken@xmldatabases.org">Kimbro Staken</a>
  * @author <a href="mailto:vladimir@apache.org">Vladimir R. Bossicard</a>
  * @author <a href="mailto:vgritsenko@apache.org">Vadim Gritsenko</a>
@@ -55,7 +55,7 @@
      */
     protected int LARGE_KEY_SIZE = 8192 + 32;
 
-    private Filer filer;
+    protected Filer filer;
 
 
     public FilerTestBase(String name, Filer filer) {

Added: xml/xindice/trunk/java/tests/src/org/apache/xindice/core/query/IndexedQueryTest.java
URL: http://svn.apache.org/viewvc/xml/xindice/trunk/java/tests/src/org/apache/xindice/core/query/IndexedQueryTest.java?view=auto&rev=473150
==============================================================================
--- xml/xindice/trunk/java/tests/src/org/apache/xindice/core/query/IndexedQueryTest.java (added)
+++ xml/xindice/trunk/java/tests/src/org/apache/xindice/core/query/IndexedQueryTest.java Thu Nov  9 16:32:21 2006
@@ -0,0 +1,79 @@
+package org.apache.xindice.core.query;
+
+import org.apache.xindice.core.Collection;
+import org.apache.xindice.core.Database;
+import org.apache.xindice.core.DatabaseTest;
+import org.apache.xindice.core.data.NodeSet;
+import org.apache.xindice.util.Configuration;
+import org.apache.xindice.xml.dom.DOMParser;
+
+import junit.framework.TestCase;
+import org.w3c.dom.Document;
+
+/**
+ * Tests indexed queries
+ *
+ * @version $Revision$, $Date$
+ */
+public class IndexedQueryTest extends TestCase {
+
+    private Database db;
+    private Collection collection;
+
+
+    public IndexedQueryTest(String name) {
+        super(name);
+    }
+
+    public void setUp() throws Exception {
+        String name = getClass().getName();
+        db = new Database();
+        db.setConfig(new Configuration(DOMParser.toDocument(DatabaseTest.DATABASE)));
+        collection = db.createCollection(name, new Configuration(
+                DOMParser.toDocument(
+                        "<collection compressed=\"true\" name=\"" + name + "\" inline-metadata=\"true\">" +
+                            "<filer class=\"org.apache.xindice.core.filer.BTreeFiler\" />" +
+                        "</collection>"), false
+        ));
+
+        String config = "<index name='Test' " +
+                        "       class='org.apache.xindice.core.indexer.ValueIndexer' " +
+                        "       pattern='test1' />";
+        collection.createIndexer(new Configuration(DOMParser.toDocument(config)));
+    }
+
+    public void tearDown() throws Exception {
+        db.dropCollection(collection);
+        db.close();
+    }
+
+    public void testStartsWithAndLTGTQuery() throws Exception {
+        int iterations = 10;
+        for (int i = 0; i < iterations; i++) {
+            Document document = DOMParser.toDocument("<test string='true'><test1>" + i +
+                                                     "</test1>This is a test document</test>");
+            collection.insertDocument("key" + i, document);
+        }
+
+        assertTrue(collection.getFiler().getRecordCount() == iterations);
+
+        XPathQueryResolver service = new XPathQueryResolver();
+        NodeSet result = service.query(collection, "//test1[starts-with(., '8')]", null, null);
+        int count = 0;
+        while (result.hasMoreNodes()) {
+            result.getNextNode();
+            count++;
+        }
+
+        assertEquals(1, count);
+
+        result = service.query(collection, "//test1[. < '8' or . > '8']", null, null);
+        count = 0;
+        while (result.hasMoreNodes()) {
+            result.getNextNode();
+            count++;
+        }
+
+        assertEquals(9, count);
+    }
+}

Propchange: xml/xindice/trunk/java/tests/src/org/apache/xindice/core/query/IndexedQueryTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: xml/xindice/trunk/java/tests/src/org/apache/xindice/core/query/IndexedQueryTest.java
------------------------------------------------------------------------------
    svn:keywords = Id Revision Author Date