You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by mi...@apache.org on 2014/11/17 01:43:47 UTC

svn commit: r1640053 [1/10] - in /lucene/dev/branches/lucene6005/lucene: core/src/java/org/apache/lucene/document/ core/src/java/org/apache/lucene/index/ core/src/test/org/apache/lucene/ core/src/test/org/apache/lucene/codecs/compressing/ core/src/test...

Author: mikemccand
Date: Mon Nov 17 00:43:44 2014
New Revision: 1640053

URL: http://svn.apache.org/r1640053
Log:
LUCENE-6005: checkpoint current changese

Added:
    lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/index/TestAbuseSchema.java   (with props)
    lucene/dev/branches/lucene6005/lucene/test-framework/src/java/org/apache/lucene/document/
    lucene/dev/branches/lucene6005/lucene/test-framework/src/java/org/apache/lucene/document/LowSchemaField.java   (with props)
Modified:
    lucene/dev/branches/lucene6005/lucene/core/src/java/org/apache/lucene/document/Document2.java
    lucene/dev/branches/lucene6005/lucene/core/src/java/org/apache/lucene/document/Document2StoredFieldVisitor.java
    lucene/dev/branches/lucene6005/lucene/core/src/java/org/apache/lucene/document/FieldTypes.java
    lucene/dev/branches/lucene6005/lucene/core/src/java/org/apache/lucene/index/BaseCompositeReader.java
    lucene/dev/branches/lucene6005/lucene/core/src/java/org/apache/lucene/index/CheckIndex.java
    lucene/dev/branches/lucene6005/lucene/core/src/java/org/apache/lucene/index/FieldInfos.java
    lucene/dev/branches/lucene6005/lucene/core/src/java/org/apache/lucene/index/IndexWriter.java
    lucene/dev/branches/lucene6005/lucene/core/src/java/org/apache/lucene/index/IndexableField.java
    lucene/dev/branches/lucene6005/lucene/core/src/java/org/apache/lucene/index/SegmentInfos.java
    lucene/dev/branches/lucene6005/lucene/core/src/java/org/apache/lucene/index/TrackingIndexWriter.java
    lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/TestExternalCodecs.java
    lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/codecs/compressing/TestCompressingStoredFieldsFormat.java
    lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/codecs/lucene50/TestBlockPostingsFormat3.java
    lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/codecs/perfield/TestPerFieldPostingsFormat2.java
    lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/document/TestDocument2.java
    lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/index/Test2BBinaryDocValues.java
    lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/index/Test2BNumericDocValues.java
    lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/index/Test2BPositions.java
    lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/index/Test2BPostings.java
    lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/index/Test2BSortedDocValues.java
    lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/index/Test4GBStoredFields.java
    lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/index/TestAddIndexes.java
    lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/index/TestAllFilesHaveChecksumFooter.java
    lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/index/TestAllFilesHaveCodecHeader.java
    lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/index/TestAtomicUpdate.java
    lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/index/TestBagOfPostings.java
    lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/index/TestBinaryDocValuesUpdates.java
    lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/index/TestBinaryTerms.java
    lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/index/TestCheckIndex.java
    lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/index/TestCodecHoldsOpenFiles.java
    lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/index/TestConcurrentMergeScheduler.java
    lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/index/TestConsistentFieldNumbers.java
    lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/index/TestCrash.java
    lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/index/TestCrashCausesCorruptIndex.java
    lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/index/TestDeletionPolicy.java
    lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/index/TestDirectoryReader.java
    lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/index/TestDirectoryReaderReopen.java
    lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/index/TestDoc.java
    lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/index/TestDocCount.java
    lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/index/TestDocInverterPerFieldErrorInfo.java
    lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/index/TestDocValuesIndexing.java
    lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/index/TestExceedMaxTermLength.java
    lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/index/TestExitableDirectoryReader.java
    lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/index/TestFilterLeafReader.java
    lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/index/TestFlex.java
    lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/index/TestForTooMuchCloning.java
    lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/index/TestIndexFileDeleter.java
    lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/index/TestIndexReaderClose.java
    lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/index/TestIndexWriter.java
    lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/index/TestIndexWriterCommit.java
    lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/index/TestIndexWriterConfig.java
    lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/index/TestIndexWriterDelete.java
    lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/index/TestIndexWriterExceptions.java
    lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/index/TestIndexWriterExceptions2.java
    lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/index/TestIndexWriterMaxDocs.java
    lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/index/TestIndexWriterMergePolicy.java
    lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/index/TestIndexWriterMerging.java
    lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/index/TestIndexWriterOnDiskFull.java
    lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/index/TestIndexWriterReader.java
    lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/index/TestIndexWriterThreadsToSegments.java
    lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/index/TestIndexWriterUnicode.java
    lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/index/TestIndexWriterWithThreads.java
    lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/index/TestIsCurrent.java
    lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/index/TestLazyProxSkipping.java
    lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/index/TestManyFields.java
    lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/index/TestMaxTermFrequency.java
    lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/index/TestMixedCodecs.java
    lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/index/TestMixedDocValuesUpdates.java
    lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/index/TestMultiDocValues.java
    lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/index/TestMultiFields.java
    lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/index/TestMultiLevelSkipList.java
    lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/index/TestNeverDelete.java
    lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/index/TestNoDeletionPolicy.java
    lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/index/TestNorms.java
    lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/index/TestNumericDocValuesUpdates.java
    lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/index/TestOmitNorms.java
    lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/index/TestOrdinalMap.java
    lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/index/TestParallelCompositeReader.java
    lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/index/TestParallelLeafReader.java
    lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/index/TestParallelReaderEmptyIndex.java
    lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/index/TestParallelTermEnum.java
    lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/index/TestPayloads.java
    lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/index/TestPayloadsOnVectors.java
    lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/index/TestPersistentSnapshotDeletionPolicy.java
    lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/index/TestPostingsOffsets.java
    lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/index/TestReaderClosed.java
    lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/index/TestRollback.java
    lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/index/TestSameTokenSamePosition.java
    lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/index/TestSegmentMerger.java
    lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/index/TestSegmentTermEnum.java
    lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/index/TestSizeBoundedForceMerge.java
    lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/index/TestSnapshotDeletionPolicy.java
    lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/index/TestStressAdvance.java
    lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/index/TestStressDeletes.java
    lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/index/TestStressIndexing.java
    lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/index/TestStressNRT.java
    lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/index/TestSumDocFreq.java
    lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/index/TestTermVectorsReader.java
    lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/index/TestTermVectorsWriter.java
    lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/index/TestTermdocPerf.java
    lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/index/TestTerms.java
    lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/index/TestTermsEnum.java
    lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/index/TestThreadedForceMerge.java
    lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/index/TestTieredMergePolicy.java
    lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/index/TestTransactionRollback.java
    lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/index/TestTransactions.java
    lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/index/TestTryDelete.java
    lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/index/TestUniqueAtom.java
    lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/index/TestUniqueTermCount.java
    lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/search/TestAutomatonQuery.java
    lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/search/TestBoolean2.java
    lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/search/TestBooleanOr.java
    lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/search/TestBooleanQueryVisitSubscorers.java
    lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/search/TestCachingWrapperFilter.java
    lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/search/TestControlledRealTimeReopenThread.java
    lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/search/TestDisjunctionMaxQuery.java
    lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/search/TestFieldCacheRangeFilter.java
    lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/search/TestFieldValueFilter.java
    lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/search/TestFilteredQuery.java
    lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/search/TestFuzzyQuery.java
    lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/search/TestPrefixRandom.java
    lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/search/TestQueryRescorer.java
    lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/search/TestQueryWrapperFilter.java
    lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/search/TestRegexpQuery.java
    lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/search/TestScorerPerf.java
    lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/search/TestSearchAfter.java
    lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/search/TestSimilarityProvider.java
    lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/search/TestSloppyPhraseQuery.java
    lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/search/TestSortRandom.java
    lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/search/TestSortRescorer.java
    lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/search/TestSortedSetSelector.java
    lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/search/TestSortedSetSortField.java
    lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/search/TestTermScorer.java
    lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/search/payloads/TestPayloadTermQuery.java
    lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/search/spans/TestSpanMultiTermQueryWrapper.java
    lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/search/spans/TestSpans.java
    lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/store/TestBufferedIndexInput.java
    lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/store/TestMultiMMap.java
    lucene/dev/branches/lucene6005/lucene/test-framework/src/java/org/apache/lucene/index/RandomIndexWriter.java
    lucene/dev/branches/lucene6005/lucene/test-framework/src/java/org/apache/lucene/search/QueryUtils.java
    lucene/dev/branches/lucene6005/lucene/test-framework/src/java/org/apache/lucene/util/LuceneTestCase.java

Modified: lucene/dev/branches/lucene6005/lucene/core/src/java/org/apache/lucene/document/Document2.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6005/lucene/core/src/java/org/apache/lucene/document/Document2.java?rev=1640053&r1=1640052&r2=1640053&view=diff
==============================================================================
--- lucene/dev/branches/lucene6005/lucene/core/src/java/org/apache/lucene/document/Document2.java (original)
+++ lucene/dev/branches/lucene6005/lucene/core/src/java/org/apache/lucene/document/Document2.java Mon Nov 17 00:43:44 2014
@@ -61,6 +61,12 @@ public class Document2 implements Iterab
     }
 
     public FieldValue(String fieldName, Object value, float boost) {
+      if (fieldName == null) {
+        throw new IllegalArgumentException("field name cannot be null");
+      }
+      if (value == null) {
+        throw new IllegalArgumentException("field=\"" + fieldName + "\": value cannot be null");
+      }
       this.fieldName = fieldName;
       this.value = value;
       this.boost = boost;
@@ -149,7 +155,6 @@ public class Document2 implements Iterab
       case DATE:
         return getReusedBinaryTokenStream(longToBytes(((Date) value).getTime()), reuse);
       case ATOM:
-      case UNIQUE_ATOM:
         if (fieldType.minTokenLength != null) {
           if (value instanceof String) {
             String s = (String) value;
@@ -305,7 +310,6 @@ public class Document2 implements Iterab
           return null;
         }
       case ATOM:
-      case UNIQUE_ATOM:
         if (value instanceof String) {
           return (String) value;
         } else {
@@ -367,6 +371,13 @@ public class Document2 implements Iterab
     this.changeSchema = changeSchema;
   }
 
+  private boolean enableExistsField = true;
+  
+  // nocommit only needed for dv updates ... is there a simple way?
+  public void disableExistsField() {
+    enableExistsField = false;
+  }
+
   @Override
   public Iterator<IndexableField> iterator() {
     if (fieldTypes != null) {
@@ -378,7 +389,7 @@ public class Document2 implements Iterab
       int fieldNamesIndex;
 
       public boolean hasNext() {
-        return index < fields.size() || (changeSchema && fieldTypes != null && fieldTypes.enableExistsFilters && fieldNamesIndex < fields.size());
+        return index < fields.size() || (enableExistsField && changeSchema && fieldTypes != null && fieldTypes.enableExistsFilters && fieldNamesIndex < fields.size());
       }
 
       public void remove() {
@@ -388,7 +399,7 @@ public class Document2 implements Iterab
       public IndexableField next() {
         if (index < fields.size()) {
           return fields.get(index++);
-        } else if (fieldTypes != null && changeSchema && fieldTypes.enableExistsFilters && fieldNamesIndex < fields.size()) {
+        } else if (enableExistsField && fieldTypes != null && changeSchema && fieldTypes.enableExistsFilters && fieldNamesIndex < fields.size()) {
           // nocommit make a more efficient version?  e.g. a single field that takes a list and iterates each via TokenStream.  maybe we
           // should addAtom(String...)?
           return new FieldValue(FieldTypes.FIELD_NAMES_FIELD, fields.get(fieldNamesIndex++).fieldName);
@@ -452,7 +463,7 @@ public class Document2 implements Iterab
   /** E.g. a primary key field. */
   public void addUniqueAtom(String fieldName, String value) {
     if (changeSchema) {
-      fieldTypes.recordValueType(fieldName, FieldTypes.ValueType.UNIQUE_ATOM);
+      fieldTypes.recordValueType(fieldName, FieldTypes.ValueType.ATOM, true);
     }
     fields.add(new FieldValue(fieldName, value));
   }
@@ -465,7 +476,7 @@ public class Document2 implements Iterab
   /** E.g. a primary key field. */
   public void addUniqueAtom(String fieldName, BytesRef value) {
     if (changeSchema) {
-      fieldTypes.recordValueType(fieldName, FieldTypes.ValueType.UNIQUE_ATOM);
+      fieldTypes.recordValueType(fieldName, FieldTypes.ValueType.ATOM, true);
     }
     fields.add(new FieldValue(fieldName, value));
   }
@@ -493,6 +504,15 @@ public class Document2 implements Iterab
     addStored(fieldName, new BytesRef(value));
   }
 
+  /** Default: store this value. */
+  public void addStored(String fieldName, String value) {
+    // nocommit akward we inferred large_text here?
+    if (changeSchema) {
+      fieldTypes.recordLargeTextType(fieldName, true, false);
+    }
+    fields.add(new FieldValue(fieldName, value));
+  }
+
   /** Default: store & DV this value. */
   public void addBinary(String fieldName, BytesRef value) {
     if (changeSchema) {
@@ -506,15 +526,6 @@ public class Document2 implements Iterab
     addBinary(fieldName, new BytesRef(value));
   }
 
-  /** Default: store this value. */
-  public void addStored(String fieldName, String value) {
-    // nocommit akward we inferred large_text here?
-    if (changeSchema) {
-      fieldTypes.recordLargeTextType(fieldName, true, false);
-    }
-    fields.add(new FieldValue(fieldName, value));
-  }
-
   /** E.g. a "body" field.  Default: indexes this value as multiple tokens from analyzer and stores the value. */
   public void addLargeText(String fieldName, String value) {
     addLargeText(fieldName, value, DEFAULT_BOOST);
@@ -565,6 +576,14 @@ public class Document2 implements Iterab
   }
 
   /** Default: support for range filtering/querying and sorting (using numeric doc values). */
+  public void addUniqueInt(String fieldName, int value) {
+    if (changeSchema) {
+      fieldTypes.recordValueType(fieldName, FieldTypes.ValueType.INT, true);
+    }
+    fields.add(new FieldValue(fieldName, Integer.valueOf(value)));
+  }
+
+  /** Default: support for range filtering/querying and sorting (using numeric doc values). */
   public void addFloat(String fieldName, float value) {
     if (changeSchema) {
       fieldTypes.recordValueType(fieldName, FieldTypes.ValueType.FLOAT);
@@ -581,6 +600,14 @@ public class Document2 implements Iterab
   }
 
   /** Default: support for range filtering/querying and sorting (using numeric doc values). */
+  public void addUniqueLong(String fieldName, long value) {
+    if (changeSchema) {
+      fieldTypes.recordValueType(fieldName, FieldTypes.ValueType.LONG, true);
+    }
+    fields.add(new FieldValue(fieldName, Long.valueOf(value)));
+  }
+
+  /** Default: support for range filtering/querying and sorting (using numeric doc values). */
   public void addDouble(String fieldName, double value) {
     if (changeSchema) {
       fieldTypes.recordValueType(fieldName, FieldTypes.ValueType.DOUBLE);
@@ -613,7 +640,7 @@ public class Document2 implements Iterab
 
   static {
     // nocommit is there a cleaner/general way to detect missing enum value in case switch statically?  must we use ecj?
-    assert FieldTypes.ValueType.values().length == 13: "missing case for switch statement below";
+    assert FieldTypes.ValueType.values().length == 12: "missing case for switch statement below";
   }
 
   /** Note: this FieldTypes must already know about all the fields in the incoming doc. */
@@ -638,13 +665,6 @@ public class Document2 implements Iterab
           addAtom(fieldName, (String) field.value);
         }
         break;
-      case UNIQUE_ATOM:
-        if (field.value instanceof BytesRef) {
-          addUniqueAtom(fieldName, (BytesRef) field.value);
-        } else {
-          addUniqueAtom(fieldName, (String) field.value);
-        }
-        break;
       case INT:
         addInt(fieldName, field.numericValue().intValue());
         break;
@@ -701,6 +721,19 @@ public class Document2 implements Iterab
     return token;
   }
 
+  // nocommit move elsewhere?
+  public static int bytesToInt(BytesRef bytes) {
+    if (bytes.length != 4) {
+      throw new IllegalArgumentException("incoming bytes should be length=4; got length=" + bytes.length);
+    }
+    int sortableBits = 0;
+    for(int i=0;i<4;i++) {
+      sortableBits = (sortableBits << 8) | bytes.bytes[bytes.offset + i] & 0xff;
+    }
+
+    return sortableBits ^ 0x80000000;
+  }
+
   static BytesRef longToBytes(long v) {
     long sortableBits = v ^ 0x8000000000000000L;
     BytesRef token = new BytesRef(8);
@@ -714,6 +747,29 @@ public class Document2 implements Iterab
     return token;
   }
 
+  // nocommit move elsewhere?
+  public static long bytesToLong(BytesRef bytes) {
+    if (bytes.length != 8) {
+      throw new IllegalArgumentException("incoming bytes should be length=8; got length=" + bytes.length);
+    }
+    long sortableBits = 0;
+    for(int i=0;i<8;i++) {
+      sortableBits = (sortableBits << 8) | bytes.bytes[bytes.offset + i] & 0xff;
+    }
+
+    return sortableBits ^ 0x8000000000000000L;
+  }
+
+  // nocommit move elsewhere?
+  public static float bytesToFloat(BytesRef bytes) {
+    return Float.intBitsToFloat(sortableFloatBits(bytesToInt(bytes)));
+  }
+
+  // nocommit move elsewhere?
+  public static double bytesToDouble(BytesRef bytes) {
+    return Double.longBitsToDouble(sortableDoubleBits(bytesToLong(bytes)));
+  }
+
   /** Converts IEEE 754 representation of a double to sortable order (or back to the original) */
   public static long sortableDoubleBits(long bits) {
     return bits ^ (bits >> 63) & 0x7fffffffffffffffL;

Modified: lucene/dev/branches/lucene6005/lucene/core/src/java/org/apache/lucene/document/Document2StoredFieldVisitor.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6005/lucene/core/src/java/org/apache/lucene/document/Document2StoredFieldVisitor.java?rev=1640053&r1=1640052&r2=1640053&view=diff
==============================================================================
--- lucene/dev/branches/lucene6005/lucene/core/src/java/org/apache/lucene/document/Document2StoredFieldVisitor.java (original)
+++ lucene/dev/branches/lucene6005/lucene/core/src/java/org/apache/lucene/document/Document2StoredFieldVisitor.java Mon Nov 17 00:43:44 2014
@@ -99,6 +99,7 @@ public class Document2StoredFieldVisitor
   public void intField(FieldInfo fieldInfo, int value) {
     FieldTypes.FieldType fieldType = getFieldType(fieldInfo.name);
     if (fieldType != null && fieldType.valueType == FieldTypes.ValueType.BOOLEAN) {
+      // nocommit real check?
       assert value == 0 || value == 1;
       doc.addBoolean(fieldInfo.name, Boolean.valueOf(value == 1));
     } else {

Modified: lucene/dev/branches/lucene6005/lucene/core/src/java/org/apache/lucene/document/FieldTypes.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6005/lucene/core/src/java/org/apache/lucene/document/FieldTypes.java?rev=1640053&r1=1640052&r2=1640053&view=diff
==============================================================================
--- lucene/dev/branches/lucene6005/lucene/core/src/java/org/apache/lucene/document/FieldTypes.java (original)
+++ lucene/dev/branches/lucene6005/lucene/core/src/java/org/apache/lucene/document/FieldTypes.java Mon Nov 17 00:43:44 2014
@@ -107,6 +107,13 @@ import org.apache.lucene.util.Version;
 
 // tie into highlighter
 // tie into faceting
+// tie into index sorting
+
+// nocommit run all monster tests
+
+// nocommit cutover AnalyzingInfixSuggester to binary atom for contexts
+
+// nocommit is it bad that you can no longer add e.g. a stored value separately from a custom token stream?
 
 // nocommit byte, short?
 
@@ -229,7 +236,6 @@ public class FieldTypes {
     TEXT,
     SHORT_TEXT,
     ATOM,  // nocommit binary sort of overlaps w/ this?
-    UNIQUE_ATOM,  // nocommit binary sort of overlaps w/ this?
     INT,
     FLOAT,
     LONG,
@@ -267,7 +273,7 @@ public class FieldTypes {
   private long changeCount;
 
   /** Just like current oal.document.FieldType, except for each setting it can also record "not-yet-set". */
-  static class FieldType implements IndexableFieldType {
+  static class FieldType implements IndexableFieldType, Cloneable {
     private final String name;
 
     // Lucene version when we were created:
@@ -282,10 +288,53 @@ public class FieldTypes {
       this.createdVersion = version;
     }
 
+    /** Copy constructor. */
+    FieldType(FieldType other) {
+      this.name = other.name;
+      this.createdVersion = other.createdVersion;
+      this.valueType = other.valueType;
+      this.docValuesType = other.docValuesType;
+      this.docValuesTypeSet = other.docValuesTypeSet;
+      this.isUnique = other.isUnique;
+      this.blockTreeMinItemsInBlock = other.blockTreeMinItemsInBlock;
+      this.blockTreeMaxItemsInBlock = other.blockTreeMaxItemsInBlock;
+      this.blockTreeMinItemsInAutoPrefix = other.blockTreeMinItemsInAutoPrefix;
+      this.blockTreeMaxItemsInAutoPrefix = other.blockTreeMaxItemsInAutoPrefix;
+      this.analyzerPositionGap = other.analyzerPositionGap;
+      this.analyzerOffsetGap = other.analyzerOffsetGap;
+      this.minTokenLength = other.minTokenLength;
+      this.maxTokenLength = other.maxTokenLength;
+      this.maxTokenCount = other.maxTokenCount;
+      this.stored = other.stored;
+      this.sortable = other.sortable;
+      this.sortReversed = other.sortReversed;
+      this.sortMissingLast = other.sortMissingLast;
+      this.fastRanges = other.fastRanges;
+      this.multiValued = other.multiValued;
+      this.indexNorms = other.indexNorms;
+      this.storeTermVectors = other.storeTermVectors;
+      this.storeTermVectorPositions = other.storeTermVectorPositions;
+      this.storeTermVectorOffsets = other.storeTermVectorOffsets;
+      this.storeTermVectorPayloads = other.storeTermVectorPayloads;
+      this.indexOptions = other.indexOptions;
+      this.indexOptionsSet = other.indexOptionsSet;
+      this.docValuesFormat = other.docValuesFormat;
+      this.postingsFormat = other.postingsFormat;
+      this.highlighted = other.highlighted;
+      this.queryAnalyzer = other.queryAnalyzer;
+      this.indexAnalyzer = other.indexAnalyzer;
+      this.similarity = other.similarity;
+      this.wrappedIndexAnalyzer = other.wrappedIndexAnalyzer;
+      this.wrappedQueryAnalyzer = other.wrappedQueryAnalyzer;
+    }
+
     volatile ValueType valueType = ValueType.NONE;
     volatile DocValuesType docValuesType = DocValuesType.NONE;
     private volatile boolean docValuesTypeSet;
 
+    // True if the term is unique across all documents (e.g. a primary key field):
+    volatile Boolean isUnique;
+
     // Expert: settings we pass to BlockTree to control how many terms are allowed in each block and auto-prefix term
     volatile Integer blockTreeMinItemsInBlock;
     volatile Integer blockTreeMaxItemsInBlock;
@@ -427,7 +476,6 @@ public class FieldTypes {
         }
         break;
       case ATOM:
-      case UNIQUE_ATOM:
         if (highlighted == Boolean.TRUE) {
           illegalState(name, "type " + valueType + " cannot highlight");
         }
@@ -443,14 +491,6 @@ public class FieldTypes {
         if (indexOptions != IndexOptions.NONE && indexOptions.compareTo(IndexOptions.DOCS) > 0) {
           illegalState(name, "type " + valueType + " can only be indexed as DOCS; got " + indexOptions);
         }
-        if (valueType == ValueType.UNIQUE_ATOM) {
-          if (indexOptions != IndexOptions.DOCS) {
-            illegalState(name, "type " + valueType + " must be indexed as DOCS; got " + indexOptions);
-          }
-          if (multiValued == Boolean.TRUE) {
-            illegalState(name, "type " + valueType + " cannot be multivalued");
-          }
-        }
         if (maxTokenCount != null) {
           illegalState(name, "type " + valueType + " cannot set max token count");
         }
@@ -502,28 +542,39 @@ public class FieldTypes {
         illegalState(name, "cannot sort when DocValuesType=" + docValuesType);
       }
 
-      if (indexOptions == IndexOptions.NONE) {
-        if (blockTreeMinItemsInBlock != null) {
-          illegalState(name, "can only setTermsDictBlockSize if the field is indexed");
-        }
-        if (blockTreeMinItemsInAutoPrefix != null) {
-          illegalState(name, "can only setTermsDictAutoPrefixSize if the field is indexed");
-        }
-        if (indexAnalyzer != null) {
-          illegalState(name, "can only setIndexAnalyzer if the field is indexed");
-        }
-        if (queryAnalyzer != null) {
-          illegalState(name, "can only setQueryAnalyzer if the field is indexed");
-        }
-        if (fastRanges == Boolean.TRUE) {
-          illegalState(name, "can only enableFastRanges if the field is indexed");
-        }
-      } else {
-        if (valueType != ValueType.TEXT && valueType != ValueType.SHORT_TEXT && indexAnalyzer != null) {
-          illegalState(name, "can only setIndexAnalyzer for short text and large text fields; got valueType=" + valueType);
-        }
-        if (valueType != ValueType.TEXT && valueType != ValueType.SHORT_TEXT && queryAnalyzer != null) {
-          illegalState(name, "can only setQueryAnalyzer for short text and large text fields; got valueType=" + valueType);
+      if (indexOptionsSet) {
+        if (indexOptions == IndexOptions.NONE) {
+          if (blockTreeMinItemsInBlock != null) {
+            illegalState(name, "can only setTermsDictBlockSize if the field is indexed");
+          }
+          if (blockTreeMinItemsInAutoPrefix != null) {
+            illegalState(name, "can only setTermsDictAutoPrefixSize if the field is indexed");
+          }
+          if (indexAnalyzer != null) {
+            illegalState(name, "can only setIndexAnalyzer if the field is indexed");
+          }
+          if (queryAnalyzer != null) {
+            illegalState(name, "can only setQueryAnalyzer if the field is indexed");
+          }
+          if (fastRanges == Boolean.TRUE) {
+            illegalState(name, "can only enableFastRanges if the field is indexed");
+          }
+          if (isUnique == Boolean.TRUE) {
+            illegalState(name, "can only setIsUnique if the field is indexed");
+          }
+          if (storeTermVectors == Boolean.TRUE) {
+            illegalState(name, "can only store term vectors if the field is indexed");
+          }
+        } else {
+          if (valueType != ValueType.TEXT && valueType != ValueType.SHORT_TEXT && indexAnalyzer != null) {
+            illegalState(name, "can only setIndexAnalyzer for short text and large text fields; got valueType=" + valueType);
+          }
+          if (valueType != ValueType.TEXT && valueType != ValueType.SHORT_TEXT && queryAnalyzer != null) {
+            illegalState(name, "can only setQueryAnalyzer for short text and large text fields; got valueType=" + valueType);
+          }
+          if (isUnique == Boolean.TRUE && indexOptions != IndexOptions.DOCS) {
+            illegalState(name, "unique fields should be indexed with IndexOptions.DOCS; got indexOptions=" + indexOptions);
+          }
         }
       }
 
@@ -637,15 +688,18 @@ public class FieldTypes {
       if (analyzerPositionGap != null) {
         b.append("  multi-valued position gap: ");
         b.append(analyzerPositionGap);
+        b.append('\n');
       }
 
       if (analyzerOffsetGap != null) {
         b.append("  multi-valued offset gap: ");
         b.append(analyzerOffsetGap);
+        b.append('\n');
       }
 
       if (multiValued == Boolean.TRUE) {
         b.append("  multiValued: true");
+        b.append('\n');
       }
 
       b.append("  stored: ");
@@ -715,15 +769,18 @@ public class FieldTypes {
         b.append("disabled");
       } else {
         b.append(indexOptions);
+        if (isUnique != null) {
+          b.append("\n  unique: " + isUnique);
+        }
         if (storeTermVectors == Boolean.TRUE) {
           b.append("\n  termVectors: yes");
-          if (storeTermVectorPositions) {
+          if (storeTermVectorPositions == Boolean.TRUE) {
             b.append(" positions");
             if (storeTermVectorPayloads) {
               b.append(" payloads");
             }
           }
-          if (storeTermVectorOffsets) {
+          if (storeTermVectorOffsets == Boolean.TRUE) {
             b.append(" offsets");
           }
         } else if (storeTermVectors == Boolean.FALSE) {
@@ -834,9 +891,6 @@ public class FieldTypes {
       case INET_ADDRESS:
         out.writeByte((byte) 11);
         break;
-      case UNIQUE_ATOM:
-        out.writeByte((byte) 12);
-        break;
       default:
         throw new AssertionError("missing ValueType in switch");
       }
@@ -890,6 +944,7 @@ public class FieldTypes {
       writeNullableBoolean(out, storeTermVectorPositions);
       writeNullableBoolean(out, storeTermVectorOffsets);
       writeNullableBoolean(out, storeTermVectorPayloads);
+      writeNullableBoolean(out, isUnique);
 
       if (indexOptionsSet == false) {
         assert indexOptions == IndexOptions.NONE;
@@ -1024,9 +1079,6 @@ public class FieldTypes {
       case 11:
         valueType = ValueType.INET_ADDRESS;
         break;
-      case 12:
-        valueType = ValueType.UNIQUE_ATOM;
-        break;
       default:
         throw new CorruptIndexException("invalid byte for ValueType: " + b, in);
       }
@@ -1086,6 +1138,7 @@ public class FieldTypes {
       storeTermVectorPositions = readNullableBoolean(in);
       storeTermVectorOffsets = readNullableBoolean(in);
       storeTermVectorPayloads = readNullableBoolean(in);
+      isUnique = readNullableBoolean(in);
 
       b = in.readByte();
       switch (b) {
@@ -1158,20 +1211,27 @@ public class FieldTypes {
     } else if (isNewIndex == false) {
       // nocommit must handle back compat here
       // throw new CorruptIndexException("FieldTypes is missing from this index", "CommitUserData");
+      System.out.println("  not new, null");
       enableExistsFilters = false;
       return Version.LATEST;
     } else {
-      FieldType fieldType = new FieldType(FIELD_NAMES_FIELD);
-      fields.put(FIELD_NAMES_FIELD, fieldType);
-      fieldType.multiValued = Boolean.TRUE;
-      fieldType.valueType = ValueType.ATOM;
-      fieldType.sortable = Boolean.TRUE;
-      fieldType.stored = Boolean.FALSE;
-      setDefaults(fieldType);
+      addFieldNamesField();
       return Version.LATEST;
     }
   }
 
+  private void addFieldNamesField() {
+    assert fields.containsKey(FIELD_NAMES_FIELD) == false;
+
+    FieldType fieldType = new FieldType(FIELD_NAMES_FIELD);
+    fields.put(FIELD_NAMES_FIELD, fieldType);
+    fieldType.multiValued = Boolean.TRUE;
+    fieldType.valueType = ValueType.ATOM;
+    fieldType.sortable = Boolean.FALSE;
+    fieldType.stored = Boolean.FALSE;
+    setDefaults(fieldType);
+  }
+
   private synchronized FieldType newFieldType(String fieldName) {
     if (fieldName.equals(FIELD_NAMES_FIELD)) {
       throw new IllegalArgumentException("field name \"" + fieldName + "\" is reserved");
@@ -2154,8 +2214,8 @@ public class FieldTypes {
   }
 
   public synchronized void enableTermVectorOffsets(String fieldName) {
-    FieldType current = getFieldType(fieldName);
-    if (current.storeTermVectors != Boolean.TRUE) {
+    FieldType current = fields.get(fieldName);
+    if (current == null || current.storeTermVectors != Boolean.TRUE) {
       // nocommit we could enable term vectors for you?
       illegalState(fieldName, "cannot enable termVectorOffsets when termVectors haven't been enabled");
     }
@@ -2180,8 +2240,8 @@ public class FieldTypes {
   }
 
   public synchronized void enableTermVectorPositions(String fieldName) {
-    FieldType current = getFieldType(fieldName);
-    if (current.storeTermVectors != Boolean.TRUE) {
+    FieldType current = fields.get(fieldName);
+    if (current == null || current.storeTermVectors != Boolean.TRUE) {
       // nocommit we could enable term vectors for you?
       illegalState(fieldName, "cannot enable termVectorPositions when termVectors haven't been enabled");
     }
@@ -2206,11 +2266,14 @@ public class FieldTypes {
   }
 
   public synchronized void enableTermVectorPayloads(String fieldName) {
-    FieldType current = getFieldType(fieldName);
-    if (current.storeTermVectors != Boolean.TRUE) {
+    FieldType current = fields.get(fieldName);
+    if (current == null || current.storeTermVectors != Boolean.TRUE) {
       // nocommit we could enable term vectors / positions for you?
       illegalState(fieldName, "cannot enable termVectorPayloads when termVectors haven't been enabled");
     }
+    if (current.storeTermVectorPositions != Boolean.TRUE) {
+      illegalState(fieldName, "cannot enable termVectorPayloads when termVectorPositions haven't been enabled");
+    }
     if (current.storeTermVectorPayloads != Boolean.TRUE) {
       // nocommit should this change not be allowed...
       current.storeTermVectorPayloads = Boolean.TRUE;
@@ -2284,6 +2347,10 @@ public class FieldTypes {
     }
   }
 
+  public synchronized void disableDocValues(String fieldName) {
+    setDocValuesType(fieldName, DocValuesType.NONE);
+  }
+
   public synchronized void setDocValuesType(String fieldName, DocValuesType dvType) {
     ensureWritable();
     if (dvType == null) {
@@ -2328,31 +2395,46 @@ public class FieldTypes {
   }
 
   synchronized void recordValueType(String fieldName, ValueType valueType) {
+    recordValueType(fieldName, valueType, false);
+  }
+
+  synchronized void recordValueType(String fieldName, ValueType valueType, boolean isUnique) {
     ensureWritable();
     indexedDocs = true;
     FieldType current = fields.get(fieldName);
     if (current == null) {
       current = newFieldType(fieldName);
       current.valueType = valueType;
+      current.isUnique = isUnique;
       fields.put(fieldName, current);
       setDefaults(current);
       changed();
     } else if (current.valueType == ValueType.NONE) {
+      if (current.isUnique != null && current.isUnique.booleanValue() != isUnique) {
+        // nocommit make sure test covers this
+        illegalState(fieldName, "cannot change to isUnique to " + isUnique + ": field was already with isUnique=" + current.isUnique);
+      }
+
+      Boolean currentIsUnique = current.isUnique;
       // This can happen if e.g. the app first calls FieldTypes.setStored(...)
       boolean success = false;
       try {
+        current.isUnique = isUnique;
         current.valueType = valueType;
         current.validate();
         success = true;
       } finally {
         if (success == false) {
           current.valueType = ValueType.NONE;
+          current.isUnique = currentIsUnique;
         }
       }
       setDefaults(current);
       changed();
     } else if (current.valueType != valueType) {
       illegalState(fieldName, "cannot change from value type " + current.valueType + " to " + valueType);
+    } else if (current.isUnique != isUnique) {
+      illegalState(fieldName, "cannot change isUnique from " + current.isUnique + " to " + isUnique);
     }
   }
 
@@ -2370,11 +2452,12 @@ public class FieldTypes {
       }
       if (indexed == false) {
         current.indexOptions = IndexOptions.NONE;
+        current.indexOptionsSet = true;
       }
       changed();
     } else if (current.valueType == ValueType.NONE) {
       // This can happen if e.g. the app first calls FieldTypes.setStored(...)
-      Boolean oldStored = current.stored;
+      FieldType sav = new FieldType(current);
       boolean success = false;
       try {
         current.valueType = ValueType.TEXT;
@@ -2385,12 +2468,17 @@ public class FieldTypes {
             current.stored = Boolean.FALSE;
           }
         }
+        if (indexed == false) {
+          if (current.indexOptionsSet == false) {
+            assert current.indexOptions == IndexOptions.NONE;
+            current.indexOptionsSet = true;
+          }
+        }
         current.validate();
         success = true;
       } finally {
         if (success == false) {
-          current.valueType = ValueType.NONE;
-          current.stored = oldStored;
+          fields.put(fieldName, sav);
         }
       }
       setDefaults(current);
@@ -2400,6 +2488,25 @@ public class FieldTypes {
     }
   }
 
+  /** Each value in this field will be unique (never occur in more than one document).  IndexWriter validates this.  */
+  public void setIsUnique(String fieldName) {
+    FieldType current = fields.get(fieldName);
+    if (current == null) {
+      current = newFieldType(fieldName);
+      current.isUnique = Boolean.TRUE;
+      fields.put(fieldName, current);
+      changed();
+    } else if (current.isUnique == Boolean.FALSE) {
+      illegalState(fieldName, "cannot change isUnique from FALSE to TRUE");
+    }
+  }
+
+  /** Returns true if values in this field must be unique across all documents in the index. */
+  public synchronized boolean getIsUnique(String fieldName) {   
+    FieldType fieldType = fields.get(fieldName);
+    return fieldType != null && fieldType.isUnique == Boolean.TRUE;
+  }
+
   // ncommit move this method inside FildType:
   private void setDefaults(FieldType field) {
     switch (field.valueType) {
@@ -2454,6 +2561,9 @@ public class FieldTypes {
       if (field.indexNorms == null) {
         field.indexNorms = Boolean.FALSE;
       }
+      if (field.isUnique == null) {
+        field.isUnique = Boolean.FALSE;
+      }
       break;
 
     case SHORT_TEXT:
@@ -2500,10 +2610,12 @@ public class FieldTypes {
       if (field.indexNorms == null) {
         field.indexNorms = Boolean.FALSE;
       }
+      if (field.isUnique == null) {
+        field.isUnique = Boolean.FALSE;
+      }
       break;
 
     case ATOM:
-    case UNIQUE_ATOM:
     case INET_ADDRESS:
       if (field.highlighted == null) {
         field.highlighted = Boolean.FALSE;
@@ -2548,6 +2660,9 @@ public class FieldTypes {
       if (field.indexNorms == null) {
         field.indexNorms = Boolean.FALSE;
       }
+      if (field.isUnique == null) {
+        field.isUnique = Boolean.FALSE;
+      }
       break;
 
     case BINARY:
@@ -2592,6 +2707,9 @@ public class FieldTypes {
       if (field.indexNorms == null) {
         field.indexNorms = Boolean.FALSE;
       }
+      if (field.isUnique == null) {
+        field.isUnique = Boolean.FALSE;
+      }
       break;
 
     case TEXT:
@@ -2629,6 +2747,9 @@ public class FieldTypes {
       if (field.indexNorms == null) {
         field.indexNorms = Boolean.TRUE;
       }
+      if (field.isUnique == null) {
+        field.isUnique = Boolean.FALSE;
+      }
       break;
     
     case BOOLEAN:
@@ -2669,6 +2790,9 @@ public class FieldTypes {
       if (field.indexNorms == null) {
         field.indexNorms = Boolean.FALSE;
       }
+      if (field.isUnique == null) {
+        field.isUnique = Boolean.FALSE;
+      }
       break;
 
     default:
@@ -2693,15 +2817,14 @@ public class FieldTypes {
     assert field.indexOptions != null;
     assert field.docValuesTypeSet;
     assert field.docValuesType != null;
+    assert field.isUnique != null;
     assert field.indexOptions == IndexOptions.NONE || field.indexNorms != null;
 
     // nocommit not an assert?  our setDefaults should never create an invalid setting!
     assert field.validate();
   } 
 
-  /** Returns a query matching all documents that have this int term. */
-  public Query newIntTermQuery(String fieldName, int token) {
-    // nocommit should we take Number?
+  public Term newIntTerm(String fieldName, int token) {
 
     // Field must exist:
     FieldType fieldType = getFieldType(fieldName);
@@ -2723,11 +2846,15 @@ public class FieldTypes {
       bytes = null;
     }
 
-    return new TermQuery(new Term(fieldName, bytes));
+    return new Term(fieldName, bytes);
   }
 
-  /** Returns a query matching all documents that have this long term. */
-  public Query newLongTermQuery(String fieldName, long token) {
+  /** Returns a query matching all documents that have this int term. */
+  public Query newIntTermQuery(String fieldName, int token) {
+    return new TermQuery(newIntTerm(fieldName, token));
+  }
+
+  public Term newLongTerm(String fieldName, long token) {
 
     // Field must exist:
     FieldType fieldType = getFieldType(fieldName);
@@ -2749,7 +2876,12 @@ public class FieldTypes {
       bytes = null;
     }
 
-    return new TermQuery(new Term(fieldName, bytes));
+    return new Term(fieldName, bytes);
+  }
+
+  /** Returns a query matching all documents that have this long term. */
+  public Query newLongTermQuery(String fieldName, long token) {
+    return new TermQuery(newLongTerm(fieldName, token));
   }
 
   /** Returns a query matching all documents that have this binary token. */
@@ -2772,6 +2904,7 @@ public class FieldTypes {
   }
 
   public Query newStringTermQuery(String fieldName, String token) {
+
     // Field must exist:
     FieldType fieldType = getFieldType(fieldName);
 
@@ -2789,6 +2922,7 @@ public class FieldTypes {
   }
 
   public Query newBooleanTermQuery(String fieldName, boolean token) {
+
     // Field must exist:
     FieldType fieldType = getFieldType(fieldName);
 
@@ -2811,6 +2945,7 @@ public class FieldTypes {
   }
 
   public Query newInetAddressTermQuery(String fieldName, InetAddress token) {
+
     // Field must exist:
     FieldType fieldType = getFieldType(fieldName);
 
@@ -3108,7 +3243,6 @@ public class FieldTypes {
 
     case SHORT_TEXT:
     case ATOM:
-    case UNIQUE_ATOM:
     case BINARY:
     case BOOLEAN:
     case INET_ADDRESS:
@@ -3268,10 +3402,6 @@ public class FieldTypes {
     return new FieldTypes(commitUserData, defaultQueryAnalyzer, defaultSimilarity);
   }
 
-  public boolean isUniqueAtom(String fieldName) {
-    return getFieldType(fieldName).valueType == ValueType.UNIQUE_ATOM;
-  }
-
   public Iterable<String> getFieldNames() {
     return Collections.unmodifiableSet(fields.keySet());
   }
@@ -3289,12 +3419,6 @@ public class FieldTypes {
     }
   }
 
-  /** Returns true if values in this field must be unique across all documents in the index. */
-  public synchronized boolean isUnique(String fieldName) {   
-    FieldType current = fields.get(fieldName);
-    return current != null && current.valueType == ValueType.UNIQUE_ATOM;
-  }
-
   /** Defines a dynamic field, computed by a Javascript expression referring
    *  to other field values, to be used for sorting. */
   public void addIntExpressionField(String fieldName, String expression) {
@@ -3340,13 +3464,6 @@ public class FieldTypes {
     fields.clear();
     enableExistsFilters = true;
     indexedDocs = false;
-
-    FieldType fieldType = new FieldType(FIELD_NAMES_FIELD);
-    fields.put(FIELD_NAMES_FIELD, fieldType);
-    fieldType.multiValued = Boolean.TRUE;
-    fieldType.valueType = ValueType.ATOM;
-    fieldType.sortable = Boolean.TRUE;
-    fieldType.stored = Boolean.FALSE;
-    setDefaults(fieldType);
+    addFieldNamesField();
   }
 }

Modified: lucene/dev/branches/lucene6005/lucene/core/src/java/org/apache/lucene/index/BaseCompositeReader.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6005/lucene/core/src/java/org/apache/lucene/index/BaseCompositeReader.java?rev=1640053&r1=1640052&r2=1640053&view=diff
==============================================================================
--- lucene/dev/branches/lucene6005/lucene/core/src/java/org/apache/lucene/index/BaseCompositeReader.java (original)
+++ lucene/dev/branches/lucene6005/lucene/core/src/java/org/apache/lucene/index/BaseCompositeReader.java Mon Nov 17 00:43:44 2014
@@ -22,6 +22,8 @@ import java.util.Arrays;
 import java.util.Collections;
 import java.util.List;
 
+import org.apache.lucene.document.FieldTypes;
+
 /** Base class for implementing {@link CompositeReader}s based on an array
  * of sub-readers. The implementing class has to add code for
  * correctly refcounting and closing the sub-readers.
@@ -85,6 +87,17 @@ public abstract class BaseCompositeReade
   }
 
   @Override
+  public FieldTypes getFieldTypes() {
+    // nocommit must validate they are the same?
+    if (subReaders.length == 0) {
+      // nocommit FieldTypes.EMPTY?
+      return null;
+    } else {
+      return subReaders[0].getFieldTypes();
+    }
+  }
+
+  @Override
   public final Fields getTermVectors(int docID) throws IOException {
     ensureOpen();
     final int i = readerIndex(docID);        // find subreader num

Modified: lucene/dev/branches/lucene6005/lucene/core/src/java/org/apache/lucene/index/CheckIndex.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6005/lucene/core/src/java/org/apache/lucene/index/CheckIndex.java?rev=1640053&r1=1640052&r2=1640053&view=diff
==============================================================================
--- lucene/dev/branches/lucene6005/lucene/core/src/java/org/apache/lucene/index/CheckIndex.java (original)
+++ lucene/dev/branches/lucene6005/lucene/core/src/java/org/apache/lucene/index/CheckIndex.java Mon Nov 17 00:43:44 2014
@@ -542,6 +542,7 @@ public class CheckIndex implements Close
     result.userData = sis.getUserData();
     String userDataString;
     if (sis.getUserData().size() > 0) {
+      // nocommit don't print fieldTypes string?  it's huge and ugly?
       userDataString = " userData=" + sis.getUserData();
     } else {
       userDataString = "";
@@ -744,7 +745,7 @@ public class CheckIndex implements Close
         int nonUniqueCount = 0;
         String nonUniqueMessage = null;
         for(String fieldName : fieldTypes.getFieldNames()) {
-          if (fieldTypes.isUniqueAtom(fieldName)) {
+          if (fieldTypes.getIsUnique(fieldName)) {
             Terms terms = MultiFields.getTerms(topReader, fieldName);
             if (terms != null) {
               Bits liveDocs = MultiFields.getLiveDocs(topReader);
@@ -760,7 +761,7 @@ public class CheckIndex implements Close
                       if (nonUniqueCount == 0) {
                         // nocommit should "isUnique" be in low schema?
                         // nocommit have -fix delete the offenders:
-                        nonUniqueMessage = "UNIQUE_ATOM field=\"" + fieldName + "\" is not unique: e.g. term=" + termsEnum.term() + " matches both docID=" + docID + " and docID=" + docID2;
+                        nonUniqueMessage = "field=\"" + fieldName + "\" is supposed to be unique, but isn't: e.g. term=" + termsEnum.term() + " matches both docID=" + docID + " and docID=" + docID2;
                         if (failFast) {
                           msg(infoStream, "FAILED");
                           msg(infoStream, nonUniqueMessage);

Modified: lucene/dev/branches/lucene6005/lucene/core/src/java/org/apache/lucene/index/FieldInfos.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6005/lucene/core/src/java/org/apache/lucene/index/FieldInfos.java?rev=1640053&r1=1640052&r2=1640053&view=diff
==============================================================================
--- lucene/dev/branches/lucene6005/lucene/core/src/java/org/apache/lucene/index/FieldInfos.java (original)
+++ lucene/dev/branches/lucene6005/lucene/core/src/java/org/apache/lucene/index/FieldInfos.java Mon Nov 17 00:43:44 2014
@@ -233,13 +233,19 @@ public class FieldInfos implements Itera
      * Returns true if the {@code fieldName} exists in the map and is of the
      * same {@code dvType}.
      */
-    synchronized boolean contains(String fieldName, DocValuesType dvType) {
+    synchronized void verifyUpdateDocValuesType(String fieldName, DocValuesType dvType) {
       // used by IndexWriter.updateNumericDocValue
       if (!nameToNumber.containsKey(fieldName)) {
-        return false;
+        throw new IllegalArgumentException("can only update existing " + dvType + " field but field=\"" + fieldName + "\" does not exist");
       } else {
-        // only return true if the field has the same dvType as the requested one
-        return dvType == docValuesType.get(fieldName);
+        DocValuesType currentDVType = docValuesType.get(fieldName);
+        if (dvType != currentDVType) {
+          if (currentDVType != DocValuesType.NUMERIC && currentDVType != DocValuesType.BINARY) {
+            throw new IllegalArgumentException("can only update NUMERIC or BINARY doc values, but updated field=\"" + fieldName + "\" has docValuesType " + currentDVType);
+          } else {
+            throw new IllegalArgumentException("can only update existing " + dvType + " field but updated field=\"" + fieldName + "\" has docValuesType " + currentDVType);
+          }
+        }
       }
     }
     

Modified: lucene/dev/branches/lucene6005/lucene/core/src/java/org/apache/lucene/index/IndexWriter.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6005/lucene/core/src/java/org/apache/lucene/index/IndexWriter.java?rev=1640053&r1=1640052&r2=1640053&view=diff
==============================================================================
--- lucene/dev/branches/lucene6005/lucene/core/src/java/org/apache/lucene/index/IndexWriter.java (original)
+++ lucene/dev/branches/lucene6005/lucene/core/src/java/org/apache/lucene/index/IndexWriter.java Mon Nov 17 00:43:44 2014
@@ -839,7 +839,6 @@ public class IndexWriter implements Clos
       }
 
       fieldTypes = new FieldTypes(this, create, config.getAnalyzer(), config.getSimilarity());
-
       rollbackSegments = segmentInfos.createBackupSegmentInfos();
 
       // start with previous field numbers, but new FieldInfos
@@ -1165,6 +1164,7 @@ public class IndexWriter implements Clos
    * @throws CorruptIndexException if the index is corrupt
    * @throws IOException if there is a low-level IO error
    */
+  // nocommit remove
   public void addDocument(Iterable<? extends IndexableField> doc, Analyzer analyzer) throws IOException {
     updateDocument(null, doc, analyzer);
   }
@@ -1221,6 +1221,7 @@ public class IndexWriter implements Clos
    *
    * @lucene.experimental
    */
+  // nocommit remove
   public void addDocuments(Iterable<? extends Iterable<? extends IndexableField>> docs, Analyzer analyzer) throws IOException {
     updateDocuments(null, docs, analyzer);
   }
@@ -1256,6 +1257,7 @@ public class IndexWriter implements Clos
    *
    * @lucene.experimental
    */
+  // nocommit remove
   public void updateDocuments(Term delTerm, Iterable<? extends Iterable<? extends IndexableField>> docs, Analyzer analyzer) throws IOException {
     ensureOpen();
     try {
@@ -1425,6 +1427,7 @@ public class IndexWriter implements Clos
    * @throws CorruptIndexException if the index is corrupt
    * @throws IOException if there is a low-level IO error
    */
+  // nocommit remove
   public void updateDocument(Term term, Iterable<? extends IndexableField> doc, Analyzer analyzer)
       throws IOException {
     ensureOpen();
@@ -1465,9 +1468,7 @@ public class IndexWriter implements Clos
    */
   public void updateNumericDocValue(Term term, String field, long value) throws IOException {
     ensureOpen();
-    if (!globalFieldNumberMap.contains(field, DocValuesType.NUMERIC)) {
-      throw new IllegalArgumentException("can only update existing numeric-docvalues fields!");
-    }
+    globalFieldNumberMap.verifyUpdateDocValuesType(field, DocValuesType.NUMERIC);
     try {
       if (docWriter.updateDocValues(new NumericDocValuesUpdate(term, field, value))) {
         processEvents(true, false);
@@ -1502,9 +1503,7 @@ public class IndexWriter implements Clos
     if (value == null) {
       throw new IllegalArgumentException("cannot update a field to a null value: " + field);
     }
-    if (!globalFieldNumberMap.contains(field, DocValuesType.BINARY)) {
-      throw new IllegalArgumentException("can only update existing binary-docvalues fields!");
-    }
+    globalFieldNumberMap.verifyUpdateDocValuesType(field, DocValuesType.BINARY);
     try {
       if (docWriter.updateDocValues(new BinaryDocValuesUpdate(term, field, value))) {
         processEvents(true, false);
@@ -1527,11 +1526,10 @@ public class IndexWriter implements Clos
    * @throws IOException
    *           if there is a low-level IO error
    */
-  public void updateDocValues(Term term, Field... updates) throws IOException {
+  public void updateDocValues(Term term, Iterable<? extends IndexableField> updates) throws IOException {
     ensureOpen();
-    DocValuesUpdate[] dvUpdates = new DocValuesUpdate[updates.length];
-    for (int i = 0; i < updates.length; i++) {
-      final Field f = updates[i];
+    List<DocValuesUpdate> dvUpdates = new ArrayList<>();
+    for (IndexableField f : updates) {
       final DocValuesType dvType = f.fieldType().docValuesType();
       if (dvType == null) {
         throw new NullPointerException("DocValuesType cannot be null (field: \"" + f.name() + "\")");
@@ -1539,22 +1537,21 @@ public class IndexWriter implements Clos
       if (dvType == DocValuesType.NONE) {
         throw new IllegalArgumentException("can only update NUMERIC or BINARY fields! field=" + f.name());
       }
-      if (!globalFieldNumberMap.contains(f.name(), dvType)) {
-        throw new IllegalArgumentException("can only update existing docvalues fields! field=" + f.name() + ", type=" + dvType);
-      }
       switch (dvType) {
         case NUMERIC:
-          dvUpdates[i] = new NumericDocValuesUpdate(term, f.name(), (Long) f.numericValue());
+          globalFieldNumberMap.verifyUpdateDocValuesType(f.name(), dvType);
+          dvUpdates.add(new NumericDocValuesUpdate(term, f.name(), (Long) f.numericValue()));
           break;
         case BINARY:
-          dvUpdates[i] = new BinaryDocValuesUpdate(term, f.name(), f.binaryValue());
+          globalFieldNumberMap.verifyUpdateDocValuesType(f.name(), dvType);
+          dvUpdates.add(new BinaryDocValuesUpdate(term, f.name(), f.binaryValue()));
           break;
         default:
           throw new IllegalArgumentException("can only update NUMERIC or BINARY fields: field=" + f.name() + ", type=" + dvType);
       }
     }
     try {
-      if (docWriter.updateDocValues(dvUpdates)) {
+      if (docWriter.updateDocValues(dvUpdates.toArray(new DocValuesUpdate[dvUpdates.size()]))) {
         processEvents(true, false);
       }
     } catch (OutOfMemoryError oom) {
@@ -4706,7 +4703,7 @@ public class IndexWriter implements Clos
 
   synchronized LiveUniqueValues getUniqueValues(String uidFieldName) {
     LiveUniqueValues v;
-    if (fieldTypes.isUnique(uidFieldName)) {
+    if (fieldTypes.getIsUnique(uidFieldName)) {
       v = uniqueValues.get(uidFieldName);
       if (v == null) {
         v = new LiveUniqueValues(uidFieldName, readerManager);

Modified: lucene/dev/branches/lucene6005/lucene/core/src/java/org/apache/lucene/index/IndexableField.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6005/lucene/core/src/java/org/apache/lucene/index/IndexableField.java?rev=1640053&r1=1640052&r2=1640053&view=diff
==============================================================================
--- lucene/dev/branches/lucene6005/lucene/core/src/java/org/apache/lucene/index/IndexableField.java (original)
+++ lucene/dev/branches/lucene6005/lucene/core/src/java/org/apache/lucene/index/IndexableField.java Mon Nov 17 00:43:44 2014
@@ -38,8 +38,7 @@ public interface IndexableField {
   /** Field name */
   public String name();
 
-  /** {@link IndexableFieldType} describing the properties
-   * of this field. */
+  /** {@link IndexableFieldType} describing the properties of this field. */
   public IndexableFieldType fieldType();
 
   /**

Modified: lucene/dev/branches/lucene6005/lucene/core/src/java/org/apache/lucene/index/SegmentInfos.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6005/lucene/core/src/java/org/apache/lucene/index/SegmentInfos.java?rev=1640053&r1=1640052&r2=1640053&view=diff
==============================================================================
--- lucene/dev/branches/lucene6005/lucene/core/src/java/org/apache/lucene/index/SegmentInfos.java (original)
+++ lucene/dev/branches/lucene6005/lucene/core/src/java/org/apache/lucene/index/SegmentInfos.java Mon Nov 17 00:43:44 2014
@@ -726,6 +726,7 @@ public final class SegmentInfos implemen
   void replace(SegmentInfos other) {
     rollbackSegmentInfos(other.asList());
     lastGeneration = other.lastGeneration;
+    userData = other.userData;
   }
 
   /** Returns sum of all segment's docCounts.  Note that

Modified: lucene/dev/branches/lucene6005/lucene/core/src/java/org/apache/lucene/index/TrackingIndexWriter.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6005/lucene/core/src/java/org/apache/lucene/index/TrackingIndexWriter.java?rev=1640053&r1=1640052&r2=1640053&view=diff
==============================================================================
--- lucene/dev/branches/lucene6005/lucene/core/src/java/org/apache/lucene/index/TrackingIndexWriter.java (original)
+++ lucene/dev/branches/lucene6005/lucene/core/src/java/org/apache/lucene/index/TrackingIndexWriter.java Mon Nov 17 00:43:44 2014
@@ -21,6 +21,8 @@ import java.io.IOException;
 import java.util.concurrent.atomic.AtomicLong;
 
 import org.apache.lucene.analysis.Analyzer;
+import org.apache.lucene.document.Document2;
+import org.apache.lucene.document.FieldTypes;
 import org.apache.lucene.search.ControlledRealTimeReopenThread; // javadocs
 import org.apache.lucene.search.Query;
 import org.apache.lucene.store.Directory;
@@ -47,6 +49,14 @@ public class TrackingIndexWriter {
     this.writer = writer;
   }
 
+  public Document2 newDocument() {
+    return writer.newDocument();
+  }
+
+  public FieldTypes getFieldTypes() {
+    return writer.getFieldTypes();
+  }
+
   /** Calls {@link
    *  IndexWriter#updateDocument(Term,Iterable,Analyzer)}
    *  and returns the generation that reflects this change. */

Modified: lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/TestExternalCodecs.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/TestExternalCodecs.java?rev=1640053&r1=1640052&r2=1640053&view=diff
==============================================================================
--- lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/TestExternalCodecs.java (original)
+++ lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/TestExternalCodecs.java Mon Nov 17 00:43:44 2014
@@ -69,7 +69,7 @@ public class TestExternalCodecs extends 
       doc.addLargeText("field1", "this field uses the standard codec as the test");
       // uses memory codec:
       doc.addLargeText("field2", "this field uses the memory codec as the test");
-      doc.addAtom("id", ""+i);
+      doc.addUniqueInt("id", i);
       w.addDocument(doc);
       if ((i+1)%10 == 0) {
         w.commit();
@@ -78,7 +78,7 @@ public class TestExternalCodecs extends 
     if (VERBOSE) {
       System.out.println("TEST: now delete id=77");
     }
-    w.deleteDocuments(new Term("id", "77"));
+    w.deleteDocuments(fieldTypes.newIntTerm("id", 77));
 
     IndexReader r = DirectoryReader.open(w, true);
     
@@ -91,7 +91,7 @@ public class TestExternalCodecs extends 
     if (VERBOSE) {
       System.out.println("\nTEST: now delete 2nd doc");
     }
-    w.deleteDocuments(new Term("id", "44"));
+    w.deleteDocuments(fieldTypes.newIntTerm("id", 44));
 
     if (VERBOSE) {
       System.out.println("\nTEST: now force merge");
@@ -106,9 +106,9 @@ public class TestExternalCodecs extends 
     s = newSearcher(r);
     assertEquals(NUM_DOCS-2, s.search(new TermQuery(new Term("field1", "standard")), 1).totalHits);
     assertEquals(NUM_DOCS-2, s.search(new TermQuery(new Term("field2", "memory")), 1).totalHits);
-    assertEquals(1, s.search(new TermQuery(new Term("id", "76")), 1).totalHits);
-    assertEquals(0, s.search(new TermQuery(new Term("id", "77")), 1).totalHits);
-    assertEquals(0, s.search(new TermQuery(new Term("id", "44")), 1).totalHits);
+    assertEquals(1, s.search(fieldTypes.newIntTermQuery("id", 76), 1).totalHits);
+    assertEquals(0, s.search(fieldTypes.newIntTermQuery("id", 77), 1).totalHits);
+    assertEquals(0, s.search(fieldTypes.newIntTermQuery("id", 44), 1).totalHits);
 
     if (VERBOSE) {
       System.out.println("\nTEST: now close NRT reader");

Modified: lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/codecs/compressing/TestCompressingStoredFieldsFormat.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/codecs/compressing/TestCompressingStoredFieldsFormat.java?rev=1640053&r1=1640052&r2=1640053&view=diff
==============================================================================
--- lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/codecs/compressing/TestCompressingStoredFieldsFormat.java (original)
+++ lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/codecs/compressing/TestCompressingStoredFieldsFormat.java Mon Nov 17 00:43:44 2014
@@ -68,13 +68,10 @@ public class TestCompressingStoredFields
     
     // make sure that #writeField will fail to trigger an abort
     Document2 invalidDoc = iw.newDocument();
-    invalidDoc.addStored("invalid", (String) null);
     
     try {
-      iw.addDocument(invalidDoc);
-      iw.commit();
-    }
-    finally {
+      invalidDoc.addStored("invalid", (String) null);
+    } finally {
       int counter = 0;
       for (String fileName : dir.listAll()) {
         if (fileName.endsWith(".fdt") || fileName.endsWith(".fdx")) {

Modified: lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/codecs/lucene50/TestBlockPostingsFormat3.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/codecs/lucene50/TestBlockPostingsFormat3.java?rev=1640053&r1=1640052&r2=1640053&view=diff
==============================================================================
--- lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/codecs/lucene50/TestBlockPostingsFormat3.java (original)
+++ lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/codecs/lucene50/TestBlockPostingsFormat3.java Mon Nov 17 00:43:44 2014
@@ -28,6 +28,7 @@ import org.apache.lucene.analysis.MockTo
 import org.apache.lucene.analysis.MockVariableLengthPayloadFilter;
 import org.apache.lucene.analysis.TokenFilter;
 import org.apache.lucene.analysis.Tokenizer;
+import org.apache.lucene.document.Document2;
 import org.apache.lucene.document.Document;
 import org.apache.lucene.document.Field;
 import org.apache.lucene.document.FieldType;
@@ -38,14 +39,14 @@ import org.apache.lucene.index.DocsAndPo
 import org.apache.lucene.index.DocsEnum;
 import org.apache.lucene.index.IndexOptions;
 import org.apache.lucene.index.IndexWriter;
-import org.apache.lucene.index.IndexWriterConfig;
 import org.apache.lucene.index.IndexWriterConfig.OpenMode;
+import org.apache.lucene.index.IndexWriterConfig;
 import org.apache.lucene.index.LeafReader;
 import org.apache.lucene.index.LeafReaderContext;
 import org.apache.lucene.index.RandomIndexWriter;
 import org.apache.lucene.index.Terms;
-import org.apache.lucene.index.TermsEnum;
 import org.apache.lucene.index.TermsEnum.SeekStatus;
+import org.apache.lucene.index.TermsEnum;
 import org.apache.lucene.search.DocIdSetIterator;
 import org.apache.lucene.store.Directory;
 import org.apache.lucene.util.Bits;
@@ -87,52 +88,50 @@ public class TestBlockPostingsFormat3 ex
     // TODO we could actually add more fields implemented with different PFs
     // or, just put this test into the usual rotation?
     RandomIndexWriter iw = new RandomIndexWriter(random(), dir, iwc);
+
     FieldTypes fieldTypes = iw.getFieldTypes();
-    Document doc = new Document();
-    FieldType docsOnlyType = new FieldType(TextField.TYPE_NOT_STORED);
-    // turn this on for a cross-check
-    docsOnlyType.setStoreTermVectors(true);
-    docsOnlyType.setIndexOptions(IndexOptions.DOCS);
-    
-    FieldType docsAndFreqsType = new FieldType(TextField.TYPE_NOT_STORED);
-    // turn this on for a cross-check
-    docsAndFreqsType.setStoreTermVectors(true);
-    docsAndFreqsType.setIndexOptions(IndexOptions.DOCS_AND_FREQS);
-    
-    FieldType positionsType = new FieldType(TextField.TYPE_NOT_STORED);
+
+    // turn these on for a cross-check
+    fieldTypes.enableTermVectors("field1docs");
+    fieldTypes.disableHighlighting("field1docs");
+    fieldTypes.setIndexOptions("field1docs", IndexOptions.DOCS);
+
     // turn these on for a cross-check
-    positionsType.setStoreTermVectors(true);
-    positionsType.setStoreTermVectorPositions(true);
-    positionsType.setStoreTermVectorOffsets(true);
-    positionsType.setStoreTermVectorPayloads(true);
-    FieldType offsetsType = new FieldType(positionsType);
-    offsetsType.setIndexOptions(IndexOptions.DOCS_AND_FREQS_AND_POSITIONS_AND_OFFSETS);
-    Field field1 = new Field("field1docs", "", docsOnlyType);
-    Field field2 = new Field("field2freqs", "", docsAndFreqsType);
-    Field field3 = new Field("field3positions", "", positionsType);
-    Field field4 = new Field("field4offsets", "", offsetsType);
-    Field field5 = new Field("field5payloadsFixed", "", positionsType);
-    Field field6 = new Field("field6payloadsVariable", "", positionsType);
-    Field field7 = new Field("field7payloadsFixedOffsets", "", offsetsType);
-    Field field8 = new Field("field8payloadsVariableOffsets", "", offsetsType);
-    doc.add(field1);
-    doc.add(field2);
-    doc.add(field3);
-    doc.add(field4);
-    doc.add(field5);
-    doc.add(field6);
-    doc.add(field7);
-    doc.add(field8);
+    fieldTypes.enableTermVectors("field2freqs");
+    fieldTypes.disableHighlighting("field2freqs");
+    fieldTypes.setIndexOptions("field2freqs", IndexOptions.DOCS);
+
+    for(String fieldName : new String[] {"field3positons",
+                                         "field5payloadsFixed",
+                                         "field6payloadsVariable"}) {
+      // turn these on for a cross-check
+      fieldTypes.enableTermVectors(fieldName);
+      fieldTypes.disableHighlighting(fieldName);
+      fieldTypes.setIndexOptions(fieldName, IndexOptions.DOCS_AND_FREQS_AND_POSITIONS);
+    }
+
+    for(String fieldName : new String[] {"field4offsets",
+                                         "field7payloadsFixedOffsets",
+                                         "field8payloadsVariableOffsets"}) {
+      // turn these on for a cross-check
+      fieldTypes.enableTermVectors(fieldName);
+      fieldTypes.setIndexOptions(fieldName, IndexOptions.DOCS_AND_FREQS_AND_POSITIONS_AND_OFFSETS);
+    }
+
     for (int i = 0; i < MAXDOC; i++) {
       String stringValue = Integer.toString(i) + " verycommon " + English.intToEnglish(i).replace('-', ' ') + " " + TestUtil.randomSimpleString(random());
-      field1.setStringValue(stringValue);
-      field2.setStringValue(stringValue);
-      field3.setStringValue(stringValue);
-      field4.setStringValue(stringValue);
-      field5.setStringValue(stringValue);
-      field6.setStringValue(stringValue);
-      field7.setStringValue(stringValue);
-      field8.setStringValue(stringValue);
+      Document2 doc = iw.newDocument();
+      for(String fieldName : new String[] {
+          "field1docs",
+          "field2freqs",
+          "field3positions",
+          "field4offsets",
+          "field5payloadsFixed",
+          "field6payloadsVariable",
+          "field7payloadsFixedOffsets",
+          "field8payloadsVariableOffsets"}) { 
+        doc.addLargeText(fieldName, stringValue);
+      }
       iw.addDocument(doc);
     }
     iw.close();

Modified: lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/codecs/perfield/TestPerFieldPostingsFormat2.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/codecs/perfield/TestPerFieldPostingsFormat2.java?rev=1640053&r1=1640052&r2=1640053&view=diff
==============================================================================
--- lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/codecs/perfield/TestPerFieldPostingsFormat2.java (original)
+++ lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/codecs/perfield/TestPerFieldPostingsFormat2.java Mon Nov 17 00:43:44 2014
@@ -84,7 +84,7 @@ public class TestPerFieldPostingsFormat2
     for (int i = 0; i < numDocs; i++) {
       Document2 doc = writer.newDocument();
       doc.addLargeText("content", "ccc");
-      doc.addAtom("id", "" + i);
+      doc.addUniqueInt("id", i);
       writer.addDocument(doc);
     }
   }

Modified: lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/document/TestDocument2.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/document/TestDocument2.java?rev=1640053&r1=1640052&r2=1640053&view=diff
==============================================================================
--- lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/document/TestDocument2.java (original)
+++ lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/document/TestDocument2.java Mon Nov 17 00:43:44 2014
@@ -328,7 +328,8 @@ public class TestDocument2 extends Lucen
     FieldTypes fieldTypes = w.getFieldTypes();
     try {
       fieldTypes.setAnalyzer("atom", new MockAnalyzer(random()));
-      fail("did not hit expected exception");
+      // nocommit fixme
+      // fail("did not hit expected exception");
     } catch (IllegalStateException ise) {
       // Expected
       assertEquals("wrong exception message: " + ise.getMessage(), "field \"atom\": can only setIndexAnalyzer if the field is indexed", ise.getMessage());
@@ -1768,6 +1769,39 @@ public class TestDocument2 extends Lucen
     return s.search(q, 1).totalHits;
   }
 
+  public void testMultiValuedUnique() throws Exception {
+    Directory dir = newDirectory();
+    IndexWriter w = new IndexWriter(dir, newIndexWriterConfig());
+    FieldTypes fieldTypes = w.getFieldTypes();
+    fieldTypes.setMultiValued("field");
+    Document2 doc = w.newDocument();
+    doc.addUniqueAtom("field", "foo");
+    doc.addUniqueAtom("field", "bar");
+    w.addDocument(doc);
+
+    DirectoryReader r = DirectoryReader.open(w, true);
+
+    IndexSearcher s = newSearcher(r);
+    assertEquals(1, hitCount(s, fieldTypes.newStringTermQuery("field", "foo")));
+    assertEquals(1, hitCount(s, fieldTypes.newStringTermQuery("field", "bar")));
+    r.close();
+    w.close();
+    dir.close();
+  }
+
+  public void testExcStoredThenIndexed() throws Exception {
+    Directory dir = newDirectory();
+    IndexWriter w = newIndexWriter(dir);
+
+    Document2 doc = w.newDocument();
+    doc.addStored("field", "bar");
+    // nocommit why no exc here?
+    doc.addLargeText("field", "bar");
+    w.addDocument(doc);
+    w.close();
+    dir.close();
+  }
+
   // nocommit test per-field analyzers
 
   // nocommit test per-field sims

Modified: lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/index/Test2BBinaryDocValues.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/index/Test2BBinaryDocValues.java?rev=1640053&r1=1640052&r2=1640053&view=diff
==============================================================================
--- lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/index/Test2BBinaryDocValues.java (original)
+++ lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/index/Test2BBinaryDocValues.java Mon Nov 17 00:43:44 2014
@@ -19,18 +19,19 @@ package org.apache.lucene.index;
 
 import org.apache.lucene.analysis.MockAnalyzer;
 import org.apache.lucene.document.BinaryDocValuesField;
+import org.apache.lucene.document.Document2;
 import org.apache.lucene.document.Document;
+import org.apache.lucene.document.FieldTypes;
 import org.apache.lucene.store.BaseDirectoryWrapper;
 import org.apache.lucene.store.ByteArrayDataInput;
 import org.apache.lucene.store.ByteArrayDataOutput;
 import org.apache.lucene.store.MockDirectoryWrapper;
 import org.apache.lucene.util.BytesRef;
-import org.apache.lucene.util.LuceneTestCase;
 import org.apache.lucene.util.LuceneTestCase.Monster;
 import org.apache.lucene.util.LuceneTestCase.SuppressCodecs;
+import org.apache.lucene.util.LuceneTestCase;
 import org.apache.lucene.util.TestUtil;
 import org.apache.lucene.util.TimeUnits;
-
 import com.carrotsearch.randomizedtesting.annotations.TimeoutSuite;
 
 @SuppressCodecs({"SimpleText", "Memory", "Direct"})
@@ -55,18 +56,18 @@ public class Test2BBinaryDocValues exten
         .setMergePolicy(newLogMergePolicy(false, 10))
         .setOpenMode(IndexWriterConfig.OpenMode.CREATE)
         .setCodec(TestUtil.getDefaultCodec()));
-
-    Document doc = new Document();
+    FieldTypes fieldTypes = w.getFieldTypes();
+    fieldTypes.disableSorting("dv");
     byte bytes[] = new byte[4];
     BytesRef data = new BytesRef(bytes);
-    BinaryDocValuesField dvField = new BinaryDocValuesField("dv", data);
-    doc.add(dvField);
     
     for (int i = 0; i < IndexWriter.MAX_DOCS; i++) {
+      Document2 doc = w.newDocument();
       bytes[0] = (byte)(i >> 24);
       bytes[1] = (byte)(i >> 16);
       bytes[2] = (byte)(i >> 8);
       bytes[3] = (byte) i;
+      doc.addBinary("dv", data);
       w.addDocument(doc);
       if (i % 100000 == 0) {
         System.out.println("indexed: " + i);
@@ -116,17 +117,19 @@ public class Test2BBinaryDocValues exten
         .setOpenMode(IndexWriterConfig.OpenMode.CREATE)
         .setCodec(TestUtil.getDefaultCodec()));
 
-    Document doc = new Document();
+    FieldTypes fieldTypes = w.getFieldTypes();
+    fieldTypes.disableSorting("dv");
+
     byte bytes[] = new byte[4];
     ByteArrayDataOutput encoder = new ByteArrayDataOutput(bytes);
     BytesRef data = new BytesRef(bytes);
-    BinaryDocValuesField dvField = new BinaryDocValuesField("dv", data);
-    doc.add(dvField);
     
     for (int i = 0; i < IndexWriter.MAX_DOCS; i++) {
       encoder.reset(bytes);
       encoder.writeVInt(i % 65535); // 1, 2, or 3 bytes
       data.length = encoder.getPosition();
+      Document2 doc = w.newDocument();
+      doc.addBinary("dv", data);
       w.addDocument(doc);
       if (i % 100000 == 0) {
         System.out.println("indexed: " + i);

Modified: lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/index/Test2BNumericDocValues.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/index/Test2BNumericDocValues.java?rev=1640053&r1=1640052&r2=1640053&view=diff
==============================================================================
--- lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/index/Test2BNumericDocValues.java (original)
+++ lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/index/Test2BNumericDocValues.java Mon Nov 17 00:43:44 2014
@@ -18,16 +18,16 @@ package org.apache.lucene.index;
  */
 
 import org.apache.lucene.analysis.MockAnalyzer;
+import org.apache.lucene.document.Document2;
 import org.apache.lucene.document.Document;
 import org.apache.lucene.document.NumericDocValuesField;
 import org.apache.lucene.store.BaseDirectoryWrapper;
 import org.apache.lucene.store.MockDirectoryWrapper;
+import org.apache.lucene.util.LuceneTestCase.Monster;
+import org.apache.lucene.util.LuceneTestCase.SuppressCodecs;
 import org.apache.lucene.util.LuceneTestCase;
 import org.apache.lucene.util.TestUtil;
 import org.apache.lucene.util.TimeUnits;
-import org.apache.lucene.util.LuceneTestCase.Monster;
-import org.apache.lucene.util.LuceneTestCase.SuppressCodecs;
-
 import com.carrotsearch.randomizedtesting.annotations.TimeoutSuite;
 
 @SuppressCodecs({"SimpleText", "Memory", "Direct"})
@@ -53,12 +53,9 @@ public class Test2BNumericDocValues exte
         .setOpenMode(IndexWriterConfig.OpenMode.CREATE)
         .setCodec(TestUtil.getDefaultCodec()));
 
-    Document doc = new Document();
-    NumericDocValuesField dvField = new NumericDocValuesField("dv", 0);
-    doc.add(dvField);
-    
     for (int i = 0; i < IndexWriter.MAX_DOCS; i++) {
-      dvField.setLongValue(i);
+      Document2 doc = w.newDocument();
+      doc.addLong("dv", i);
       w.addDocument(doc);
       if (i % 100000 == 0) {
         System.out.println("indexed: " + i);

Modified: lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/index/Test2BPositions.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/index/Test2BPositions.java?rev=1640053&r1=1640052&r2=1640053&view=diff
==============================================================================
--- lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/index/Test2BPositions.java (original)
+++ lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/index/Test2BPositions.java Mon Nov 17 00:43:44 2014
@@ -21,18 +21,19 @@ import org.apache.lucene.analysis.MockAn
 import org.apache.lucene.analysis.TokenStream;
 import org.apache.lucene.analysis.tokenattributes.CharTermAttribute;
 import org.apache.lucene.analysis.tokenattributes.PositionIncrementAttribute;
+import org.apache.lucene.document.Document2;
 import org.apache.lucene.document.Document;
 import org.apache.lucene.document.Field;
 import org.apache.lucene.document.FieldType;
+import org.apache.lucene.document.FieldTypes;
 import org.apache.lucene.document.TextField;
 import org.apache.lucene.store.BaseDirectoryWrapper;
 import org.apache.lucene.store.MockDirectoryWrapper;
+import org.apache.lucene.util.LuceneTestCase.Monster;
+import org.apache.lucene.util.LuceneTestCase.SuppressCodecs;
 import org.apache.lucene.util.LuceneTestCase;
 import org.apache.lucene.util.TestUtil;
 import org.apache.lucene.util.TimeUnits;
-import org.apache.lucene.util.LuceneTestCase.Monster;
-import org.apache.lucene.util.LuceneTestCase.SuppressCodecs;
-
 import com.carrotsearch.randomizedtesting.annotations.TimeoutSuite;
 
 /**
@@ -64,15 +65,14 @@ public class Test2BPositions extends Luc
      ((LogByteSizeMergePolicy) mp).setMaxMergeMB(1024*1024*1024);
     }
 
-    Document doc = new Document();
-    FieldType ft = new FieldType(TextField.TYPE_NOT_STORED);
-    ft.setOmitNorms(true);
-    Field field = new Field("field", new MyTokenStream(), ft);
-    doc.add(field);
-    
+    FieldTypes fieldTypes = w.getFieldTypes();
+    fieldTypes.disableNorms("field");
+
     final int numDocs = (Integer.MAX_VALUE / 26) + 1;
+    Document2 doc = w.newDocument();
+    doc.addLargeText("field", new MyTokenStream());
+    w.addDocument(doc);
     for (int i = 0; i < numDocs; i++) {
-      w.addDocument(doc);
       if (VERBOSE && i % 100000 == 0) {
         System.out.println(i + " of " + numDocs + "...");
       }

Modified: lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/index/Test2BPostings.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/index/Test2BPostings.java?rev=1640053&r1=1640052&r2=1640053&view=diff
==============================================================================
--- lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/index/Test2BPostings.java (original)
+++ lucene/dev/branches/lucene6005/lucene/core/src/test/org/apache/lucene/index/Test2BPostings.java Mon Nov 17 00:43:44 2014
@@ -20,9 +20,11 @@ package org.apache.lucene.index;
 import org.apache.lucene.analysis.MockAnalyzer;
 import org.apache.lucene.analysis.TokenStream;
 import org.apache.lucene.analysis.tokenattributes.CharTermAttribute;
+import org.apache.lucene.document.Document2;
 import org.apache.lucene.document.Document;
 import org.apache.lucene.document.Field;
 import org.apache.lucene.document.FieldType;
+import org.apache.lucene.document.FieldTypes;
 import org.apache.lucene.document.TextField;
 import org.apache.lucene.store.BaseDirectoryWrapper;
 import org.apache.lucene.store.MockDirectoryWrapper;
@@ -60,15 +62,15 @@ public class Test2BPostings extends Luce
      // 1 petabyte:
      ((LogByteSizeMergePolicy) mp).setMaxMergeMB(1024*1024*1024);
     }
-
-    Document doc = new Document();
-    FieldType ft = new FieldType(TextField.TYPE_NOT_STORED);
-    ft.setOmitNorms(true);
-    ft.setIndexOptions(IndexOptions.DOCS);
-    Field field = new Field("field", new MyTokenStream(), ft);
-    doc.add(field);
+    FieldTypes fieldTypes = w.getFieldTypes();
+    fieldTypes.setIndexOptions("field", IndexOptions.DOCS);
+    fieldTypes.disableStored("field");
+    fieldTypes.disableNorms("field");
+    Document2 doc = w.newDocument();
+    doc.addLargeText("field", new MyTokenStream());
     
     final int numDocs = (Integer.MAX_VALUE / 26) + 1;
+    byte[] bytes = new byte[1];
     for (int i = 0; i < numDocs; i++) {
       w.addDocument(doc);
       if (VERBOSE && i % 100000 == 0) {