You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by ar...@apache.org on 2009/01/13 11:29:03 UTC

svn commit: r734092 - in /jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene: SharedFieldCache.java SharedFieldSortComparator.java

Author: ard
Date: Tue Jan 13 02:28:48 2009
New Revision: 734092

URL: http://svn.apache.org/viewvc?rev=734092&view=rev
Log:
JCR-1931 replacement of string arrays with hashmap in case of sparse array (<1% non null)

Modified:
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/SharedFieldCache.java
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/SharedFieldSortComparator.java

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/SharedFieldCache.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/SharedFieldCache.java?rev=734092&r1=734091&r2=734092&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/SharedFieldCache.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/SharedFieldCache.java Tue Jan 13 02:28:48 2009
@@ -43,6 +43,13 @@
     public static class StringIndex {
 
         /**
+         * Some heuristic factor that determines whether the array is sparse. Note that if less then
+         * 1% is set, we already count the array as sparse. This is because it will become memory consuming
+         * quickly by keeping the (sparse) arrays 
+         */
+        private static final int SPARSE_FACTOR = 100;
+
+        /**
          * All the term values, in natural order.
          */
         public final String[] lookup;
@@ -50,15 +57,65 @@
         /**
          * Terms indexed by document id.
          */
-        public final String[] terms;
+        private final String[] terms;
+
+        /**
+         * Terms map indexed by document id.
+         */
+        public final Map termsMap;
+
+        /**
+         * Boolean indicating whether the hashMap impl has to be used
+         */
+        public final boolean sparse;
 
         /**
          * Creates one of these objects
          */
-        public StringIndex(String[] terms, String[] lookup) {
-            this.terms = terms;
+        public StringIndex(String[] terms, String[] lookup, int setValues) {
+            if (isSparse(terms, setValues)) {
+                this.sparse = true;
+                this.terms = null;
+                if (setValues == 0) {
+                    this.termsMap = null;
+                } else {
+                    this.termsMap = getTermsMap(terms, setValues);
+                }
+            } else {
+                this.sparse = false;
+                this.terms = terms;
+                this.termsMap = null;
+            }
             this.lookup = lookup;
         }
+
+        public String getTerm(int i) {
+            if (sparse) {
+                return termsMap == null ? null : (String) termsMap.get(new Integer(i));
+            } else {
+                return terms[i];
+            }
+        }
+
+        private Map getTermsMap(String[] terms, int setValues) {
+            Map map = new HashMap(setValues);
+            for (int i = 0; i < terms.length && setValues > 0; i++) {
+                if (terms[i] != null) {
+                    map.put(new Integer(i), terms[i]);
+                    setValues--;
+                }
+            }
+            return map;
+        }
+
+        private boolean isSparse(String[] terms, int setValues) {
+            // some really simple test to test whether the array is sparse. Currently, when less then 1% is set, the array is already sparse 
+            // for this typical cache to avoid memory issues
+            if (setValues * SPARSE_FACTOR < terms.length) {
+                return true;
+            }
+            return false;
+        }
     }
 
     /**
@@ -114,6 +171,7 @@
             if (includeLookup) {
                 mterms = new ArrayList();
             }
+            int setValues = 0;
             if (retArray.length > 0) {
                 TermDocs termDocs = reader.termDocs();
                 TermEnum termEnum = reader.terms(new Term(field, prefix));
@@ -141,6 +199,7 @@
 
                         termDocs.seek(termEnum);
                         while (termDocs.next()) {
+                            setValues++;
                             retArray[termDocs.doc()] = term.text().substring(prefix.length());
                         }
                     } while (termEnum.next());
@@ -153,7 +212,7 @@
             if (includeLookup) {
                 lookup = (String[]) mterms.toArray(new String[mterms.size()]);
             }
-            SharedFieldCache.StringIndex value = new SharedFieldCache.StringIndex(retArray, lookup);
+            SharedFieldCache.StringIndex value = new SharedFieldCache.StringIndex(retArray, lookup, setValues);
             store(reader, field, prefix, comparator, value);
             return value;
         }

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/SharedFieldSortComparator.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/SharedFieldSortComparator.java?rev=734092&r1=734091&r2=734092&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/SharedFieldSortComparator.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/SharedFieldSortComparator.java Tue Jan 13 02:28:48 2009
@@ -117,8 +117,8 @@
                 int idx1 = readerIndex(i.doc);
                 int idx2 = readerIndex(j.doc);
 
-                String iTerm = indexes[idx1].terms[i.doc - starts[idx1]];
-                String jTerm = indexes[idx2].terms[j.doc - starts[idx2]];
+                String iTerm = indexes[idx1].getTerm(i.doc - starts[idx1]);
+                String jTerm = indexes[idx2].getTerm(j.doc - starts[idx2]);
 
                 if (iTerm == jTerm) {
                     return 0;
@@ -141,8 +141,8 @@
              */
             public Comparable sortValue(final ScoreDoc i) {
                 if (createComparatorValues) {
-                    StringIndex index = indexes[readerIndex(i.doc)];
-                    return index.terms[i.doc];
+                    int idx = readerIndex(i.doc);
+                    return indexes[idx].getTerm(i.doc - starts[idx]);
                 } else {
                     // return dummy value
                     return "";