You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by rm...@apache.org on 2011/05/14 15:51:59 UTC

svn commit: r1103112 [22/24] - in /lucene/dev/branches/flexscoring: ./ dev-tools/eclipse/ dev-tools/idea/.idea/ dev-tools/idea/lucene/contrib/ant/ dev-tools/idea/lucene/contrib/db/bdb-je/ dev-tools/idea/lucene/contrib/db/bdb/ dev-tools/idea/lucene/cont...

Modified: lucene/dev/branches/flexscoring/solr/src/java/org/apache/solr/schema/TrieField.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/flexscoring/solr/src/java/org/apache/solr/schema/TrieField.java?rev=1103112&r1=1103111&r2=1103112&view=diff
==============================================================================
--- lucene/dev/branches/flexscoring/solr/src/java/org/apache/solr/schema/TrieField.java (original)
+++ lucene/dev/branches/flexscoring/solr/src/java/org/apache/solr/schema/TrieField.java Sat May 14 13:51:35 2011
@@ -17,6 +17,8 @@
 package org.apache.solr.schema;
 
 import org.apache.lucene.document.Fieldable;
+import org.apache.lucene.document.Field;
+import org.apache.lucene.document.NumericField;
 import org.apache.lucene.search.*;
 import org.apache.lucene.search.cache.CachedArrayCreator;
 import org.apache.lucene.search.cache.DoubleValuesCreator;
@@ -40,17 +42,17 @@ import java.util.Map;
 import java.util.Date;
 
 /**
- * Provides field types to support for Lucene's Trie Range Queries.
+ * Provides field types to support for Lucene's {@link NumericField}.
  * See {@link org.apache.lucene.search.NumericRangeQuery} for more details.
  * It supports integer, float, long, double and date types.
  * <p/>
  * For each number being added to this field, multiple terms are generated as per the algorithm described in the above
- * link. The possible number of terms increases dramatically with higher precision steps (factor 2^precisionStep). For
+ * link. The possible number of terms increases dramatically with lower precision steps. For
  * the fast range search to work, trie fields must be indexed.
  * <p/>
  * Trie fields are sortable in numerical order and can be used in function queries.
  * <p/>
- * Note that if you use a precisionStep of 32 for int/float and 64 for long/double, then multiple terms will not be
+ * Note that if you use a precisionStep of 32 for int/float and 64 for long/double/date, then multiple terms will not be
  * generated, range search will be no faster than any other number field, but sorting will still be possible.
  *
  * @version $Id$
@@ -101,21 +103,28 @@ public class TrieField extends FieldType
 
   @Override
   public Object toObject(Fieldable f) {
-    byte[] arr = f.getBinaryValue();
-    if (arr==null) return badFieldString(f);
-    switch (type) {
-      case INTEGER:
-        return TrieFieldHelper.toInt(arr);
-      case FLOAT:
-        return TrieFieldHelper.toFloat(arr);
-      case LONG:
-        return TrieFieldHelper.toLong(arr);
-      case DOUBLE:
-        return TrieFieldHelper.toDouble(arr);
-      case DATE:
-        return new Date(TrieFieldHelper.toLong(arr));
-      default:
-        throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, "Unknown type for trie field: " + f.name());
+    if (f instanceof NumericField) {
+      final Number val = ((NumericField) f).getNumericValue();
+      if (val==null) return badFieldString(f);
+      return (type == TrieTypes.DATE) ? new Date(val.longValue()) : val;
+    } else {
+      // the following code is "deprecated" and only to support pre-3.2 indexes using the old BinaryField encoding:
+      final byte[] arr = f.getBinaryValue();
+      if (arr==null) return badFieldString(f);
+      switch (type) {
+        case INTEGER:
+          return toInt(arr);
+        case FLOAT:
+          return Float.intBitsToFloat(toInt(arr));
+        case LONG:
+          return toLong(arr);
+        case DOUBLE:
+          return Double.longBitsToDouble(toLong(arr));
+        case DATE:
+          return new Date(toLong(arr));
+        default:
+          throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, "Unknown type for trie field: " + f.name());
+      }
     }
   }
 
@@ -198,30 +207,7 @@ public class TrieField extends FieldType
 
   @Override
   public void write(TextResponseWriter writer, String name, Fieldable f) throws IOException {
-    byte[] arr = f.getBinaryValue();
-    if (arr==null) {
-      writer.writeStr(name, badFieldString(f),true);
-      return;
-    }
-    switch (type) {
-      case INTEGER:
-        writer.writeInt(name,TrieFieldHelper.toInt(arr));
-        break;
-      case FLOAT:
-        writer.writeFloat(name,TrieFieldHelper.toFloat(arr));
-        break;
-      case LONG:
-        writer.writeLong(name,TrieFieldHelper.toLong(arr));
-        break;
-      case DOUBLE:
-        writer.writeDouble(name,TrieFieldHelper.toDouble(arr));
-        break;
-      case DATE:
-        writer.writeDate(name,new Date(TrieFieldHelper.toLong(arr)));
-        break;
-      default:
-        throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, "Unknown type for trie field: " + f.name());
-    }
+    writer.writeVal(name, toObject(f));
   }
 
   @Override
@@ -290,6 +276,17 @@ public class TrieField extends FieldType
     return query;
   }
 
+  @Deprecated
+  static int toInt(byte[] arr) {
+    return (arr[0]<<24) | ((arr[1]&0xff)<<16) | ((arr[2]&0xff)<<8) | (arr[3]&0xff);
+  }
+  
+  @Deprecated
+  static long toLong(byte[] arr) {
+    int high = (arr[0]<<24) | ((arr[1]&0xff)<<16) | ((arr[2]&0xff)<<8) | (arr[3]&0xff);
+    int low = (arr[4]<<24) | ((arr[5]&0xff)<<16) | ((arr[6]&0xff)<<8) | (arr[7]&0xff);
+    return (((long)high)<<32) | (low&0x0ffffffffL);
+  }
 
   @Override
   public String storedToReadable(Fieldable f) {
@@ -341,22 +338,9 @@ public class TrieField extends FieldType
 
   @Override
   public String toExternal(Fieldable f) {
-    byte[] arr = f.getBinaryValue();
-    if (arr==null) return badFieldString(f);
-    switch (type) {
-      case INTEGER:
-        return Integer.toString(TrieFieldHelper.toInt(arr));
-      case FLOAT:
-        return Float.toString(TrieFieldHelper.toFloat(arr));
-      case LONG:
-        return Long.toString(TrieFieldHelper.toLong(arr));
-      case DOUBLE:
-        return Double.toString(TrieFieldHelper.toDouble(arr));
-      case DATE:
-        return dateField.formatDate(new Date(TrieFieldHelper.toLong(arr)));
-      default:
-        throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, "Unknown type for trie field: " + f.name());
-    }
+    return (type == TrieTypes.DATE)
+      ? dateField.toExternal((Date) toObject(f)) 
+      : toObject(f).toString();
   }
 
   @Override
@@ -372,7 +356,7 @@ public class TrieField extends FieldType
       case DOUBLE:
         return Double.toString( NumericUtils.sortableLongToDouble(NumericUtils.prefixCodedToLong(indexedForm)) );
       case DATE:
-        return dateField.formatDate( new Date(NumericUtils.prefixCodedToLong(indexedForm)) );
+        return dateField.toExternal( new Date(NumericUtils.prefixCodedToLong(indexedForm)) );
       default:
         throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, "Unknown type for trie field: " + type);
     }
@@ -397,7 +381,7 @@ public class TrieField extends FieldType
         s = Double.toString( NumericUtils.sortableLongToDouble(NumericUtils.prefixCodedToLong(indexedForm)) );
         break;
       case DATE:
-        s = dateField.formatDate( new Date(NumericUtils.prefixCodedToLong(indexedForm)) );
+        s = dateField.toExternal( new Date(NumericUtils.prefixCodedToLong(indexedForm)) );
         break;
       default:
         throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, "Unknown type for trie field: " + type);
@@ -426,59 +410,117 @@ public class TrieField extends FieldType
 
   @Override
   public String storedToIndexed(Fieldable f) {
-    // TODO: optimize to remove redundant string conversion
-    return readableToIndexed(storedToReadable(f));
+    final BytesRef bytes = new BytesRef(NumericUtils.BUF_SIZE_LONG);
+    if (f instanceof NumericField) {
+      final Number val = ((NumericField) f).getNumericValue();
+      if (val==null)
+        throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, "Invalid field contents: "+f.name());
+      switch (type) {
+        case INTEGER:
+          NumericUtils.intToPrefixCoded(val.intValue(), 0, bytes);
+          break;
+        case FLOAT:
+          NumericUtils.intToPrefixCoded(NumericUtils.floatToSortableInt(val.floatValue()), 0, bytes);
+          break;
+        case LONG: //fallthrough!
+        case DATE:
+          NumericUtils.longToPrefixCoded(val.longValue(), 0, bytes);
+          break;
+        case DOUBLE:
+          NumericUtils.longToPrefixCoded(NumericUtils.doubleToSortableLong(val.doubleValue()), 0, bytes);
+          break;
+        default:
+          throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, "Unknown type for trie field: " + f.name());
+      }
+    } else {
+      // the following code is "deprecated" and only to support pre-3.2 indexes using the old BinaryField encoding:
+      final byte[] arr = f.getBinaryValue();
+      if (arr==null)
+        throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, "Invalid field contents: "+f.name());
+      switch (type) {
+        case INTEGER:
+          NumericUtils.intToPrefixCoded(toInt(arr), 0, bytes);
+          break;
+        case FLOAT: {
+          // WARNING: Code Duplication! Keep in sync with o.a.l.util.NumericUtils!
+          // copied from NumericUtils to not convert to/from float two times
+          // code in next 2 lines is identical to: int v = NumericUtils.floatToSortableInt(Float.intBitsToFloat(toInt(arr)));
+          int v = toInt(arr);
+          if (v<0) v ^= 0x7fffffff;
+          NumericUtils.intToPrefixCoded(v, 0, bytes);
+          break;
+        }
+        case LONG: //fallthrough!
+        case DATE:
+          NumericUtils.longToPrefixCoded(toLong(arr), 0, bytes);
+          break;
+        case DOUBLE: {
+          // WARNING: Code Duplication! Keep in sync with o.a.l.util.NumericUtils!
+          // copied from NumericUtils to not convert to/from double two times
+          // code in next 2 lines is identical to: long v = NumericUtils.doubleToSortableLong(Double.longBitsToDouble(toLong(arr)));
+          long v = toLong(arr);
+          if (v<0) v ^= 0x7fffffffffffffffL;
+          NumericUtils.longToPrefixCoded(v, 0, bytes);
+          break;
+        }
+        default:
+          throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, "Unknown type for trie field: " + f.name());
+      }
+    }
+    return bytes.utf8ToString();
   }
 
   @Override
   public Fieldable createField(SchemaField field, Object value, float boost) {
-    TrieFieldHelper.FieldInfo info = new TrieFieldHelper.FieldInfo();
-    info.index = field.indexed();
-    info.store = field.stored();
-    info.precisionStep = precisionStep;
-    info.omitNorms = field.omitNorms();
-    info.omitTF = field.omitTf();
-    
-    if (!info.index && !info.store) {
+    boolean indexed = field.indexed();
+    boolean stored = field.stored();
+
+    if (!indexed && !stored) {
       if (log.isTraceEnabled())
         log.trace("Ignoring unindexed/unstored field: " + field);
       return null;
     }
 
+    final NumericField f = new NumericField(field.getName(), precisionStep, stored ? Field.Store.YES : Field.Store.NO, indexed);
     switch (type) {
       case INTEGER:
         int i = (value instanceof Number)
           ? ((Number)value).intValue()
           : Integer.parseInt(value.toString());
-        return TrieFieldHelper.createIntField(field.getName(), i, info, boost);
-
+        f.setIntValue(i);
+        break;
       case FLOAT:
-        float f = (value instanceof Number)
+        float fl = (value instanceof Number)
           ? ((Number)value).floatValue()
           : Float.parseFloat(value.toString());
-        return TrieFieldHelper.createFloatField(field.getName(), f, info, boost);
-        
+        f.setFloatValue(fl);
+        break;
       case LONG:
         long l = (value instanceof Number)
           ? ((Number)value).longValue()
           : Long.parseLong(value.toString());
-        return TrieFieldHelper.createLongField(field.getName(), l, info, boost);
-          
+        f.setLongValue(l);
+        break;
       case DOUBLE:
         double d = (value instanceof Number)
           ? ((Number)value).doubleValue()
           : Double.parseDouble(value.toString());
-        return TrieFieldHelper.createDoubleField(field.getName(), d, info, boost);
-        
+        f.setDoubleValue(d);
+        break;
       case DATE:
         Date date = (value instanceof Date)
           ? ((Date)value)
           : dateField.parseMath(null, value.toString());
-        return TrieFieldHelper.createDateField(field.getName(), date, info, boost);
-        
+        f.setLongValue(date.getTime());
+        break;
       default:
         throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, "Unknown type for trie field: " + type);
     }
+
+    f.setOmitNorms(field.omitNorms());
+    f.setOmitTermFreqAndPositions(field.omitTf());
+    f.setBoost(boost);
+    return f;
   }
 
   public enum TrieTypes {
@@ -498,14 +540,12 @@ public class TrieField extends FieldType
    * that indexes multiple precisions per value.
    */
   public static String getMainValuePrefix(FieldType ft) {
-    if (ft instanceof TrieDateField) {
-      int step = ((TrieDateField)ft).getPrecisionStep();
-      if (step <= 0 || step >=64) return null;
-      return LONG_PREFIX;
-    } else if (ft instanceof TrieField) {
-      TrieField trie = (TrieField)ft;
-      if (trie.precisionStep  == Integer.MAX_VALUE) return null;
-
+    if (ft instanceof TrieDateField)
+      ft = ((TrieDateField) ft).wrappedField;
+    if (ft instanceof TrieField) {
+      final TrieField trie = (TrieField)ft;
+      if (trie.precisionStep  == Integer.MAX_VALUE)
+        return null;
       switch (trie.type) {
         case INTEGER:
         case FLOAT:
@@ -539,6 +579,11 @@ class TrieDateFieldSource extends LongFi
   }
 
   @Override
+  public Object longToObject(long val) {
+    return new Date(val);
+  }
+
+  @Override
   public long externalToLong(String extVal) {
     return TrieField.dateField.parseMath(null, extVal).getTime();
   }

Modified: lucene/dev/branches/flexscoring/solr/src/java/org/apache/solr/search/BitDocSet.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/flexscoring/solr/src/java/org/apache/solr/search/BitDocSet.java?rev=1103112&r1=1103111&r2=1103112&view=diff
==============================================================================
--- lucene/dev/branches/flexscoring/solr/src/java/org/apache/solr/search/BitDocSet.java (original)
+++ lucene/dev/branches/flexscoring/solr/src/java/org/apache/solr/search/BitDocSet.java Sat May 14 13:51:35 2011
@@ -161,6 +161,16 @@ public class BitDocSet extends DocSetBas
   }
 
   @Override
+  public boolean intersects(DocSet other) {
+    if (other instanceof BitDocSet) {
+      return bits.intersects(((BitDocSet)other).bits);
+    } else {
+      // they had better not call us back!
+      return other.intersects(this);
+    }
+  }
+
+  @Override
   public int unionSize(DocSet other) {
     if (other instanceof BitDocSet) {
       // if we don't know our current size, this is faster than
@@ -184,6 +194,11 @@ public class BitDocSet extends DocSetBas
   }
 
   @Override
+  public void setBitsOn(OpenBitSet target) {
+    target.union(bits);
+  }
+
+  @Override
    public DocSet andNot(DocSet other) {
     OpenBitSet newbits = (OpenBitSet)(bits.clone());
      if (other instanceof BitDocSet) {
@@ -211,4 +226,9 @@ public class BitDocSet extends DocSetBas
   public long memSize() {
     return (bits.getBits().length << 3) + 16;
   }
+
+  @Override
+  protected BitDocSet clone() {
+    return new BitDocSet((OpenBitSet)bits.clone(), size);
+  }
 }

Modified: lucene/dev/branches/flexscoring/solr/src/java/org/apache/solr/search/DocSet.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/flexscoring/solr/src/java/org/apache/solr/search/DocSet.java?rev=1103112&r1=1103111&r2=1103112&view=diff
==============================================================================
--- lucene/dev/branches/flexscoring/solr/src/java/org/apache/solr/search/DocSet.java (original)
+++ lucene/dev/branches/flexscoring/solr/src/java/org/apache/solr/search/DocSet.java Sat May 14 13:51:35 2011
@@ -115,6 +115,9 @@ public interface DocSet /* extends Colle
    */
   public int intersectionSize(DocSet other);
 
+  /** Returns true if these sets have any elements in common */
+  public boolean intersects(DocSet other);
+
   /**
    * Returns the union of this set with another set.  Neither set is modified - a new DocSet is
    * created and returned.
@@ -146,6 +149,14 @@ public interface DocSet /* extends Colle
    * methods will be invoked with.
    */
   public Filter getTopFilter();
+
+  /**
+   * Takes the docs from this set and sets those bits on the target OpenBitSet.
+   * The target should be sized large enough to accommodate all of the documents before calling this method.
+   */
+  public void setBitsOn(OpenBitSet target);
+
+  public static DocSet EMPTY = new SortedIntDocSet(new int[0], 0);
 }
 
 /** A base class that may be usefull for implementing DocSets */
@@ -213,6 +224,17 @@ abstract class DocSetBase implements Doc
     return new BitDocSet(newbits);
   }
 
+  public boolean intersects(DocSet other) {
+    // intersection is overloaded in the smaller DocSets to be more
+    // efficient, so dispatch off of it instead.
+    if (!(other instanceof BitDocSet)) {
+      return other.intersects(this);
+    }
+    // less efficient way: get the intersection size
+    return intersectionSize(other) > 0;
+  }
+
+
   public DocSet union(DocSet other) {
     OpenBitSet newbits = (OpenBitSet)(this.getBits().clone());
     newbits.or(other.getBits());
@@ -295,6 +317,14 @@ abstract class DocSetBase implements Doc
       }
     };
   }
+
+  public void setBitsOn(OpenBitSet target) {
+    DocIterator iter = iterator();
+    while (iter.hasNext()) {
+      target.fastSet(iter.nextDoc());
+    }
+  }
+
 }
 
 

Modified: lucene/dev/branches/flexscoring/solr/src/java/org/apache/solr/search/DocSlice.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/flexscoring/solr/src/java/org/apache/solr/search/DocSlice.java?rev=1103112&r1=1103111&r2=1103112&view=diff
==============================================================================
--- lucene/dev/branches/flexscoring/solr/src/java/org/apache/solr/search/DocSlice.java (original)
+++ lucene/dev/branches/flexscoring/solr/src/java/org/apache/solr/search/DocSlice.java Sat May 14 13:51:35 2011
@@ -17,6 +17,8 @@
 
 package org.apache.solr.search;
 
+import java.util.Arrays;
+
 /**
  * <code>DocSlice</code> implements DocList as an array of docids and optional scores.
  *
@@ -141,4 +143,22 @@ public class DocSlice extends DocSetBase
     HashDocSet h = new HashDocSet(docs,offset,len);
     return h.intersectionSize(other);  
   }
+
+  @Override
+  public boolean intersects(DocSet other) {
+    if (other instanceof SortedIntDocSet || other instanceof HashDocSet) {
+      return other.intersects(this);
+    }
+    HashDocSet h = new HashDocSet(docs,offset,len);
+    return h.intersects(other);
+  }
+
+  @Override
+  protected DocSlice clone() {
+    try {
+      // DocSlice is not currently mutable
+      DocSlice slice = (DocSlice) super.clone();
+    } catch (CloneNotSupportedException e) {}
+    return null;
+  }
 }

Modified: lucene/dev/branches/flexscoring/solr/src/java/org/apache/solr/search/ExtendedDismaxQParserPlugin.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/flexscoring/solr/src/java/org/apache/solr/search/ExtendedDismaxQParserPlugin.java?rev=1103112&r1=1103111&r2=1103112&view=diff
==============================================================================
--- lucene/dev/branches/flexscoring/solr/src/java/org/apache/solr/search/ExtendedDismaxQParserPlugin.java (original)
+++ lucene/dev/branches/flexscoring/solr/src/java/org/apache/solr/search/ExtendedDismaxQParserPlugin.java Sat May 14 13:51:35 2011
@@ -238,6 +238,7 @@ class ExtendedDismaxQParser extends QPar
 
       try {
         up.setRemoveStopFilter(!stopwords);
+        up.exceptions = true;
         parsedUserQuery = up.parse(mainUserQuery);
 
         if (stopwords && isEmpty(parsedUserQuery)) {
@@ -247,6 +248,7 @@ class ExtendedDismaxQParser extends QPar
         }
       } catch (Exception e) {
         // ignore failure and reparse later after escaping reserved chars
+        up.exceptions = false;
       }
 
       if (parsedUserQuery != null && doMinMatched) {
@@ -785,12 +787,19 @@ class ExtendedDismaxQParser extends QPar
       RANGE
     }
 
+
+  static final RuntimeException unknownField = new RuntimeException("UnknownField");
+  static {
+    unknownField.fillInStackTrace();
+  }
+
   /**
    * A subclass of SolrQueryParser that supports aliasing fields for
    * constructing DisjunctionMaxQueries.
    */
   class ExtendedSolrQueryParser extends SolrQueryParser {
 
+
     /** A simple container for storing alias info
      */
     protected class Alias {
@@ -803,6 +812,7 @@ class ExtendedDismaxQParser extends QPar
     boolean allowWildcard=true;
     int minClauseSize = 0;    // minimum number of clauses per phrase query...
                               // used when constructing boosting part of query via sloppy phrases
+    boolean exceptions;  //  allow exceptions to be thrown (for example on a missing field)
 
     ExtendedAnalyzer analyzer;
 
@@ -982,6 +992,15 @@ class ExtendedDismaxQParser extends QPar
           return q;
         }
       } else {
+
+        // verify that a fielded query is actually on a field that exists... if not,
+        // then throw an exception to get us out of here, and we'll treat it like a
+        // literal when we try the escape+re-parse.
+        if (exceptions) {
+          FieldType ft = schema.getFieldTypeNoEx(field);
+          if (ft == null) throw unknownField;
+        }
+
         return getQuery();
       }
     }

Modified: lucene/dev/branches/flexscoring/solr/src/java/org/apache/solr/search/HashDocSet.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/flexscoring/solr/src/java/org/apache/solr/search/HashDocSet.java?rev=1103112&r1=1103111&r2=1103112&view=diff
==============================================================================
--- lucene/dev/branches/flexscoring/solr/src/java/org/apache/solr/search/HashDocSet.java (original)
+++ lucene/dev/branches/flexscoring/solr/src/java/org/apache/solr/search/HashDocSet.java Sat May 14 13:51:35 2011
@@ -48,6 +48,12 @@ public final class HashDocSet extends Do
 
   private final int mask;
 
+  public HashDocSet(HashDocSet set) {
+    this.table = set.table.clone();
+    this.size = set.size;
+    this.mask = set.mask;
+  }
+
   /** Create a HashDocSet from a list of *unique* ids */
   public HashDocSet(int[] docs, int offset, int len) {
     this(docs, offset, len, DEFAULT_INVERSE_LOAD_FACTOR);
@@ -207,6 +213,31 @@ public final class HashDocSet extends Do
 
   }
 
+  @Override
+  public boolean intersects(DocSet other) {
+   if (other instanceof HashDocSet) {
+     // set "a" to the smallest doc set for the most efficient
+     // intersection.
+     final HashDocSet a = size()<=other.size() ? this : (HashDocSet)other;
+     final HashDocSet b = size()<=other.size() ? (HashDocSet)other : this;
+
+     for (int i=0; i<a.table.length; i++) {
+       int id=a.table[i];
+       if (id >= 0 && b.exists(id)) {
+         return true;
+       }
+     }
+     return false;
+   } else {
+     for (int i=0; i<table.length; i++) {
+       int id=table[i];
+       if (id >= 0 && other.exists(id)) {
+         return true;
+       }
+     }
+     return false;
+   }
+  }
 
   @Override
   public DocSet andNot(DocSet other) {
@@ -249,6 +280,10 @@ public final class HashDocSet extends Do
    }
   }
 
+  @Override
+  protected HashDocSet clone() {
+    return new HashDocSet(this);
+  }
 
   // don't implement andNotSize() and unionSize() on purpose... they are implemented
   // in BaseDocSet in terms of intersectionSize().

Modified: lucene/dev/branches/flexscoring/solr/src/java/org/apache/solr/search/QParserPlugin.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/flexscoring/solr/src/java/org/apache/solr/search/QParserPlugin.java?rev=1103112&r1=1103111&r2=1103112&view=diff
==============================================================================
--- lucene/dev/branches/flexscoring/solr/src/java/org/apache/solr/search/QParserPlugin.java (original)
+++ lucene/dev/branches/flexscoring/solr/src/java/org/apache/solr/search/QParserPlugin.java Sat May 14 13:51:35 2011
@@ -40,6 +40,7 @@ public abstract class QParserPlugin impl
     FunctionRangeQParserPlugin.NAME, FunctionRangeQParserPlugin.class,
     SpatialFilterQParserPlugin.NAME, SpatialFilterQParserPlugin.class,
     SpatialBoxQParserPlugin.NAME, SpatialBoxQParserPlugin.class,
+    JoinQParserPlugin.NAME, JoinQParserPlugin.class,
   };
 
   /** return a {@link QParser} */

Modified: lucene/dev/branches/flexscoring/solr/src/java/org/apache/solr/search/QueryParsing.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/flexscoring/solr/src/java/org/apache/solr/search/QueryParsing.java?rev=1103112&r1=1103111&r2=1103112&view=diff
==============================================================================
--- lucene/dev/branches/flexscoring/solr/src/java/org/apache/solr/search/QueryParsing.java (original)
+++ lucene/dev/branches/flexscoring/solr/src/java/org/apache/solr/search/QueryParsing.java Sat May 14 13:51:35 2011
@@ -306,7 +306,7 @@ public class QueryParsing {
         Boolean top = sp.getSortDirection();
         if (null == top) {
             throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, 
-                                    "Can't determine Sort Order: " + sp);
+                                    "Can't determine a Sort Order (asc or desc) in sort spec " + sp);
         }
         
         if (SCORE.equals(field)) {
@@ -638,7 +638,11 @@ public class QueryParsing {
       }
 
       String v = val.substring(start,pos);
-      return flt ? Double.parseDouble(v) : Long.parseLong(v);
+      if (flt) {
+        return Double.parseDouble(v);
+      } else {
+        return Long.parseLong(v);
+      }
     }
 
     double getDouble() throws ParseException {
@@ -693,7 +697,8 @@ public class QueryParsing {
         pos++;
         while (pos < end) {
           ch = val.charAt(pos);
-          if (!Character.isJavaIdentifierPart(ch) && ch != '.' && ch != ':') {
+//          if (!Character.isJavaIdentifierPart(ch) && ch != '.' && ch != ':') {
+          if (!Character.isJavaIdentifierPart(ch) && ch != '.') {
             break;
           }
           pos++;

Modified: lucene/dev/branches/flexscoring/solr/src/java/org/apache/solr/search/ReturnFields.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/flexscoring/solr/src/java/org/apache/solr/search/ReturnFields.java?rev=1103112&r1=1103111&r2=1103112&view=diff
==============================================================================
--- lucene/dev/branches/flexscoring/solr/src/java/org/apache/solr/search/ReturnFields.java (original)
+++ lucene/dev/branches/flexscoring/solr/src/java/org/apache/solr/search/ReturnFields.java Sat May 14 13:51:35 2011
@@ -27,6 +27,7 @@ import org.apache.lucene.queryParser.Par
 import org.apache.lucene.search.Query;
 import org.apache.solr.common.SolrException;
 import org.apache.solr.common.params.CommonParams;
+import org.apache.solr.common.params.SolrParams;
 import org.apache.solr.common.util.NamedList;
 import org.apache.solr.core.SolrCore;
 import org.apache.solr.request.SolrQueryRequest;
@@ -89,12 +90,10 @@ public class ReturnFields
         parseFieldList( new String[]{fl}, req);
       }
     }
-    SolrCore.log.info("fields=" + fields + "\t globs="+globs + "\t transformer="+transformer);
   }
 
   public ReturnFields(String[] fl, SolrQueryRequest req) {
     parseFieldList(fl, req);
-    SolrCore.log.info("fields=" + fields + "\t globs="+globs + "\t transformer="+transformer);
   }
 
   private void parseFieldList(String[] fl, SolrQueryRequest req) {
@@ -161,7 +160,7 @@ public class ReturnFields
         char ch = sp.ch();
 
         if (field != null) {
-          if (sp.opt('=')) {
+          if (sp.opt(':')) {
             // this was a key, not a field name
             key = field;
             field = null;
@@ -179,7 +178,7 @@ public class ReturnFields
         }
 
         if (key != null) {
-          // we read "key = "
+          // we read "key : "
           field = sp.getId(null);
           ch = sp.ch();
           if (field != null && (ch==' ' || ch == ',' || ch==0)) {
@@ -194,7 +193,7 @@ public class ReturnFields
 
         if (field == null) {
           // We didn't find a simple name, so let's see if it's a globbed field name.
-          // Globbing only works with recommended field names.
+          // Globbing only works with field names of the recommended form (roughly like java identifiers)
 
           field = sp.getGlobbedId(null);
           ch = sp.ch();
@@ -259,6 +258,18 @@ public class ReturnFields
           }
 
           if (key==null) {
+            SolrParams localParams = parser.getLocalParams();
+            if (localParams != null) {
+              key = localParams.get("key");
+            }
+            if (key == null) {
+              // use the function name itself as the field name
+              key = sp.val.substring(start, sp.pos);
+            }
+          }
+
+
+          if (key==null) {
             key = funcStr;
           }
           okFieldNames.add( key );
@@ -292,7 +303,7 @@ public class ReturnFields
   private void addField( String field, String key, DocTransformers augmenters, SolrQueryRequest req )
   {
     String disp = (key==null) ? field : key;
-    fields.add( field ); // need to put in the map to maintain order for things like CSVResponseWriter
+    fields.add(field); // need to put in the map to maintain order for things like CSVResponseWriter
     okFieldNames.add( field );
     okFieldNames.add( key );
     // a valid field name

Modified: lucene/dev/branches/flexscoring/solr/src/java/org/apache/solr/search/SolrIndexSearcher.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/flexscoring/solr/src/java/org/apache/solr/search/SolrIndexSearcher.java?rev=1103112&r1=1103111&r2=1103112&view=diff
==============================================================================
--- lucene/dev/branches/flexscoring/solr/src/java/org/apache/solr/search/SolrIndexSearcher.java (original)
+++ lucene/dev/branches/flexscoring/solr/src/java/org/apache/solr/search/SolrIndexSearcher.java Sat May 14 13:51:35 2011
@@ -28,12 +28,17 @@ import org.apache.lucene.store.FSDirecto
 import org.apache.lucene.util.Bits;
 import org.apache.lucene.util.BytesRef;
 import org.apache.lucene.util.OpenBitSet;
+import org.apache.solr.common.params.ModifiableSolrParams;
 import org.apache.solr.common.util.NamedList;
 import org.apache.solr.common.util.SimpleOrderedMap;
 import org.apache.solr.core.SolrConfig;
 import org.apache.solr.core.SolrCore;
 import org.apache.solr.core.SolrInfoMBean;
+import org.apache.solr.request.LocalSolrQueryRequest;
+import org.apache.solr.request.SolrQueryRequest;
+import org.apache.solr.request.SolrRequestInfo;
 import org.apache.solr.request.UnInvertedField;
+import org.apache.solr.response.SolrQueryResponse;
 import org.apache.solr.schema.IndexSchema;
 import org.apache.solr.schema.SchemaField;
 import org.slf4j.Logger;
@@ -189,6 +194,10 @@ public class SolrIndexSearcher extends I
     return name;
   }
 
+  public SolrCore getCore() {
+    return core;
+  }
+
 
   /** Register sub-objects such as caches
    */
@@ -576,32 +585,6 @@ public class SolrIndexSearcher extends I
     return answer;
   }
 
-  /** lucene.internal */
-  public DocSet getDocSet(Query query, DocsEnumState deState) throws IOException {
-    // Get the absolute value (positive version) of this query.  If we
-    // get back the same reference, we know it's positive.
-    Query absQ = QueryUtils.getAbs(query);
-    boolean positive = query==absQ;
-
-    if (filterCache != null) {
-      DocSet absAnswer = filterCache.get(absQ);
-      if (absAnswer!=null) {
-        if (positive) return absAnswer;
-        else return getPositiveDocSet(matchAllDocsQuery).andNot(absAnswer);
-      }
-    }
-
-    DocSet absAnswer = getDocSetNC(absQ, null, deState);
-    DocSet answer = positive ? absAnswer : getPositiveDocSet(matchAllDocsQuery, deState).andNot(absAnswer);
-
-    if (filterCache != null) {
-      // cache negative queries as positive
-      filterCache.put(absQ, absAnswer);
-    }
-
-    return answer;
-  }
-
   // only handle positive (non negative) queries
   DocSet getPositiveDocSet(Query q) throws IOException {
     DocSet answer;
@@ -614,18 +597,6 @@ public class SolrIndexSearcher extends I
     return answer;
   }
 
-  // only handle positive (non negative) queries
-  DocSet getPositiveDocSet(Query q, DocsEnumState deState) throws IOException {
-    DocSet answer;
-    if (filterCache != null) {
-      answer = filterCache.get(q);
-      if (answer!=null) return answer;
-    }
-    answer = getDocSetNC(q,null,deState);
-    if (filterCache != null) filterCache.put(q,answer);
-    return answer;
-  }
-
   private static Query matchAllDocsQuery = new MatchAllDocsQuery();
 
   /**
@@ -756,21 +727,31 @@ public class SolrIndexSearcher extends I
 
   }
 
-  // query must be positive
-  protected DocSet getDocSetNC(Query query, DocSet filter, DocsEnumState deState) throws IOException {
-    if (filter != null) return getDocSetNC(query, filter, null);
+  /** lucene.internal */
+  public DocSet getDocSet(DocsEnumState deState) throws IOException {
+    int largestPossible = deState.termsEnum.docFreq();
+    boolean useCache = filterCache != null && largestPossible >= deState.minSetSizeCached;
+    TermQuery key = null;
+
+    if (useCache) {
+      key = new TermQuery(new Term(deState.fieldName, new BytesRef(deState.termsEnum.term()), false));
+      DocSet result = filterCache.get(key);
+      if (result != null) return result;
+    }
 
     int smallSetSize = maxDoc()>>6;
-    int largestPossible = deState.termsEnum.docFreq();
+    int scratchSize = Math.min(smallSetSize, largestPossible);
+    if (deState.scratch == null || deState.scratch.length < scratchSize)
+      deState.scratch = new int[scratchSize];
 
-    int[] docs = new int[Math.min(smallSetSize, largestPossible)];
+    final int[] docs = deState.scratch;
     int upto = 0;
     int bitsSet = 0;
     OpenBitSet obs = null;
 
-    DocsEnum docsEnum = deState.termsEnum.docs(deState.deletedDocs, deState.reuse);
-    if (deState.reuse == null) {
-      deState.reuse = docsEnum;
+    DocsEnum docsEnum = deState.termsEnum.docs(deState.deletedDocs, deState.docsEnum);
+    if (deState.docsEnum == null) {
+      deState.docsEnum = docsEnum;
     }
 
     if (docsEnum instanceof MultiDocsEnum) {
@@ -822,15 +803,22 @@ public class SolrIndexSearcher extends I
       }
     }
 
+    DocSet result;
     if (obs != null) {
       for (int i=0; i<upto; i++) {
         obs.fastSet(docs[i]);  
       }
       bitsSet += upto;
-      return new BitDocSet(obs, bitsSet);
+      result = new BitDocSet(obs, bitsSet);
+    } else {
+      result = new SortedIntDocSet(Arrays.copyOf(docs, upto));
     }
 
-    return new SortedIntDocSet(docs, upto);
+    if (useCache) {
+      filterCache.put(key, result);
+    }
+    
+    return result;
   }
 
   // query must be positive
@@ -1593,14 +1581,12 @@ public class SolrIndexSearcher extends I
     DocIterator iter = set.iterator();
     int base=0;
     int end=0;
-    int readerIndex = -1;
-    
-    AtomicReaderContext leaf = null;
+    int readerIndex = 0;
 
-    for (int i = 0; i < leafContexts.length; i++) {
+    while (iter.hasNext()) {
       int doc = iter.nextDoc();
       while (doc>=end) {
-        leaf = leafContexts[i++];
+        AtomicReaderContext leaf = leafContexts[readerIndex++];
         base = leaf.docBase;
         end = base + leaf.reader.maxDoc();
         topCollector.setNextReader(leaf);
@@ -1642,17 +1628,20 @@ public class SolrIndexSearcher extends I
   }
 
   /** @lucene.internal */
-  public int numDocs(Query a, DocSet b, DocsEnumState deState) throws IOException {
+  public int numDocs(DocSet a, DocsEnumState deState) throws IOException {
     // Negative query if absolute value different from original
-    Query absQ = QueryUtils.getAbs(a);
-    DocSet positiveA = getPositiveDocSet(absQ, deState);
-    return a==absQ ? b.intersectionSize(positiveA) : b.andNotSize(positiveA);
+    return a.intersectionSize(getDocSet(deState));
   }
 
   public static class DocsEnumState {
+    public String fieldName;  // currently interned for as long as lucene requires it
     public TermsEnum termsEnum;
     public Bits deletedDocs;
-    public DocsEnum reuse;
+    public DocsEnum docsEnum;
+
+    public int minSetSizeCached;
+
+    public int[] scratch;
   }
 
    /**
@@ -1708,9 +1697,29 @@ public class SolrIndexSearcher extends I
     boolean logme = log.isInfoEnabled();
     long warmingStartTime = System.currentTimeMillis();
     // warm the caches in order...
+    ModifiableSolrParams params = new ModifiableSolrParams();
+    params.add("warming","true");
     for (int i=0; i<cacheList.length; i++) {
       if (logme) log.info("autowarming " + this + " from " + old + "\n\t" + old.cacheList[i]);
-      this.cacheList[i].warm(this, old.cacheList[i]);
+
+
+      SolrQueryRequest req = new LocalSolrQueryRequest(core,params) {
+        @Override public SolrIndexSearcher getSearcher() { return SolrIndexSearcher.this; }
+        @Override public void close() { }
+      };
+
+      SolrQueryResponse rsp = new SolrQueryResponse();
+      SolrRequestInfo.setRequestInfo(new SolrRequestInfo(req, rsp));
+      try {
+        this.cacheList[i].warm(this, old.cacheList[i]);
+      } finally {
+        try {
+          req.close();
+        } finally {
+          SolrRequestInfo.clearRequestInfo();
+        }
+      }
+
       if (logme) log.info("autowarming result for " + this + "\n\t" + this.cacheList[i]);
     }
     warmupTime = System.currentTimeMillis() - warmingStartTime;

Modified: lucene/dev/branches/flexscoring/solr/src/java/org/apache/solr/search/SolrQueryParser.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/flexscoring/solr/src/java/org/apache/solr/search/SolrQueryParser.java?rev=1103112&r1=1103111&r2=1103112&view=diff
==============================================================================
--- lucene/dev/branches/flexscoring/solr/src/java/org/apache/solr/search/SolrQueryParser.java (original)
+++ lucene/dev/branches/flexscoring/solr/src/java/org/apache/solr/search/SolrQueryParser.java Sat May 14 13:51:35 2011
@@ -67,7 +67,7 @@ public class SolrQueryParser extends Que
   }
 
   public SolrQueryParser(QParser parser, String defaultField, Analyzer analyzer) {
-    super(parser.getReq().getCore().getSolrConfig().getLuceneVersion("luceneMatchVersion", Version.LUCENE_30), defaultField, analyzer);
+    super(parser.getReq().getCore().getSolrConfig().luceneMatchVersion, defaultField, analyzer);
     this.schema = parser.getReq().getSchema();
     this.parser = parser;
     this.defaultField = defaultField;

Modified: lucene/dev/branches/flexscoring/solr/src/java/org/apache/solr/search/SortedIntDocSet.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/flexscoring/solr/src/java/org/apache/solr/search/SortedIntDocSet.java?rev=1103112&r1=1103111&r2=1103112&view=diff
==============================================================================
--- lucene/dev/branches/flexscoring/solr/src/java/org/apache/solr/search/SortedIntDocSet.java (original)
+++ lucene/dev/branches/flexscoring/solr/src/java/org/apache/solr/search/SortedIntDocSet.java Sat May 14 13:51:35 2011
@@ -166,6 +166,59 @@ public class SortedIntDocSet extends Doc
     return icount;
   }
 
+
+  public static boolean intersects(int[] smallerSortedList, int[] biggerSortedList) {
+    // see intersectionSize for more in-depth comments of this algorithm
+
+    final int a[] = smallerSortedList;
+    final int b[] = biggerSortedList;
+
+    int step = (b.length/a.length)+1;
+
+    step = step + step;
+
+    int low = 0;
+    int max = b.length-1;
+
+    for (int i=0; i<a.length; i++) {
+      int doca = a[i];
+      int high = max;
+      int probe = low + step;
+      if (probe<high) {
+        if (b[probe]>=doca) {
+          high=probe;
+        } else {
+          low=probe+1;
+          probe = low + step;
+          if (probe<high) {
+            if (b[probe]>=doca) {
+              high=probe;
+            } else {
+              low=probe+1;
+            }
+          }
+        }
+      }
+
+      while (low <= high) {
+        int mid = (low+high) >>> 1;
+        int docb = b[mid];
+
+        if (docb < doca) {
+          low = mid+1;
+        }
+        else if (docb > doca) {
+          high = mid-1;
+        }
+        else {
+          return true;
+        }
+      }
+    }
+
+    return false;
+  }
+
   public int intersectionSize(DocSet other) {
     if (!(other instanceof SortedIntDocSet)) {
       // assume other implementations are better at random access than we are,
@@ -215,6 +268,49 @@ public class SortedIntDocSet extends Doc
     return icount;
   }
 
+  @Override
+  public boolean intersects(DocSet other) {
+    if (!(other instanceof SortedIntDocSet)) {
+      // assume other implementations are better at random access than we are,
+      // true of BitDocSet and HashDocSet.
+      for (int i=0; i<docs.length; i++) {
+        if (other.exists(docs[i])) return true;
+      }
+      return false;
+    }
+
+    // make "a" the smaller set.
+    int[] otherDocs = ((SortedIntDocSet)other).docs;
+    final int[] a = docs.length < otherDocs.length ? docs : otherDocs;
+    final int[] b = docs.length < otherDocs.length ? otherDocs : docs;
+
+    if (a.length==0) return false;
+
+    // if b is 8 times bigger than a, use the modified binary search.
+    if ((b.length>>3) >= a.length) {
+      return intersects(a,b);
+    }
+
+    // if they are close in size, just do a linear walk of both.
+    int i=0,j=0;
+    int doca=a[i],docb=b[j];
+    for(;;) {
+      // switch on the sign bit somehow?  Hopefull JVM is smart enough to just test once.
+
+      // Since set a is less dense then set b, doca is likely to be greater than docb so
+      // check that case first.  This resulted in a 13% speedup.
+      if (doca > docb) {
+        if (++j >= b.length) break;
+        docb=b[j];
+      } else if (doca < docb) {
+        if (++i >= a.length) break;
+        doca=a[i];
+      } else {
+        return true;
+      }
+    }
+    return false;
+  }
 
   /** puts the intersection of a and b into the target array and returns the size */
   public static int intersection(int a[], int lena, int b[], int lenb, int[] target) {
@@ -463,6 +559,13 @@ public class SortedIntDocSet extends Doc
     return new SortedIntDocSet(arr,sz);
   }
 
+  @Override
+  public void setBitsOn(OpenBitSet target) {
+    for (int doc : docs) {
+      target.fastSet(doc);
+    }
+  }
+
 
   public boolean exists(int doc) {
     // this could be faster by estimating where in the list the doc is likely to appear,
@@ -653,4 +756,8 @@ public class SortedIntDocSet extends Doc
     };
   }
 
+  @Override
+  protected SortedIntDocSet clone() {
+    return new SortedIntDocSet(docs.clone());
+  }
 }

Modified: lucene/dev/branches/flexscoring/solr/src/java/org/apache/solr/search/ValueSourceParser.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/flexscoring/solr/src/java/org/apache/solr/search/ValueSourceParser.java?rev=1103112&r1=1103111&r2=1103112&view=diff
==============================================================================
--- lucene/dev/branches/flexscoring/solr/src/java/org/apache/solr/search/ValueSourceParser.java (original)
+++ lucene/dev/branches/flexscoring/solr/src/java/org/apache/solr/search/ValueSourceParser.java Sat May 14 13:51:35 2011
@@ -335,6 +335,15 @@ public abstract class ValueSourceParser 
         return new StringDistanceFunction(str1, str2, dist);
       }
     });
+    addParser("field", new ValueSourceParser() {
+      @Override
+      public ValueSource parse(FunctionQParser fp) throws ParseException {
+
+        String fieldName = fp.parseArg();
+        SchemaField f = fp.getReq().getSchema().getField(fieldName);
+        return f.getType().getValueSource(f, fp);
+      }
+    });
 
     addParser(new DoubleParser("rad") {
       @Override
@@ -784,7 +793,7 @@ class LongConstValueSource extends Const
 
   @Override
   public DocValues getValues(Map context, AtomicReaderContext readerContext) throws IOException {
-    return new DocValues() {
+    return new LongDocValues(this) {
       @Override
       public float floatVal(int doc) {
         return fv;
@@ -806,11 +815,6 @@ class LongConstValueSource extends Const
       }
 
       @Override
-      public String strVal(int doc) {
-        return Long.toString(constant);
-      }
-
-      @Override
       public String toString(int doc) {
         return description();
       }
@@ -892,28 +896,12 @@ abstract class DoubleParser extends Name
     @Override
     public DocValues getValues(Map context, AtomicReaderContext readerContext) throws IOException {
       final DocValues vals =  source.getValues(context, readerContext);
-      return new DocValues() {
-        @Override
-        public float floatVal(int doc) {
-          return (float)doubleVal(doc);
-        }
-        @Override
-        public int intVal(int doc) {
-          return (int)doubleVal(doc);
-        }
-        @Override
-        public long longVal(int doc) {
-          return (long)doubleVal(doc);
-        }
+      return new DoubleDocValues(this) {
         @Override
         public double doubleVal(int doc) {
           return func(doc, vals);
         }
         @Override
-        public String strVal(int doc) {
-          return Double.toString(doubleVal(doc));
-        }
-        @Override
         public String toString(int doc) {
           return name() + '(' + vals.toString(doc) + ')';
         }
@@ -957,28 +945,12 @@ abstract class Double2Parser extends Nam
     public DocValues getValues(Map context, AtomicReaderContext readerContext) throws IOException {
       final DocValues aVals =  a.getValues(context, readerContext);
       final DocValues bVals =  b.getValues(context, readerContext);
-      return new DocValues() {
-        @Override
-        public float floatVal(int doc) {
-          return (float)doubleVal(doc);
-        }
-        @Override
-        public int intVal(int doc) {
-          return (int)doubleVal(doc);
-        }
-        @Override
-        public long longVal(int doc) {
-          return (long)doubleVal(doc);
-        }
-        @Override
+      return new DoubleDocValues(this) {
+         @Override
         public double doubleVal(int doc) {
           return func(doc, aVals, bVals);
         }
         @Override
-        public String strVal(int doc) {
-          return Double.toString(doubleVal(doc));
-        }
-        @Override
         public String toString(int doc) {
           return name() + '(' + aVals.toString(doc) + ',' + bVals.toString(doc) + ')';
         }

Modified: lucene/dev/branches/flexscoring/solr/src/java/org/apache/solr/search/function/ByteFieldSource.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/flexscoring/solr/src/java/org/apache/solr/search/function/ByteFieldSource.java?rev=1103112&r1=1103111&r2=1103112&view=diff
==============================================================================
--- lucene/dev/branches/flexscoring/solr/src/java/org/apache/solr/search/function/ByteFieldSource.java (original)
+++ lucene/dev/branches/flexscoring/solr/src/java/org/apache/solr/search/function/ByteFieldSource.java Sat May 14 13:51:35 2011
@@ -88,6 +88,11 @@ public class ByteFieldSource extends Num
         return description() + '=' + byteVal(doc);
       }
 
+      @Override
+      public Object objectVal(int doc) {
+        return arr[doc];  // TODO: valid?
+      }
+
     };
   }
 }

Modified: lucene/dev/branches/flexscoring/solr/src/java/org/apache/solr/search/function/ConstValueSource.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/flexscoring/solr/src/java/org/apache/solr/search/function/ConstValueSource.java?rev=1103112&r1=1103111&r2=1103112&view=diff
==============================================================================
--- lucene/dev/branches/flexscoring/solr/src/java/org/apache/solr/search/function/ConstValueSource.java (original)
+++ lucene/dev/branches/flexscoring/solr/src/java/org/apache/solr/search/function/ConstValueSource.java Sat May 14 13:51:35 2011
@@ -41,7 +41,7 @@ public class ConstValueSource extends Co
 
   @Override
   public DocValues getValues(Map context, AtomicReaderContext readerContext) throws IOException {
-    return new DocValues() {
+    return new FloatDocValues(this) {
       @Override
       public float floatVal(int doc) {
         return constant;
@@ -59,13 +59,13 @@ public class ConstValueSource extends Co
         return dv;
       }
       @Override
-      public String strVal(int doc) {
-        return Float.toString(constant);
-      }
-      @Override
       public String toString(int doc) {
         return description();
       }
+      @Override
+      public Object objectVal(int doc) {
+        return constant;
+      }
     };
   }
 

Modified: lucene/dev/branches/flexscoring/solr/src/java/org/apache/solr/search/function/DocFreqValueSource.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/flexscoring/solr/src/java/org/apache/solr/search/function/DocFreqValueSource.java?rev=1103112&r1=1103111&r2=1103112&view=diff
==============================================================================
--- lucene/dev/branches/flexscoring/solr/src/java/org/apache/solr/search/function/DocFreqValueSource.java (original)
+++ lucene/dev/branches/flexscoring/solr/src/java/org/apache/solr/search/function/DocFreqValueSource.java Sat May 14 13:51:35 2011
@@ -21,14 +21,13 @@ import org.apache.lucene.index.IndexRead
 import org.apache.lucene.index.Term;
 import org.apache.lucene.search.IndexSearcher;
 import org.apache.lucene.util.BytesRef;
-import org.apache.solr.search.MutableValueInt;
-import org.apache.solr.search.MutableValue;
+import org.apache.solr.search.*;
 
 import java.io.IOException;
 import java.util.Map;
 
 
-class ConstIntDocValues extends DocValues {
+class ConstIntDocValues extends IntDocValues {
   final int ival;
   final float fval;
   final double dval;
@@ -37,6 +36,7 @@ class ConstIntDocValues extends DocValue
   final ValueSource parent;
 
   ConstIntDocValues(int val, ValueSource parent) {
+    super(parent);
     ival = val;
     fval = val;
     dval = val;
@@ -71,7 +71,7 @@ class ConstIntDocValues extends DocValue
   }
 }
 
-class ConstDoubleDocValues extends DocValues {
+class ConstDoubleDocValues extends DoubleDocValues {
   final int ival;
   final float fval;
   final double dval;
@@ -80,6 +80,7 @@ class ConstDoubleDocValues extends DocVa
   final ValueSource parent;
 
   ConstDoubleDocValues(double val, ValueSource parent) {
+    super(parent);
     ival = (int)val;
     fval = (float)val;
     dval = val;
@@ -114,115 +115,6 @@ class ConstDoubleDocValues extends DocVa
   }
 }
 
-abstract class FloatDocValues extends DocValues {
-  protected final ValueSource vs;
-
-  public FloatDocValues(ValueSource vs) {
-    this.vs = vs;    
-  }
-
-  @Override
-  public byte byteVal(int doc) {
-    return (byte)floatVal(doc);
-  }
-
-  @Override
-  public short shortVal(int doc) {
-    return (short)floatVal(doc);
-  }
-
-  @Override
-  public abstract float floatVal(int doc);
-
-  @Override
-  public int intVal(int doc) {
-    return (int)floatVal(doc);
-  }
-
-  @Override
-  public long longVal(int doc) {
-    return (long)floatVal(doc);
-  }
-
-  @Override
-  public double doubleVal(int doc) {
-    return (double)floatVal(doc);
-  }
-
-  @Override
-  public String strVal(int doc) {
-    return Float.toString(floatVal(doc));
-  }
-
-  @Override
-  public String toString(int doc) {
-    return vs.description() + '=' + strVal(doc);
-  }
-}
-
-abstract class IntDocValues extends DocValues {
-  protected final ValueSource vs;
-
-  public IntDocValues(ValueSource vs) {
-    this.vs = vs;
-  }
-
-  @Override
-  public byte byteVal(int doc) {
-    return (byte)intVal(doc);
-  }
-
-  @Override
-  public short shortVal(int doc) {
-    return (short)intVal(doc);
-  }
-
-  @Override
-  public float floatVal(int doc) {
-    return (float)intVal(doc);
-  }
-
-  @Override
-  public abstract int intVal(int doc);
-
-  @Override
-  public long longVal(int doc) {
-    return (long)intVal(doc);
-  }
-
-  @Override
-  public double doubleVal(int doc) {
-    return (double)intVal(doc);
-  }
-
-  @Override
-  public String strVal(int doc) {
-    return Integer.toString(intVal(doc));
-  }
-
-  @Override
-  public String toString(int doc) {
-    return vs.description() + '=' + strVal(doc);
-  }
-
-  @Override
-  public ValueFiller getValueFiller() {
-    return new ValueFiller() {
-      private final MutableValueInt mval = new MutableValueInt();
-
-      @Override
-      public MutableValue getValue() {
-        return mval;
-      }
-
-      @Override
-      public void fillValue(int doc) {
-        mval.value = intVal(doc);
-      }
-    };
-  }
-}
-
 
 /**
  * <code>DocFreqValueSource</code> returns the number of documents containing the term.

Modified: lucene/dev/branches/flexscoring/solr/src/java/org/apache/solr/search/function/DocValues.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/flexscoring/solr/src/java/org/apache/solr/search/function/DocValues.java?rev=1103112&r1=1103111&r2=1103112&view=diff
==============================================================================
--- lucene/dev/branches/flexscoring/solr/src/java/org/apache/solr/search/function/DocValues.java (original)
+++ lucene/dev/branches/flexscoring/solr/src/java/org/apache/solr/search/function/DocValues.java Sat May 14 13:51:35 2011
@@ -19,6 +19,7 @@ package org.apache.solr.search.function;
 
 import org.apache.lucene.search.*;
 import org.apache.lucene.index.IndexReader;
+import org.apache.lucene.util.BytesRef;
 import org.apache.solr.search.MutableValue;
 import org.apache.solr.search.MutableValueFloat;
 
@@ -47,6 +48,28 @@ public abstract class DocValues {
   // TODO: should we make a termVal, returns BytesRef?
   public String strVal(int doc) { throw new UnsupportedOperationException(); }
 
+  /** returns the bytes representation of the string val - TODO: should this return the indexed raw bytes not? */
+  public boolean bytesVal(int doc, BytesRef target) {
+    String s = strVal(doc);
+    if (s==null) {
+      target.length = 0;
+      return false;
+    }
+    target.copy(s);
+    return true;
+  };
+
+  /** Native Java Object representation of the value */
+  public Object objectVal(int doc) {
+    // most DocValues are functions, so by default return a Float()
+    return floatVal(doc);
+  }
+
+  /** Returns true if there is a value for this document */
+  public boolean exists(int doc) {
+    return true;
+  }
+
   /**
    * @param doc The doc to retrieve to sort ordinal for
    * @return the sort ordinal for the specified doc

Modified: lucene/dev/branches/flexscoring/solr/src/java/org/apache/solr/search/function/DoubleConstValueSource.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/flexscoring/solr/src/java/org/apache/solr/search/function/DoubleConstValueSource.java?rev=1103112&r1=1103111&r2=1103112&view=diff
==============================================================================
--- lucene/dev/branches/flexscoring/solr/src/java/org/apache/solr/search/function/DoubleConstValueSource.java (original)
+++ lucene/dev/branches/flexscoring/solr/src/java/org/apache/solr/search/function/DoubleConstValueSource.java Sat May 14 13:51:35 2011
@@ -40,7 +40,7 @@ public class DoubleConstValueSource exte
 
   @Override
   public DocValues getValues(Map context, AtomicReaderContext readerContext) throws IOException {
-    return new DocValues() {
+    return new DoubleDocValues(this) {
       @Override
       public float floatVal(int doc) {
         return fv;
@@ -67,6 +67,11 @@ public class DoubleConstValueSource exte
       }
 
       @Override
+      public Object objectVal(int doc) {
+        return constant;
+      }
+
+      @Override
       public String toString(int doc) {
         return description();
       }

Modified: lucene/dev/branches/flexscoring/solr/src/java/org/apache/solr/search/function/DoubleFieldSource.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/flexscoring/solr/src/java/org/apache/solr/search/function/DoubleFieldSource.java?rev=1103112&r1=1103111&r2=1103112&view=diff
==============================================================================
--- lucene/dev/branches/flexscoring/solr/src/java/org/apache/solr/search/function/DoubleFieldSource.java (original)
+++ lucene/dev/branches/flexscoring/solr/src/java/org/apache/solr/search/function/DoubleFieldSource.java Sat May 14 13:51:35 2011
@@ -51,7 +51,7 @@ public class DoubleFieldSource extends N
   public DocValues getValues(Map context, AtomicReaderContext readerContext) throws IOException {
     final DoubleValues vals = cache.getDoubles(readerContext.reader, field, creator);
     final double[] arr = vals.values;
-	final Bits valid = vals.valid;
+    final Bits valid = vals.valid;
     
     return new DocValues() {
       @Override
@@ -80,6 +80,11 @@ public class DoubleFieldSource extends N
       }
 
       @Override
+      public Object objectVal(int doc) {
+        return valid.get(doc) ? arr[doc] : null;
+      }
+
+      @Override
       public String toString(int doc) {
         return description() + '=' + doubleVal(doc);
       }

Modified: lucene/dev/branches/flexscoring/solr/src/java/org/apache/solr/search/function/DualFloatFunction.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/flexscoring/solr/src/java/org/apache/solr/search/function/DualFloatFunction.java?rev=1103112&r1=1103111&r2=1103112&view=diff
==============================================================================
--- lucene/dev/branches/flexscoring/solr/src/java/org/apache/solr/search/function/DualFloatFunction.java (original)
+++ lucene/dev/branches/flexscoring/solr/src/java/org/apache/solr/search/function/DualFloatFunction.java Sat May 14 13:51:35 2011
@@ -48,28 +48,12 @@ public abstract class DualFloatFunction 
   public DocValues getValues(Map context, AtomicReaderContext readerContext) throws IOException {
     final DocValues aVals =  a.getValues(context, readerContext);
     final DocValues bVals =  b.getValues(context, readerContext);
-    return new DocValues() {
+    return new FloatDocValues(this) {
       @Override
       public float floatVal(int doc) {
 	return func(doc, aVals, bVals);
       }
       @Override
-      public int intVal(int doc) {
-        return (int)floatVal(doc);
-      }
-      @Override
-      public long longVal(int doc) {
-        return (long)floatVal(doc);
-      }
-      @Override
-      public double doubleVal(int doc) {
-        return floatVal(doc);
-      }
-      @Override
-      public String strVal(int doc) {
-        return Float.toString(floatVal(doc));
-      }
-      @Override
       public String toString(int doc) {
 	return name() + '(' + aVals.toString(doc) + ',' + bVals.toString(doc) + ')';
       }

Modified: lucene/dev/branches/flexscoring/solr/src/java/org/apache/solr/search/function/FileFloatSource.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/flexscoring/solr/src/java/org/apache/solr/search/function/FileFloatSource.java?rev=1103112&r1=1103111&r2=1103112&view=diff
==============================================================================
--- lucene/dev/branches/flexscoring/solr/src/java/org/apache/solr/search/function/FileFloatSource.java (original)
+++ lucene/dev/branches/flexscoring/solr/src/java/org/apache/solr/search/function/FileFloatSource.java Sat May 14 13:51:35 2011
@@ -65,35 +65,15 @@ public class FileFloatSource extends Val
     final int off = offset;
 
     final float[] arr = getCachedFloats(topLevelContext.reader);
-    return new DocValues() {
+    return new FloatDocValues(this) {
       @Override
       public float floatVal(int doc) {
         return arr[doc + off];
       }
 
       @Override
-      public int intVal(int doc) {
-        return (int)arr[doc + off];
-      }
-
-      @Override
-      public long longVal(int doc) {
-        return (long)arr[doc + off];
-      }
-
-      @Override
-      public double doubleVal(int doc) {
-        return (double)arr[doc + off];
-      }
-
-      @Override
-      public String strVal(int doc) {
-        return Float.toString(arr[doc + off]);
-      }
-
-      @Override
-      public String toString(int doc) {
-        return description() + '=' + floatVal(doc);
+      public Object objectVal(int doc) {
+        return floatVal(doc);   // TODO: keep track of missing values
       }
     };
   }

Modified: lucene/dev/branches/flexscoring/solr/src/java/org/apache/solr/search/function/FloatFieldSource.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/flexscoring/solr/src/java/org/apache/solr/search/function/FloatFieldSource.java?rev=1103112&r1=1103111&r2=1103112&view=diff
==============================================================================
--- lucene/dev/branches/flexscoring/solr/src/java/org/apache/solr/search/function/FloatFieldSource.java (original)
+++ lucene/dev/branches/flexscoring/solr/src/java/org/apache/solr/search/function/FloatFieldSource.java Sat May 14 13:51:35 2011
@@ -50,37 +50,22 @@ public class FloatFieldSource extends Nu
   public DocValues getValues(Map context, AtomicReaderContext readerContext) throws IOException {
     final FloatValues vals = cache.getFloats(readerContext.reader, field, creator);
     final float[] arr = vals.values;
-	final Bits valid = vals.valid;
+    final Bits valid = vals.valid;
     
-    return new DocValues() {
+    return new FloatDocValues(this) {
       @Override
       public float floatVal(int doc) {
         return arr[doc];
       }
 
       @Override
-      public int intVal(int doc) {
-        return (int)arr[doc];
+      public Object objectVal(int doc) {
+        return valid.get(doc) ? arr[doc] : null;
       }
 
       @Override
-      public long longVal(int doc) {
-        return (long)arr[doc];
-      }
-
-      @Override
-      public double doubleVal(int doc) {
-        return (double)arr[doc];
-      }
-
-      @Override
-      public String strVal(int doc) {
-        return Float.toString(arr[doc]);
-      }
-
-      @Override
-      public String toString(int doc) {
-        return description() + '=' + floatVal(doc);
+      public boolean exists(int doc) {
+        return valid.get(doc);
       }
 
       @Override

Modified: lucene/dev/branches/flexscoring/solr/src/java/org/apache/solr/search/function/IntFieldSource.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/flexscoring/solr/src/java/org/apache/solr/search/function/IntFieldSource.java?rev=1103112&r1=1103111&r2=1103112&view=diff
==============================================================================
--- lucene/dev/branches/flexscoring/solr/src/java/org/apache/solr/search/function/IntFieldSource.java (original)
+++ lucene/dev/branches/flexscoring/solr/src/java/org/apache/solr/search/function/IntFieldSource.java Sat May 14 13:51:35 2011
@@ -51,9 +51,9 @@ public class IntFieldSource extends Nume
   public DocValues getValues(Map context, AtomicReaderContext readerContext) throws IOException {
     final IntValues vals = cache.getInts(readerContext.reader, field, creator);
     final int[] arr = vals.values;
-	final Bits valid = vals.valid;
+    final Bits valid = vals.valid;
     
-    return new DocValues() {
+    return new IntDocValues(this) {
       final MutableValueInt val = new MutableValueInt();
       
       @Override
@@ -82,6 +82,16 @@ public class IntFieldSource extends Nume
       }
 
       @Override
+      public Object objectVal(int doc) {
+        return valid.get(doc) ? arr[doc] : null;
+      }
+
+      @Override
+      public boolean exists(int doc) {
+        return valid.get(doc);
+      }
+
+      @Override
       public String toString(int doc) {
         return description() + '=' + intVal(doc);
       }

Modified: lucene/dev/branches/flexscoring/solr/src/java/org/apache/solr/search/function/JoinDocFreqValueSource.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/flexscoring/solr/src/java/org/apache/solr/search/function/JoinDocFreqValueSource.java?rev=1103112&r1=1103111&r2=1103112&view=diff
==============================================================================
--- lucene/dev/branches/flexscoring/solr/src/java/org/apache/solr/search/function/JoinDocFreqValueSource.java (original)
+++ lucene/dev/branches/flexscoring/solr/src/java/org/apache/solr/search/function/JoinDocFreqValueSource.java Sat May 14 13:51:35 2011
@@ -54,7 +54,7 @@ public class JoinDocFreqValueSource exte
     final DocTerms terms = cache.getTerms(readerContext.reader, field, true );
     final IndexReader top = ReaderUtil.getTopLevelContext(readerContext).reader;
     
-    return new DocValues() {
+    return new IntDocValues(this) {
       BytesRef ref = new BytesRef();
 
       @Override
@@ -70,31 +70,6 @@ public class JoinDocFreqValueSource exte
           throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, "caught exception in function "+description()+" : doc="+doc, e);
         }
       }
-
-      @Override
-      public float floatVal(int doc) {
-        return (float)intVal(doc);
-      }
-
-      @Override
-      public long longVal(int doc) {
-        return (long)intVal(doc);
-      }
-
-      @Override
-      public double doubleVal(int doc) {
-        return (double)intVal(doc);
-      }
-
-      @Override
-      public String strVal(int doc) {
-        return intVal(doc) + "";
-      }
-
-      @Override
-      public String toString(int doc) {
-        return description() + '=' + intVal(doc);
-      }
     };
   }
   

Modified: lucene/dev/branches/flexscoring/solr/src/java/org/apache/solr/search/function/LinearFloatFunction.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/flexscoring/solr/src/java/org/apache/solr/search/function/LinearFloatFunction.java?rev=1103112&r1=1103111&r2=1103112&view=diff
==============================================================================
--- lucene/dev/branches/flexscoring/solr/src/java/org/apache/solr/search/function/LinearFloatFunction.java (original)
+++ lucene/dev/branches/flexscoring/solr/src/java/org/apache/solr/search/function/LinearFloatFunction.java Sat May 14 13:51:35 2011
@@ -50,28 +50,12 @@ public class LinearFloatFunction extends
   @Override
   public DocValues getValues(Map context, AtomicReaderContext readerContext) throws IOException {
     final DocValues vals =  source.getValues(context, readerContext);
-    return new DocValues() {
+    return new FloatDocValues(this) {
       @Override
       public float floatVal(int doc) {
         return vals.floatVal(doc) * slope + intercept;
       }
       @Override
-      public int intVal(int doc) {
-        return (int)floatVal(doc);
-      }
-      @Override
-      public long longVal(int doc) {
-        return (long)floatVal(doc);
-      }
-      @Override
-      public double doubleVal(int doc) {
-        return (double)floatVal(doc);
-      }
-      @Override
-      public String strVal(int doc) {
-        return Float.toString(floatVal(doc));
-      }
-      @Override
       public String toString(int doc) {
         return slope + "*float(" + vals.toString(doc) + ")+" + intercept;
       }

Modified: lucene/dev/branches/flexscoring/solr/src/java/org/apache/solr/search/function/LiteralValueSource.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/flexscoring/solr/src/java/org/apache/solr/search/function/LiteralValueSource.java?rev=1103112&r1=1103111&r2=1103112&view=diff
==============================================================================
--- lucene/dev/branches/flexscoring/solr/src/java/org/apache/solr/search/function/LiteralValueSource.java (original)
+++ lucene/dev/branches/flexscoring/solr/src/java/org/apache/solr/search/function/LiteralValueSource.java Sat May 14 13:51:35 2011
@@ -17,19 +17,23 @@ package org.apache.solr.search.function;
  */
 
 import org.apache.lucene.index.IndexReader.AtomicReaderContext;
+import org.apache.lucene.util.BytesRef;
 
 import java.util.Map;
 import java.io.IOException;
 
 
 /**
- * Pass a the field value through as a String, no matter the type
+ * Pass a the field value through as a String, no matter the type // Q: doesn't this mean it's a "string"?
  *
  **/
 public class LiteralValueSource extends ValueSource {
   protected final String string;
+  protected final BytesRef bytesRef;
+
   public LiteralValueSource(String string) {
     this.string = string;
+    this.bytesRef = new BytesRef(string);
   }
 
   /** returns the literal value */
@@ -40,13 +44,19 @@ public class LiteralValueSource extends 
   @Override
   public DocValues getValues(Map context, AtomicReaderContext readerContext) throws IOException {
 
-    return new DocValues() {
+    return new StrDocValues(this) {
       @Override
       public String strVal(int doc) {
         return string;
       }
 
       @Override
+      public boolean bytesVal(int doc, BytesRef target) {
+        target.copy(bytesRef);
+        return true;
+      }
+
+      @Override
       public String toString(int doc) {
         return string;
       }

Modified: lucene/dev/branches/flexscoring/solr/src/java/org/apache/solr/search/function/LongFieldSource.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/flexscoring/solr/src/java/org/apache/solr/search/function/LongFieldSource.java?rev=1103112&r1=1103111&r2=1103112&view=diff
==============================================================================
--- lucene/dev/branches/flexscoring/solr/src/java/org/apache/solr/search/function/LongFieldSource.java (original)
+++ lucene/dev/branches/flexscoring/solr/src/java/org/apache/solr/search/function/LongFieldSource.java Sat May 14 13:51:35 2011
@@ -52,41 +52,30 @@ public class LongFieldSource extends Num
     return Long.parseLong(extVal);
   }
 
+  public Object longToObject(long val) {
+    return val;
+  }
+
   @Override
   public DocValues getValues(Map context, AtomicReaderContext readerContext) throws IOException {
     final LongValues vals = cache.getLongs(readerContext.reader, field, creator);
     final long[] arr = vals.values;
-	final Bits valid = vals.valid;
+    final Bits valid = vals.valid;
     
-    return new DocValues() {
-      @Override
-      public float floatVal(int doc) {
-        return (float) arr[doc];
-      }
-
-      @Override
-      public int intVal(int doc) {
-        return (int) arr[doc];
-      }
-
+    return new LongDocValues(this) {
       @Override
       public long longVal(int doc) {
         return arr[doc];
       }
 
       @Override
-      public double doubleVal(int doc) {
-        return arr[doc];
+      public boolean exists(int doc) {
+        return valid.get(doc);
       }
 
       @Override
-      public String strVal(int doc) {
-        return Long.toString(arr[doc]);
-      }
-
-      @Override
-      public String toString(int doc) {
-        return description() + '=' + longVal(doc);
+      public Object objectVal(int doc) {
+        return valid.get(doc) ? longToObject(arr[doc]) : null;
       }
 
       @Override
@@ -142,8 +131,6 @@ public class LongFieldSource extends Num
         };
       }
 
-
-
     };
   }
 

Modified: lucene/dev/branches/flexscoring/solr/src/java/org/apache/solr/search/function/MultiFloatFunction.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/flexscoring/solr/src/java/org/apache/solr/search/function/MultiFloatFunction.java?rev=1103112&r1=1103111&r2=1103112&view=diff
==============================================================================
--- lucene/dev/branches/flexscoring/solr/src/java/org/apache/solr/search/function/MultiFloatFunction.java (original)
+++ lucene/dev/branches/flexscoring/solr/src/java/org/apache/solr/search/function/MultiFloatFunction.java Sat May 14 13:51:35 2011
@@ -62,28 +62,12 @@ public abstract class MultiFloatFunction
       valsArr[i] = sources[i].getValues(context, readerContext);
     }
 
-    return new DocValues() {
+    return new FloatDocValues(this) {
       @Override
       public float floatVal(int doc) {
         return func(doc, valsArr);
       }
-      @Override
-      public int intVal(int doc) {
-        return (int)floatVal(doc);
-      }
-      @Override
-      public long longVal(int doc) {
-        return (long)floatVal(doc);
-      }
-      @Override
-      public double doubleVal(int doc) {
-        return (double)floatVal(doc);
-      }
-      @Override
-      public String strVal(int doc) {
-        return Float.toString(floatVal(doc));
-      }
-      @Override
+       @Override
       public String toString(int doc) {
         StringBuilder sb = new StringBuilder();
         sb.append(name()).append('(');

Modified: lucene/dev/branches/flexscoring/solr/src/java/org/apache/solr/search/function/OrdFieldSource.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/flexscoring/solr/src/java/org/apache/solr/search/function/OrdFieldSource.java?rev=1103112&r1=1103111&r2=1103112&view=diff
==============================================================================
--- lucene/dev/branches/flexscoring/solr/src/java/org/apache/solr/search/function/OrdFieldSource.java (original)
+++ lucene/dev/branches/flexscoring/solr/src/java/org/apache/solr/search/function/OrdFieldSource.java Sat May 14 13:51:35 2011
@@ -63,53 +63,29 @@ public class OrdFieldSource extends Valu
     final int off = readerContext.docBase;
     final IndexReader topReader = ReaderUtil.getTopLevelContext(readerContext).reader;
     final FieldCache.DocTermsIndex sindex = FieldCache.DEFAULT.getTermsIndex(topReader, field);
-    return new DocValues() {
+    return new IntDocValues(this) {
       protected String toTerm(String readableValue) {
         return readableValue;
       }
-      
-      @Override
-      public float floatVal(int doc) {
-        return (float)sindex.getOrd(doc+off);
-      }
-
       @Override
       public int intVal(int doc) {
         return sindex.getOrd(doc+off);
       }
-
-      @Override
-      public long longVal(int doc) {
-        return (long)sindex.getOrd(doc+off);
-      }
-
-      @Override
-      public double doubleVal(int doc) {
-        return (double)sindex.getOrd(doc+off);
-      }
-
       @Override
       public int ordVal(int doc) {
         return sindex.getOrd(doc+off);
       }
-
       @Override
       public int numOrd() {
         return sindex.numOrd();
       }
 
       @Override
-      public String strVal(int doc) {
-        // the string value of the ordinal, not the string itself
-        return Integer.toString(sindex.getOrd(doc+off));
+      public boolean exists(int doc) {
+        return sindex.getOrd(doc+off) != 0;
       }
 
       @Override
-      public String toString(int doc) {
-        return description() + '=' + intVal(doc);
-      }
-
-            @Override
       public ValueFiller getValueFiller() {
         return new ValueFiller() {
           private final MutableValueInt mval = new MutableValueInt();

Modified: lucene/dev/branches/flexscoring/solr/src/java/org/apache/solr/search/function/QueryValueSource.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/flexscoring/solr/src/java/org/apache/solr/search/function/QueryValueSource.java?rev=1103112&r1=1103111&r2=1103112&view=diff
==============================================================================
--- lucene/dev/branches/flexscoring/solr/src/java/org/apache/solr/search/function/QueryValueSource.java (original)
+++ lucene/dev/branches/flexscoring/solr/src/java/org/apache/solr/search/function/QueryValueSource.java Sat May 14 13:51:35 2011
@@ -23,6 +23,8 @@ import org.apache.lucene.search.*;
 import org.apache.lucene.search.Weight.ScorerContext;
 import org.apache.lucene.util.ReaderUtil;
 import org.apache.solr.common.SolrException;
+import org.apache.solr.search.MutableValue;
+import org.apache.solr.search.MutableValueFloat;
 
 import java.io.IOException;
 import java.util.Map;
@@ -49,7 +51,7 @@ public class QueryValueSource extends Va
 
   @Override
   public DocValues getValues(Map fcontext, AtomicReaderContext readerContext) throws IOException {
-    return new QueryDocValues(readerContext, q, defVal, fcontext);
+    return new QueryDocValues(this, readerContext, fcontext);
   }
 
   @Override
@@ -72,31 +74,31 @@ public class QueryValueSource extends Va
 }
 
 
-class QueryDocValues extends DocValues {
-  final Query q;
-//  final IndexReader reader;
+class QueryDocValues extends FloatDocValues {
   final AtomicReaderContext readerContext;
   final Weight weight;
   final float defVal;
   final Map fcontext;
+  final Query q;
 
   Scorer scorer;
   int scorerDoc; // the document the scorer is on
+  boolean noMatches=false;
 
   // the last document requested... start off with high value
   // to trigger a scorer reset on first access.
   int lastDocRequested=Integer.MAX_VALUE;
   
 
-  public QueryDocValues(AtomicReaderContext readerContext, Query q, float defVal, Map fcontext) throws IOException {
-    IndexReader reader = readerContext.reader;
+  public QueryDocValues(QueryValueSource vs, AtomicReaderContext readerContext, Map fcontext) throws IOException {
+    super(vs);
+
     this.readerContext = readerContext;
-    this.q = q;
-    this.defVal = defVal;
+    this.defVal = vs.defVal;
+    this.q = vs.q;
     this.fcontext = fcontext;
 
     Weight w = fcontext==null ? null : (Weight)fcontext.get(q);
-    // TODO: sort by function doesn't weight (SOLR-1297 is open because of this bug)... so weightSearcher will currently be null
     if (w == null) {
       IndexSearcher weightSearcher;
       if(fcontext == null) {
@@ -116,8 +118,12 @@ class QueryDocValues extends DocValues {
   public float floatVal(int doc) {
     try {
       if (doc < lastDocRequested) {
+        if (noMatches) return defVal;
         scorer = weight.scorer(readerContext, ScorerContext.def());
-        if (scorer==null) return defVal;
+        if (scorer==null) {
+          noMatches = true;
+          return defVal;
+        }
         scorerDoc = -1;
       }
       lastDocRequested = doc;
@@ -137,24 +143,104 @@ class QueryDocValues extends DocValues {
     } catch (IOException e) {
       throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, "caught exception in QueryDocVals("+q+") doc="+doc, e);
     }
-  }  
-
-  @Override
-  public int intVal(int doc) {
-    return (int)floatVal(doc);
-  }
-  @Override
-  public long longVal(int doc) {
-    return (long)floatVal(doc);
   }
+
   @Override
-  public double doubleVal(int doc) {
-    return (double)floatVal(doc);
+  public boolean exists(int doc) {
+    try {
+      if (doc < lastDocRequested) {
+        if (noMatches) return false;
+        scorer = weight.scorer(readerContext, ScorerContext.def());
+        scorerDoc = -1;
+        if (scorer==null) {
+          noMatches = true;
+          return false;
+        }
+      }
+      lastDocRequested = doc;
+
+      if (scorerDoc < doc) {
+        scorerDoc = scorer.advance(doc);
+      }
+
+      if (scorerDoc > doc) {
+        // query doesn't match this document... either because we hit the
+        // end, or because the next doc is after this doc.
+        return false;
+      }
+
+      // a match!
+      return true;
+    } catch (IOException e) {
+      throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, "caught exception in QueryDocVals("+q+") doc="+doc, e);
+    }
   }
-  @Override
-  public String strVal(int doc) {
-    return Float.toString(floatVal(doc));
+
+   @Override
+  public Object objectVal(int doc) {
+     try {
+       return exists(doc) ? scorer.score() : null;
+     } catch (IOException e) {
+       throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, "caught exception in QueryDocVals("+q+") doc="+doc, e);
+     }
+   }
+
+  @Override
+  public ValueFiller getValueFiller() {
+    //
+    // TODO: if we want to support more than one value-filler or a value-filler in conjunction with
+    // the DocValues, then members like "scorer" should be per ValueFiller instance.
+    // Or we can say that the user should just instantiate multiple DocValues.
+    //
+    return new ValueFiller() {
+      private final MutableValueFloat mval = new MutableValueFloat();
+
+      @Override
+      public MutableValue getValue() {
+        return mval;
+      }
+
+      @Override
+      public void fillValue(int doc) {
+        try {
+          if (noMatches) {
+            mval.value = defVal;
+            mval.exists = false;
+            return;
+          }
+          scorer = weight.scorer(readerContext, ScorerContext.def());
+          scorerDoc = -1;
+          if (scorer==null) {
+            noMatches = true;
+            mval.value = defVal;
+            mval.exists = false;
+            return;
+          }
+          lastDocRequested = doc;
+
+          if (scorerDoc < doc) {
+            scorerDoc = scorer.advance(doc);
+          }
+
+          if (scorerDoc > doc) {
+            // query doesn't match this document... either because we hit the
+            // end, or because the next doc is after this doc.
+            mval.value = defVal;
+            mval.exists = false;
+            return;
+          }
+
+          // a match!
+          mval.value = scorer.score();
+          mval.exists = true;
+          return;
+        } catch (IOException e) {
+          throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, "caught exception in QueryDocVals("+q+") doc="+doc, e);
+        }
+      }
+    };
   }
+
   @Override
   public String toString(int doc) {
     return "query(" + q + ",def=" + defVal + ")=" + floatVal(doc);

Modified: lucene/dev/branches/flexscoring/solr/src/java/org/apache/solr/search/function/RangeMapFloatFunction.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/flexscoring/solr/src/java/org/apache/solr/search/function/RangeMapFloatFunction.java?rev=1103112&r1=1103111&r2=1103112&view=diff
==============================================================================
--- lucene/dev/branches/flexscoring/solr/src/java/org/apache/solr/search/function/RangeMapFloatFunction.java (original)
+++ lucene/dev/branches/flexscoring/solr/src/java/org/apache/solr/search/function/RangeMapFloatFunction.java Sat May 14 13:51:35 2011
@@ -54,29 +54,13 @@ public class RangeMapFloatFunction exten
   @Override
   public DocValues getValues(Map context, AtomicReaderContext readerContext) throws IOException {
     final DocValues vals =  source.getValues(context, readerContext);
-    return new DocValues() {
+    return new FloatDocValues(this) {
       @Override
       public float floatVal(int doc) {
         float val = vals.floatVal(doc);
         return (val>=min && val<=max) ? target : (defaultVal == null ? val : defaultVal);
       }
       @Override
-      public int intVal(int doc) {
-        return (int)floatVal(doc);
-      }
-      @Override
-      public long longVal(int doc) {
-        return (long)floatVal(doc);
-      }
-      @Override
-      public double doubleVal(int doc) {
-        return (double)floatVal(doc);
-      }
-      @Override
-      public String strVal(int doc) {
-        return Float.toString(floatVal(doc));
-      }
-      @Override
       public String toString(int doc) {
         return "map(" + vals.toString(doc) + ",min=" + min + ",max=" + max + ",target=" + target + ")";
       }

Modified: lucene/dev/branches/flexscoring/solr/src/java/org/apache/solr/search/function/ReciprocalFloatFunction.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/flexscoring/solr/src/java/org/apache/solr/search/function/ReciprocalFloatFunction.java?rev=1103112&r1=1103111&r2=1103112&view=diff
==============================================================================
--- lucene/dev/branches/flexscoring/solr/src/java/org/apache/solr/search/function/ReciprocalFloatFunction.java (original)
+++ lucene/dev/branches/flexscoring/solr/src/java/org/apache/solr/search/function/ReciprocalFloatFunction.java Sat May 14 13:51:35 2011
@@ -60,28 +60,12 @@ public class ReciprocalFloatFunction ext
   @Override
   public DocValues getValues(Map context, AtomicReaderContext readerContext) throws IOException {
     final DocValues vals = source.getValues(context, readerContext);
-    return new DocValues() {
+    return new FloatDocValues(this) {
       @Override
       public float floatVal(int doc) {
         return a/(m*vals.floatVal(doc) + b);
       }
       @Override
-      public int intVal(int doc) {
-        return (int)floatVal(doc);
-      }
-      @Override
-      public long longVal(int doc) {
-        return (long)floatVal(doc);
-      }
-      @Override
-      public double doubleVal(int doc) {
-        return (double)floatVal(doc);
-      }
-      @Override
-      public String strVal(int doc) {
-        return Float.toString(floatVal(doc));
-      }
-      @Override
       public String toString(int doc) {
         return Float.toString(a) + "/("
                 + m + "*float(" + vals.toString(doc) + ')'

Modified: lucene/dev/branches/flexscoring/solr/src/java/org/apache/solr/search/function/ReverseOrdFieldSource.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/flexscoring/solr/src/java/org/apache/solr/search/function/ReverseOrdFieldSource.java?rev=1103112&r1=1103111&r2=1103112&view=diff
==============================================================================
--- lucene/dev/branches/flexscoring/solr/src/java/org/apache/solr/search/function/ReverseOrdFieldSource.java (original)
+++ lucene/dev/branches/flexscoring/solr/src/java/org/apache/solr/search/function/ReverseOrdFieldSource.java Sat May 14 13:51:35 2011
@@ -66,47 +66,11 @@ public class ReverseOrdFieldSource exten
     final FieldCache.DocTermsIndex sindex = FieldCache.DEFAULT.getTermsIndex(topReader, field);
     final int end = sindex.numOrd();
 
-    return new DocValues() {
-      @Override
-      public float floatVal(int doc) {
-        return (float)(end - sindex.getOrd(doc+off));
-      }
-
-      @Override
+    return new IntDocValues(this) {
+     @Override
       public int intVal(int doc) {
         return (end - sindex.getOrd(doc+off));
       }
-
-      @Override
-      public long longVal(int doc) {
-        return (long)(end - sindex.getOrd(doc+off));
-      }
-
-      @Override
-      public int ordVal(int doc) {
-        return (end - sindex.getOrd(doc+off));
-      }
-
-      @Override
-      public int numOrd() {
-        return end;
-      }
-
-      @Override
-      public double doubleVal(int doc) {
-        return (double)(end - sindex.getOrd(doc+off));
-      }
-
-      @Override
-      public String strVal(int doc) {
-        // the string value of the ordinal, not the string itself
-        return Integer.toString((end - sindex.getOrd(doc+off)));
-      }
-
-      @Override
-      public String toString(int doc) {
-        return description() + '=' + strVal(doc);
-      }
     };
   }
 

Modified: lucene/dev/branches/flexscoring/solr/src/java/org/apache/solr/search/function/ScaleFloatFunction.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/flexscoring/solr/src/java/org/apache/solr/search/function/ScaleFloatFunction.java?rev=1103112&r1=1103111&r2=1103112&view=diff
==============================================================================
--- lucene/dev/branches/flexscoring/solr/src/java/org/apache/solr/search/function/ScaleFloatFunction.java (original)
+++ lucene/dev/branches/flexscoring/solr/src/java/org/apache/solr/search/function/ScaleFloatFunction.java Sat May 14 13:51:35 2011
@@ -108,28 +108,12 @@ public class ScaleFloatFunction extends 
 
     final DocValues vals =  source.getValues(context, readerContext);
 
-    return new DocValues() {
+    return new FloatDocValues(this) {
       @Override
       public float floatVal(int doc) {
 	return (vals.floatVal(doc) - minSource) * scale + min;
       }
       @Override
-      public int intVal(int doc) {
-        return (int)floatVal(doc);
-      }
-      @Override
-      public long longVal(int doc) {
-        return (long)floatVal(doc);
-      }
-      @Override
-      public double doubleVal(int doc) {
-        return (double)floatVal(doc);
-      }
-      @Override
-      public String strVal(int doc) {
-        return Float.toString(floatVal(doc));
-      }
-      @Override
       public String toString(int doc) {
 	return "scale(" + vals.toString(doc) + ",toMin=" + min + ",toMax=" + max
                 + ",fromMin=" + minSource