lucenenet-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From pnas...@apache.org
Subject [03/10] Lucene.Net.Codes/Sep fully ported, work done on SimpleText and Memory as well
Date Sun, 28 Sep 2014 08:50:07 GMT
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/d852d5b0/src/Lucene.Net.Codecs/Memory/MemoryPostingsFormat.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Codecs/Memory/MemoryPostingsFormat.cs b/src/Lucene.Net.Codecs/Memory/MemoryPostingsFormat.cs
index 90e4a53..f45bc24 100644
--- a/src/Lucene.Net.Codecs/Memory/MemoryPostingsFormat.cs
+++ b/src/Lucene.Net.Codecs/Memory/MemoryPostingsFormat.cs
@@ -1,936 +1,1203 @@
-package codecs.memory;
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-import java.io.IOException;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.SortedMap;
-import java.util.TreeMap;
-
-import codecs.CodecUtil;
-import codecs.FieldsConsumer;
-import codecs.FieldsProducer;
-import codecs.PostingsConsumer;
-import codecs.PostingsFormat;
-import codecs.TermStats;
-import codecs.TermsConsumer;
-import index.DocsAndPositionsEnum;
-import index.DocsEnum;
-import index.FieldInfo.IndexOptions;
-import index.FieldInfo;
-import index.FieldInfos;
-import index.IndexFileNames;
-import index.SegmentReadState;
-import index.SegmentWriteState;
-import index.Terms;
-import index.TermsEnum;
-import store.ByteArrayDataInput;
-import store.ChecksumIndexInput;
-import store.IOContext;
-import store.IndexInput;
-import store.IndexOutput;
-import store.RAMOutputStream;
-import util.ArrayUtil;
-import util.Bits;
-import util.BytesRef;
-import util.IOUtils;
-import util.IntsRef;
-import util.RamUsageEstimator;
-import util.fst.Builder;
-import util.fst.ByteSequenceOutputs;
-import util.fst.BytesRefFSTEnum;
-import util.fst.FST;
-import util.fst.Util;
-import util.packed.PackedInts;
-
-// TODO: would be nice to somehow allow this to act like
-// InstantiatedIndex, by never writing to disk; ie you write
-// to this Codec in RAM only and then when you open a reader
-// it pulls the FST directly from what you wrote w/o going
-// to disk.
-
-/** Stores terms & postings (docs, positions, payloads) in
- *  RAM, using an FST.
- *
- * <p>Note that this codec implements advance as a linear
- * scan!  This means if you store large fields in here,
- * queries that rely on advance will (AND boolQuery,
- * PhraseQuery) will be relatively slow!
- *
- * @lucene.experimental */
-
-// TODO: Maybe name this 'Cached' or something to reflect
-// the reality that it is actually written to disk, but
-// loads itself in ram?
-public final class MemoryPostingsFormat extends PostingsFormat {
-
-  private final bool doPackFST;
-  private final float acceptableOverheadRatio;
-
-  public MemoryPostingsFormat() {
-    this(false, PackedInts.DEFAULT);
-  }
-
-  /**
-   * Create MemoryPostingsFormat, specifying advanced FST options.
-   * @param doPackFST true if a packed FST should be built.
-   *        NOTE: packed FSTs are limited to ~2.1 GB of postings.
-   * @param acceptableOverheadRatio allowable overhead for packed ints
-   *        during FST construction.
-   */
-  public MemoryPostingsFormat(bool doPackFST, float acceptableOverheadRatio) {
-    super("Memory");
-    this.doPackFST = doPackFST;
-    this.acceptableOverheadRatio = acceptableOverheadRatio;
-  }
-  
-  @Override
-  public String toString() {
-    return "PostingsFormat(name=" + getName() + " doPackFST= " + doPackFST + ")";
-  }
-
-  private final static class TermsWriter extends TermsConsumer {
-    private final IndexOutput out;
-    private final FieldInfo field;
-    private final Builder<BytesRef> builder;
-    private final ByteSequenceOutputs outputs = ByteSequenceOutputs.getSingleton();
-    private final bool doPackFST;
-    private final float acceptableOverheadRatio;
-    private int termCount;
-
-    public TermsWriter(IndexOutput out, FieldInfo field, bool doPackFST, float acceptableOverheadRatio) {
-      this.out = out;
-      this.field = field;
-      this.doPackFST = doPackFST;
-      this.acceptableOverheadRatio = acceptableOverheadRatio;
-      builder = new Builder<>(FST.INPUT_TYPE.BYTE1, 0, 0, true, true, Integer.MAX_VALUE, outputs, null, doPackFST, acceptableOverheadRatio, true, 15);
-    }
-
-    private class PostingsWriter extends PostingsConsumer {
-      private int lastDocID;
-      private int lastPos;
-      private int lastPayloadLen;
-
-      // NOTE: not private so we don't pay access check at runtime:
-      int docCount;
-      RAMOutputStream buffer = new RAMOutputStream();
-      
-      int lastOffsetLength;
-      int lastOffset;
-
-      @Override
-      public void startDoc(int docID, int termDocFreq)  {
-        //System.out.println("    startDoc docID=" + docID + " freq=" + termDocFreq);
-        final int delta = docID - lastDocID;
-        Debug.Assert( docID == 0 || delta > 0;
-        lastDocID = docID;
-        docCount++;
-
-        if (field.getIndexOptions() == IndexOptions.DOCS_ONLY) {
-          buffer.writeVInt(delta);
-        } else if (termDocFreq == 1) {
-          buffer.writeVInt((delta<<1) | 1);
-        } else {
-          buffer.writeVInt(delta<<1);
-          Debug.Assert( termDocFreq > 0;
-          buffer.writeVInt(termDocFreq);
-        }
-
-        lastPos = 0;
-        lastOffset = 0;
-      }
-
-      @Override
-      public void addPosition(int pos, BytesRef payload, int startOffset, int endOffset)  {
-        Debug.Assert( payload == null || field.hasPayloads();
-
-        //System.out.println("      addPos pos=" + pos + " payload=" + payload);
-
-        final int delta = pos - lastPos;
-        Debug.Assert( delta >= 0;
-        lastPos = pos;
-        
-        int payloadLen = 0;
-        
-        if (field.hasPayloads()) {
-          payloadLen = payload == null ? 0 : payload.length;
-          if (payloadLen != lastPayloadLen) {
-            lastPayloadLen = payloadLen;
-            buffer.writeVInt((delta<<1)|1);
-            buffer.writeVInt(payloadLen);
-          } else {
-            buffer.writeVInt(delta<<1);
-          }
-        } else {
-          buffer.writeVInt(delta);
-        }
-        
-        if (field.getIndexOptions().compareTo(IndexOptions.DOCS_AND_FREQS_AND_POSITIONS_AND_OFFSETS) >= 0) {
-          // don't use startOffset - lastEndOffset, because this creates lots of negative vints for synonyms,
-          // and the numbers aren't that much smaller anyways.
-          int offsetDelta = startOffset - lastOffset;
-          int offsetLength = endOffset - startOffset;
-          if (offsetLength != lastOffsetLength) {
-            buffer.writeVInt(offsetDelta << 1 | 1);
-            buffer.writeVInt(offsetLength);
-          } else {
-            buffer.writeVInt(offsetDelta << 1);
-          }
-          lastOffset = startOffset;
-          lastOffsetLength = offsetLength;
-        }
-        
-        if (payloadLen > 0) {
-          buffer.writeBytes(payload.bytes, payload.offset, payloadLen);
-        }
-      }
-
-      @Override
-      public void finishDoc() {
-      }
-
-      public PostingsWriter reset() {
-        Debug.Assert( buffer.getFilePointer() == 0;
-        lastDocID = 0;
-        docCount = 0;
-        lastPayloadLen = 0;
-        // force first offset to write its length
-        lastOffsetLength = -1;
-        return this;
-      }
-    }
-
-    private final PostingsWriter postingsWriter = new PostingsWriter();
-
-    @Override
-    public PostingsConsumer startTerm(BytesRef text) {
-      //System.out.println("  startTerm term=" + text.utf8ToString());
-      return postingsWriter.reset();
-    }
-
-    private final RAMOutputStream buffer2 = new RAMOutputStream();
-    private final BytesRef spare = new BytesRef();
-    private byte[] finalBuffer = new byte[128];
-
-    private final IntsRef scratchIntsRef = new IntsRef();
-
-    @Override
-    public void finishTerm(BytesRef text, TermStats stats)  {
-
-      Debug.Assert( postingsWriter.docCount == stats.docFreq;
-
-      Debug.Assert( buffer2.getFilePointer() == 0;
-
-      buffer2.writeVInt(stats.docFreq);
-      if (field.getIndexOptions() != IndexOptions.DOCS_ONLY) {
-        buffer2.writeVLong(stats.totalTermFreq-stats.docFreq);
-      }
-      int pos = (int) buffer2.getFilePointer();
-      buffer2.writeTo(finalBuffer, 0);
-      buffer2.reset();
-
-      final int totalBytes = pos + (int) postingsWriter.buffer.getFilePointer();
-      if (totalBytes > finalBuffer.length) {
-        finalBuffer = ArrayUtil.grow(finalBuffer, totalBytes);
-      }
-      postingsWriter.buffer.writeTo(finalBuffer, pos);
-      postingsWriter.buffer.reset();
-
-      spare.bytes = finalBuffer;
-      spare.length = totalBytes;
-
-      //System.out.println("    finishTerm term=" + text.utf8ToString() + " " + totalBytes + " bytes totalTF=" + stats.totalTermFreq);
-      //for(int i=0;i<totalBytes;i++) {
-      //  System.out.println("      " + Integer.toHexString(finalBuffer[i]&0xFF));
-      //}
-
-      builder.add(Util.toIntsRef(text, scratchIntsRef), BytesRef.deepCopyOf(spare));
-      termCount++;
-    }
-
-    @Override
-    public void finish(long sumTotalTermFreq, long sumDocFreq, int docCount)  {
-      if (termCount > 0) {
-        out.writeVInt(termCount);
-        out.writeVInt(field.number);
-        if (field.getIndexOptions() != IndexOptions.DOCS_ONLY) {
-          out.writeVLong(sumTotalTermFreq);
-        }
-        out.writeVLong(sumDocFreq);
-        out.writeVInt(docCount);
-        FST<BytesRef> fst = builder.finish();
-        fst.save(out);
-        //System.out.println("finish field=" + field.name + " fp=" + out.getFilePointer());
-      }
-    }
-
-    @Override
-    public Comparator<BytesRef> getComparator() {
-      return BytesRef.getUTF8SortedAsUnicodeComparator();
-    }
-  }
-
-  private static String EXTENSION = "ram";
-  private static final String CODEC_NAME = "MemoryPostings";
-  private static final int VERSION_START = 0;
-  private static final int VERSION_CURRENT = VERSION_START;
-
-  @Override
-  public FieldsConsumer fieldsConsumer(SegmentWriteState state)  {
-
-    final String fileName = IndexFileNames.segmentFileName(state.segmentInfo.name, state.segmentSuffix, EXTENSION);
-    final IndexOutput out = state.directory.createOutput(fileName, state.context);
-    bool success = false;
-    try {
-      CodecUtil.writeHeader(out, CODEC_NAME, VERSION_CURRENT);
-      success = true;
-    } finally {
-      if (!success) {
-        IOUtils.closeWhileHandlingException(out);
-      }
-    }
-    
-    return new FieldsConsumer() {
-      @Override
-      public TermsConsumer addField(FieldInfo field) {
-        //System.out.println("\naddField field=" + field.name);
-        return new TermsWriter(out, field, doPackFST, acceptableOverheadRatio);
-      }
-
-      @Override
-      public void close()  {
-        // EOF marker:
-        try {
-          out.writeVInt(0);
-          CodecUtil.writeFooter(out);
-        } finally {
-          out.close();
-        }
-      }
-    };
-  }
-
-  private final static class FSTDocsEnum extends DocsEnum {
-    private final IndexOptions indexOptions;
-    private final bool storePayloads;
-    private byte[] buffer = new byte[16];
-    private final ByteArrayDataInput in = new ByteArrayDataInput(buffer);
-
-    private Bits liveDocs;
-    private int docUpto;
-    private int docID = -1;
-    private int accum;
-    private int freq;
-    private int payloadLen;
-    private int numDocs;
-
-    public FSTDocsEnum(IndexOptions indexOptions, bool storePayloads) {
-      this.indexOptions = indexOptions;
-      this.storePayloads = storePayloads;
-    }
-
-    public bool canReuse(IndexOptions indexOptions, bool storePayloads) {
-      return indexOptions == this.indexOptions && storePayloads == this.storePayloads;
-    }
-    
-    public FSTDocsEnum reset(BytesRef bufferIn, Bits liveDocs, int numDocs) {
-      Debug.Assert( numDocs > 0;
-      if (buffer.length < bufferIn.length) {
-        buffer = ArrayUtil.grow(buffer, bufferIn.length);
-      }
-      in.reset(buffer, 0, bufferIn.length);
-      System.arraycopy(bufferIn.bytes, bufferIn.offset, buffer, 0, bufferIn.length);
-      this.liveDocs = liveDocs;
-      docID = -1;
-      accum = 0;
-      docUpto = 0;
-      freq = 1;
-      payloadLen = 0;
-      this.numDocs = numDocs;
-      return this;
-    }
-
-    @Override
-    public int nextDoc() {
-      while(true) {
-        //System.out.println("  nextDoc cycle docUpto=" + docUpto + " numDocs=" + numDocs + " fp=" + in.getPosition() + " this=" + this);
-        if (docUpto == numDocs) {
-          // System.out.println("    END");
-          return docID = NO_MORE_DOCS;
-        }
-        docUpto++;
-        if (indexOptions == IndexOptions.DOCS_ONLY) {
-          accum += in.readVInt();
-        } else {
-          final int code = in.readVInt();
-          accum += code >>> 1;
-          //System.out.println("  docID=" + accum + " code=" + code);
-          if ((code & 1) != 0) {
-            freq = 1;
-          } else {
-            freq = in.readVInt();
-            Debug.Assert( freq > 0;
-          }
-
-          if (indexOptions == IndexOptions.DOCS_AND_FREQS_AND_POSITIONS) {
-            // Skip positions/payloads
-            for(int posUpto=0;posUpto<freq;posUpto++) {
-              if (!storePayloads) {
-                in.readVInt();
-              } else {
-                final int posCode = in.readVInt();
-                if ((posCode & 1) != 0) {
-                  payloadLen = in.readVInt();
-                }
-                in.skipBytes(payloadLen);
-              }
-            }
-          } else if (indexOptions == IndexOptions.DOCS_AND_FREQS_AND_POSITIONS_AND_OFFSETS) {
-            // Skip positions/offsets/payloads
-            for(int posUpto=0;posUpto<freq;posUpto++) {
-              int posCode = in.readVInt();
-              if (storePayloads && ((posCode & 1) != 0)) {
-                payloadLen = in.readVInt();
-              }
-              if ((in.readVInt() & 1) != 0) {
-                // new offset length
-                in.readVInt();
-              }
-              if (storePayloads) {
-                in.skipBytes(payloadLen);
-              }
-            }
-          }
-        }
-
-        if (liveDocs == null || liveDocs.get(accum)) {
-          //System.out.println("    return docID=" + accum + " freq=" + freq);
-          return (docID = accum);
-        }
-      }
-    }
-
-    @Override
-    public int docID() {
-      return docID;
-    }
-
-    @Override
-    public int advance(int target)  {
-      // TODO: we could make more efficient version, but, it
-      // should be rare that this will matter in practice
-      // since usually apps will not store "big" fields in
-      // this codec!
-      return slowAdvance(target);
-    }
-
-    @Override
-    public int freq() {
-      return freq;
-    }
-    
-    @Override
-    public long cost() {
-      return numDocs;
-    }
-  }
-
-  private final static class FSTDocsAndPositionsEnum extends DocsAndPositionsEnum {
-    private final bool storePayloads;
-    private byte[] buffer = new byte[16];
-    private final ByteArrayDataInput in = new ByteArrayDataInput(buffer);
-
-    private Bits liveDocs;
-    private int docUpto;
-    private int docID = -1;
-    private int accum;
-    private int freq;
-    private int numDocs;
-    private int posPending;
-    private int payloadLength;
-    final bool storeOffsets;
-    int offsetLength;
-    int startOffset;
-
-    private int pos;
-    private final BytesRef payload = new BytesRef();
-
-    public FSTDocsAndPositionsEnum(bool storePayloads, bool storeOffsets) {
-      this.storePayloads = storePayloads;
-      this.storeOffsets = storeOffsets;
-    }
-
-    public bool canReuse(bool storePayloads, bool storeOffsets) {
-      return storePayloads == this.storePayloads && storeOffsets == this.storeOffsets;
-    }
-    
-    public FSTDocsAndPositionsEnum reset(BytesRef bufferIn, Bits liveDocs, int numDocs) {
-      Debug.Assert( numDocs > 0;
-
-      // System.out.println("D&P reset bytes this=" + this);
-      // for(int i=bufferIn.offset;i<bufferIn.length;i++) {
-      //   System.out.println("  " + Integer.toHexString(bufferIn.bytes[i]&0xFF));
-      // }
-
-      if (buffer.length < bufferIn.length) {
-        buffer = ArrayUtil.grow(buffer, bufferIn.length);
-      }
-      in.reset(buffer, 0, bufferIn.length - bufferIn.offset);
-      System.arraycopy(bufferIn.bytes, bufferIn.offset, buffer, 0, bufferIn.length);
-      this.liveDocs = liveDocs;
-      docID = -1;
-      accum = 0;
-      docUpto = 0;
-      payload.bytes = buffer;
-      payloadLength = 0;
-      this.numDocs = numDocs;
-      posPending = 0;
-      startOffset = storeOffsets ? 0 : -1; // always return -1 if no offsets are stored
-      offsetLength = 0;
-      return this;
-    }
-
-    @Override
-    public int nextDoc() {
-      while (posPending > 0) {
-        nextPosition();
-      }
-      while(true) {
-        //System.out.println("  nextDoc cycle docUpto=" + docUpto + " numDocs=" + numDocs + " fp=" + in.getPosition() + " this=" + this);
-        if (docUpto == numDocs) {
-          //System.out.println("    END");
-          return docID = NO_MORE_DOCS;
-        }
-        docUpto++;
-        
-        final int code = in.readVInt();
-        accum += code >>> 1;
-        if ((code & 1) != 0) {
-          freq = 1;
-        } else {
-          freq = in.readVInt();
-          Debug.Assert( freq > 0;
-        }
-
-        if (liveDocs == null || liveDocs.get(accum)) {
-          pos = 0;
-          startOffset = storeOffsets ? 0 : -1;
-          posPending = freq;
-          //System.out.println("    return docID=" + accum + " freq=" + freq);
-          return (docID = accum);
-        }
-
-        // Skip positions
-        for(int posUpto=0;posUpto<freq;posUpto++) {
-          if (!storePayloads) {
-            in.readVInt();
-          } else {
-            final int skipCode = in.readVInt();
-            if ((skipCode & 1) != 0) {
-              payloadLength = in.readVInt();
-              //System.out.println("    new payloadLen=" + payloadLength);
-            }
-          }
-          
-          if (storeOffsets) {
-            if ((in.readVInt() & 1) != 0) {
-              // new offset length
-              offsetLength = in.readVInt();
-            }
-          }
-          
-          if (storePayloads) {
-            in.skipBytes(payloadLength);
-          }
-        }
-      }
-    }
-
-    @Override
-    public int nextPosition() {
-      //System.out.println("    nextPos storePayloads=" + storePayloads + " this=" + this);
-      Debug.Assert( posPending > 0;
-      posPending--;
-      if (!storePayloads) {
-        pos += in.readVInt();
-      } else {
-        final int code = in.readVInt();
-        pos += code >>> 1;
-        if ((code & 1) != 0) {
-          payloadLength = in.readVInt();
-          //System.out.println("      new payloadLen=" + payloadLength);
-          //} else {
-          //System.out.println("      same payloadLen=" + payloadLength);
-        }
-      }
-      
-      if (storeOffsets) {
-        int offsetCode = in.readVInt();
-        if ((offsetCode & 1) != 0) {
-          // new offset length
-          offsetLength = in.readVInt();
-        }
-        startOffset += offsetCode >>> 1;
-      }
-      
-      if (storePayloads) {
-        payload.offset = in.getPosition();
-        in.skipBytes(payloadLength);
-        payload.length = payloadLength;
-      }
-
-      //System.out.println("      pos=" + pos + " payload=" + payload + " fp=" + in.getPosition());
-      return pos;
-    }
-
-    @Override
-    public int startOffset() {
-      return startOffset;
-    }
-
-    @Override
-    public int endOffset() {
-      return startOffset + offsetLength;
-    }
-
-    @Override
-    public BytesRef getPayload() {
-      return payload.length > 0 ? payload : null;
-    }
-
-    @Override
-    public int docID() {
-      return docID;
-    }
-
-    @Override
-    public int advance(int target)  {
-      // TODO: we could make more efficient version, but, it
-      // should be rare that this will matter in practice
-      // since usually apps will not store "big" fields in
-      // this codec!
-      return slowAdvance(target);
-    }
-
-    @Override
-    public int freq() {
-      return freq;
-    }
-    
-    @Override
-    public long cost() {
-      return numDocs;
-    }
-  }
-
-  private final static class FSTTermsEnum extends TermsEnum {
-    private final FieldInfo field;
-    private final BytesRefFSTEnum<BytesRef> fstEnum;
-    private final ByteArrayDataInput buffer = new ByteArrayDataInput();
-    private bool didDecode;
-
-    private int docFreq;
-    private long totalTermFreq;
-    private BytesRefFSTEnum.InputOutput<BytesRef> current;
-    private BytesRef postingsSpare = new BytesRef();
-
-    public FSTTermsEnum(FieldInfo field, FST<BytesRef> fst) {
-      this.field = field;
-      fstEnum = new BytesRefFSTEnum<>(fst);
-    }
-
-    private void decodeMetaData() {
-      if (!didDecode) {
-        buffer.reset(current.output.bytes, current.output.offset, current.output.length);
-        docFreq = buffer.readVInt();
-        if (field.getIndexOptions() != IndexOptions.DOCS_ONLY) {
-          totalTermFreq = docFreq + buffer.readVLong();
-        } else {
-          totalTermFreq = -1;
-        }
-        postingsSpare.bytes = current.output.bytes;
-        postingsSpare.offset = buffer.getPosition();
-        postingsSpare.length = current.output.length - (buffer.getPosition() - current.output.offset);
-        //System.out.println("  df=" + docFreq + " totTF=" + totalTermFreq + " offset=" + buffer.getPosition() + " len=" + current.output.length);
-        didDecode = true;
-      }
-    }
-
-    @Override
-    public bool seekExact(BytesRef text)  {
-      //System.out.println("te.seekExact text=" + field.name + ":" + text.utf8ToString() + " this=" + this);
-      current = fstEnum.seekExact(text);
-      didDecode = false;
-      return current != null;
-    }
-
-    @Override
-    public SeekStatus seekCeil(BytesRef text)  {
-      //System.out.println("te.seek text=" + field.name + ":" + text.utf8ToString() + " this=" + this);
-      current = fstEnum.seekCeil(text);
-      if (current == null) {
-        return SeekStatus.END;
-      } else {
-
-        // System.out.println("  got term=" + current.input.utf8ToString());
-        // for(int i=0;i<current.output.length;i++) {
-        //   System.out.println("    " + Integer.toHexString(current.output.bytes[i]&0xFF));
-        // }
-
-        didDecode = false;
-
-        if (text.equals(current.input)) {
-          //System.out.println("  found!");
-          return SeekStatus.FOUND;
-        } else {
-          //System.out.println("  not found: " + current.input.utf8ToString());
-          return SeekStatus.NOT_FOUND;
-        }
-      }
-    }
-    
-    @Override
-    public DocsEnum docs(Bits liveDocs, DocsEnum reuse, int flags) {
-      decodeMetaData();
-      FSTDocsEnum docsEnum;
-
-      if (reuse == null || !(reuse instanceof FSTDocsEnum)) {
-        docsEnum = new FSTDocsEnum(field.getIndexOptions(), field.hasPayloads());
-      } else {
-        docsEnum = (FSTDocsEnum) reuse;        
-        if (!docsEnum.canReuse(field.getIndexOptions(), field.hasPayloads())) {
-          docsEnum = new FSTDocsEnum(field.getIndexOptions(), field.hasPayloads());
-        }
-      }
-      return docsEnum.reset(this.postingsSpare, liveDocs, docFreq);
-    }
-
-    @Override
-    public DocsAndPositionsEnum docsAndPositions(Bits liveDocs, DocsAndPositionsEnum reuse, int flags) {
-
-      bool hasOffsets = field.getIndexOptions().compareTo(IndexOptions.DOCS_AND_FREQS_AND_POSITIONS_AND_OFFSETS) >= 0;
-      if (field.getIndexOptions().compareTo(IndexOptions.DOCS_AND_FREQS_AND_POSITIONS) < 0) {
-        return null;
-      }
-      decodeMetaData();
-      FSTDocsAndPositionsEnum docsAndPositionsEnum;
-      if (reuse == null || !(reuse instanceof FSTDocsAndPositionsEnum)) {
-        docsAndPositionsEnum = new FSTDocsAndPositionsEnum(field.hasPayloads(), hasOffsets);
-      } else {
-        docsAndPositionsEnum = (FSTDocsAndPositionsEnum) reuse;        
-        if (!docsAndPositionsEnum.canReuse(field.hasPayloads(), hasOffsets)) {
-          docsAndPositionsEnum = new FSTDocsAndPositionsEnum(field.hasPayloads(), hasOffsets);
-        }
-      }
-      //System.out.println("D&P reset this=" + this);
-      return docsAndPositionsEnum.reset(postingsSpare, liveDocs, docFreq);
-    }
-
-    @Override
-    public BytesRef term() {
-      return current.input;
-    }
-
-    @Override
-    public BytesRef next()  {
-      //System.out.println("te.next");
-      current = fstEnum.next();
-      if (current == null) {
-        //System.out.println("  END");
-        return null;
-      }
-      didDecode = false;
-      //System.out.println("  term=" + field.name + ":" + current.input.utf8ToString());
-      return current.input;
-    }
-
-    @Override
-    public int docFreq() {
-      decodeMetaData();
-      return docFreq;
-    }
-
-    @Override
-    public long totalTermFreq() {
-      decodeMetaData();
-      return totalTermFreq;
-    }
-
-    @Override
-    public Comparator<BytesRef> getComparator() {
-      return BytesRef.getUTF8SortedAsUnicodeComparator();
-    }
-
-    @Override
-    public void seekExact(long ord) {
-      // NOTE: we could add this...
-      throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public long ord() {
-      // NOTE: we could add this...
-      throw new UnsupportedOperationException();
-    }
-  }
-
-  private final static class TermsReader extends Terms {
-
-    private final long sumTotalTermFreq;
-    private final long sumDocFreq;
-    private final int docCount;
-    private final int termCount;
-    private FST<BytesRef> fst;
-    private final ByteSequenceOutputs outputs = ByteSequenceOutputs.getSingleton();
-    private final FieldInfo field;
-
-    public TermsReader(FieldInfos fieldInfos, IndexInput in, int termCount)  {
-      this.termCount = termCount;
-      final int fieldNumber = in.readVInt();
-      field = fieldInfos.fieldInfo(fieldNumber);
-      if (field.getIndexOptions() != IndexOptions.DOCS_ONLY) {
-        sumTotalTermFreq = in.readVLong();
-      } else {
-        sumTotalTermFreq = -1;
-      }
-      sumDocFreq = in.readVLong();
-      docCount = in.readVInt();
-      
-      fst = new FST<>(in, outputs);
-    }
-
-    @Override
-    public long getSumTotalTermFreq() {
-      return sumTotalTermFreq;
-    }
-
-    @Override
-    public long getSumDocFreq() {
-      return sumDocFreq;
-    }
-
-    @Override
-    public int getDocCount() {
-      return docCount;
-    }
-
-    @Override
-    public long size() {
-      return termCount;
-    }
-
-    @Override
-    public TermsEnum iterator(TermsEnum reuse) {
-      return new FSTTermsEnum(field, fst);
-    }
-
-    @Override
-    public Comparator<BytesRef> getComparator() {
-      return BytesRef.getUTF8SortedAsUnicodeComparator();
-    }
-
-    @Override
-    public bool hasFreqs() {
-      return field.getIndexOptions().compareTo(IndexOptions.DOCS_AND_FREQS) >= 0;
-    }
-
-    @Override
-    public bool hasOffsets() {
-      return field.getIndexOptions().compareTo(IndexOptions.DOCS_AND_FREQS_AND_POSITIONS_AND_OFFSETS) >= 0;
-    }
-
-    @Override
-    public bool hasPositions() {
-      return field.getIndexOptions().compareTo(IndexOptions.DOCS_AND_FREQS_AND_POSITIONS) >= 0;
-    }
-    
-    @Override
-    public bool hasPayloads() {
-      return field.hasPayloads();
-    }
-
-    public long ramBytesUsed() {
-      return ((fst!=null) ? fst.sizeInBytes() : 0);
-    }
-  }
-
-  @Override
-  public FieldsProducer fieldsProducer(SegmentReadState state)  {
-    final String fileName = IndexFileNames.segmentFileName(state.segmentInfo.name, state.segmentSuffix, EXTENSION);
-    final ChecksumIndexInput in = state.directory.openChecksumInput(fileName, IOContext.READONCE);
-
-    final SortedMap<String,TermsReader> fields = new TreeMap<>();
-
-    try {
-      CodecUtil.checkHeader(in, CODEC_NAME, VERSION_START, VERSION_CURRENT);
-      while(true) {
-        final int termCount = in.readVInt();
-        if (termCount == 0) {
-          break;
-        }
-        final TermsReader termsReader = new TermsReader(state.fieldInfos, in, termCount);
-        // System.out.println("load field=" + termsReader.field.name);
-        fields.put(termsReader.field.name, termsReader);
-      }
-      CodecUtil.checkFooter(in);
-    } finally {
-      in.close();
-    }
-
-    return new FieldsProducer() {
-      @Override
-      public Iterator<String> iterator() {
-        return Collections.unmodifiableSet(fields.keySet()).iterator();
-      }
-
-      @Override
-      public Terms terms(String field) {
-        return fields.get(field);
-      }
-      
-      @Override
-      public int size() {
-        return fields.size();
-      }
-
-      @Override
-      public void close() {
-        // Drop ref to FST:
-        for(TermsReader termsReader : fields.values()) {
-          termsReader.fst = null;
-        }
-      }
-
-      @Override
-      public long ramBytesUsed() {
-        long sizeInBytes = 0;
-        for(Map.Entry<String,TermsReader> entry: fields.entrySet()) {
-          sizeInBytes += (entry.getKey().length() * RamUsageEstimator.NUM_BYTES_CHAR);
-          sizeInBytes += entry.getValue().ramBytesUsed();
-        }
-        return sizeInBytes;
-      }
-      
-      @Override
-      public void checkIntegrity()  {}
-    };
-  }
-}
+using System;
+using System.Diagnostics;
+using System.Collections.Generic;
+
+namespace org.apache.lucene.codecs.memory
+{
+
+	/*
+	 * Licensed to the Apache Software Foundation (ASF) under one or more
+	 * contributor license agreements.  See the NOTICE file distributed with
+	 * this work for additional information regarding copyright ownership.
+	 * The ASF licenses this file to You under the Apache License, Version 2.0
+	 * (the "License"); you may not use this file except in compliance with
+	 * the License.  You may obtain a copy of the License at
+	 *
+	 *     http://www.apache.org/licenses/LICENSE-2.0
+	 *
+	 * Unless required by applicable law or agreed to in writing, software
+	 * distributed under the License is distributed on an "AS IS" BASIS,
+	 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+	 * See the License for the specific language governing permissions and
+	 * limitations under the License.
+	 */
+
+
+	using DocsAndPositionsEnum = org.apache.lucene.index.DocsAndPositionsEnum;
+	using DocsEnum = org.apache.lucene.index.DocsEnum;
+	using IndexOptions = org.apache.lucene.index.FieldInfo.IndexOptions;
+	using FieldInfo = org.apache.lucene.index.FieldInfo;
+	using FieldInfos = org.apache.lucene.index.FieldInfos;
+	using IndexFileNames = org.apache.lucene.index.IndexFileNames;
+	using SegmentReadState = org.apache.lucene.index.SegmentReadState;
+	using SegmentWriteState = org.apache.lucene.index.SegmentWriteState;
+	using Terms = org.apache.lucene.index.Terms;
+	using TermsEnum = org.apache.lucene.index.TermsEnum;
+	using ByteArrayDataInput = org.apache.lucene.store.ByteArrayDataInput;
+	using ChecksumIndexInput = org.apache.lucene.store.ChecksumIndexInput;
+	using IOContext = org.apache.lucene.store.IOContext;
+	using IndexInput = org.apache.lucene.store.IndexInput;
+	using IndexOutput = org.apache.lucene.store.IndexOutput;
+	using RAMOutputStream = org.apache.lucene.store.RAMOutputStream;
+	using ArrayUtil = org.apache.lucene.util.ArrayUtil;
+	using Bits = org.apache.lucene.util.Bits;
+	using BytesRef = org.apache.lucene.util.BytesRef;
+	using IOUtils = org.apache.lucene.util.IOUtils;
+	using IntsRef = org.apache.lucene.util.IntsRef;
+	using RamUsageEstimator = org.apache.lucene.util.RamUsageEstimator;
+	using Builder = org.apache.lucene.util.fst.Builder;
+	using ByteSequenceOutputs = org.apache.lucene.util.fst.ByteSequenceOutputs;
+	using BytesRefFSTEnum = org.apache.lucene.util.fst.BytesRefFSTEnum;
+	using FST = org.apache.lucene.util.fst.FST;
+	using Util = org.apache.lucene.util.fst.Util;
+	using PackedInts = org.apache.lucene.util.packed.PackedInts;
+
+	// TODO: would be nice to somehow allow this to act like
+	// InstantiatedIndex, by never writing to disk; ie you write
+	// to this Codec in RAM only and then when you open a reader
+	// it pulls the FST directly from what you wrote w/o going
+	// to disk.
+
+	/// <summary>
+	/// Stores terms & postings (docs, positions, payloads) in
+	///  RAM, using an FST.
+	/// 
+	/// <para>Note that this codec implements advance as a linear
+	/// scan!  This means if you store large fields in here,
+	/// queries that rely on advance will (AND BooleanQuery,
+	/// PhraseQuery) will be relatively slow!
+	/// 
+	/// @lucene.experimental 
+	/// </para>
+	/// </summary>
+
+	// TODO: Maybe name this 'Cached' or something to reflect
+	// the reality that it is actually written to disk, but
+	// loads itself in ram?
+	public sealed class MemoryPostingsFormat : PostingsFormat
+	{
+
+	  private readonly bool doPackFST;
+	  private readonly float acceptableOverheadRatio;
+
+	  public MemoryPostingsFormat() : this(false, PackedInts.DEFAULT)
+	  {
+	  }
+
+	  /// <summary>
+	  /// Create MemoryPostingsFormat, specifying advanced FST options. </summary>
+	  /// <param name="doPackFST"> true if a packed FST should be built.
+	  ///        NOTE: packed FSTs are limited to ~2.1 GB of postings. </param>
+	  /// <param name="acceptableOverheadRatio"> allowable overhead for packed ints
+	  ///        during FST construction. </param>
+	  public MemoryPostingsFormat(bool doPackFST, float acceptableOverheadRatio) : base("Memory")
+	  {
+		this.doPackFST = doPackFST;
+		this.acceptableOverheadRatio = acceptableOverheadRatio;
+	  }
+
+	  public override string ToString()
+	  {
+		return "PostingsFormat(name=" + Name + " doPackFST= " + doPackFST + ")";
+	  }
+
+	  private sealed class TermsWriter : TermsConsumer
+	  {
+		  internal bool InstanceFieldsInitialized = false;
+
+		  internal void InitializeInstanceFields()
+		  {
+			  postingsWriter = new PostingsWriter(this);
+		  }
+
+		internal readonly IndexOutput @out;
+		internal readonly FieldInfo field;
+		internal readonly Builder<BytesRef> builder;
+		internal readonly ByteSequenceOutputs outputs = ByteSequenceOutputs.Singleton;
+		internal readonly bool doPackFST;
+		internal readonly float acceptableOverheadRatio;
+		internal int termCount;
+
+		public TermsWriter(IndexOutput @out, FieldInfo field, bool doPackFST, float acceptableOverheadRatio)
+		{
+			if (!InstanceFieldsInitialized)
+			{
+				InitializeInstanceFields();
+				InstanceFieldsInitialized = true;
+			}
+		  this.@out = @out;
+		  this.field = field;
+		  this.doPackFST = doPackFST;
+		  this.acceptableOverheadRatio = acceptableOverheadRatio;
+		  builder = new Builder<>(FST.INPUT_TYPE.BYTE1, 0, 0, true, true, int.MaxValue, outputs, null, doPackFST, acceptableOverheadRatio, true, 15);
+		}
+
+		private class PostingsWriter : PostingsConsumer
+		{
+			private readonly MemoryPostingsFormat.TermsWriter outerInstance;
+
+			public PostingsWriter(MemoryPostingsFormat.TermsWriter outerInstance)
+			{
+				this.outerInstance = outerInstance;
+			}
+
+		  internal int lastDocID;
+		  internal int lastPos;
+		  internal int lastPayloadLen;
+
+		  // NOTE: not private so we don't pay access check at runtime:
+		  internal int docCount;
+		  internal RAMOutputStream buffer = new RAMOutputStream();
+
+		  internal int lastOffsetLength;
+		  internal int lastOffset;
+
+//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
+//ORIGINAL LINE: @Override public void startDoc(int docID, int termDocFreq) throws java.io.IOException
+		  public override void startDoc(int docID, int termDocFreq)
+		  {
+			//System.out.println("    startDoc docID=" + docID + " freq=" + termDocFreq);
+//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
+//ORIGINAL LINE: final int delta = docID - lastDocID;
+			int delta = docID - lastDocID;
+			Debug.Assert(docID == 0 || delta > 0);
+			lastDocID = docID;
+			docCount++;
+
+			if (outerInstance.field.IndexOptions == IndexOptions.DOCS_ONLY)
+			{
+			  buffer.writeVInt(delta);
+			}
+			else if (termDocFreq == 1)
+			{
+			  buffer.writeVInt((delta << 1) | 1);
+			}
+			else
+			{
+			  buffer.writeVInt(delta << 1);
+			  Debug.Assert(termDocFreq > 0);
+			  buffer.writeVInt(termDocFreq);
+			}
+
+			lastPos = 0;
+			lastOffset = 0;
+		  }
+
+//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
+//ORIGINAL LINE: @Override public void addPosition(int pos, org.apache.lucene.util.BytesRef payload, int startOffset, int endOffset) throws java.io.IOException
+		  public override void addPosition(int pos, BytesRef payload, int startOffset, int endOffset)
+		  {
+			Debug.Assert(payload == null || outerInstance.field.hasPayloads());
+
+			//System.out.println("      addPos pos=" + pos + " payload=" + payload);
+
+//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
+//ORIGINAL LINE: final int delta = pos - lastPos;
+			int delta = pos - lastPos;
+			Debug.Assert(delta >= 0);
+			lastPos = pos;
+
+			int payloadLen = 0;
+
+			if (outerInstance.field.hasPayloads())
+			{
+			  payloadLen = payload == null ? 0 : payload.length;
+			  if (payloadLen != lastPayloadLen)
+			  {
+				lastPayloadLen = payloadLen;
+				buffer.writeVInt((delta << 1) | 1);
+				buffer.writeVInt(payloadLen);
+			  }
+			  else
+			  {
+				buffer.writeVInt(delta << 1);
+			  }
+			}
+			else
+			{
+			  buffer.writeVInt(delta);
+			}
+
+			if (outerInstance.field.IndexOptions.compareTo(IndexOptions.DOCS_AND_FREQS_AND_POSITIONS_AND_OFFSETS) >= 0)
+			{
+			  // don't use startOffset - lastEndOffset, because this creates lots of negative vints for synonyms,
+			  // and the numbers aren't that much smaller anyways.
+			  int offsetDelta = startOffset - lastOffset;
+			  int offsetLength = endOffset - startOffset;
+			  if (offsetLength != lastOffsetLength)
+			  {
+				buffer.writeVInt(offsetDelta << 1 | 1);
+				buffer.writeVInt(offsetLength);
+			  }
+			  else
+			  {
+				buffer.writeVInt(offsetDelta << 1);
+			  }
+			  lastOffset = startOffset;
+			  lastOffsetLength = offsetLength;
+			}
+
+			if (payloadLen > 0)
+			{
+			  buffer.writeBytes(payload.bytes, payload.offset, payloadLen);
+			}
+		  }
+
+		  public override void finishDoc()
+		  {
+		  }
+
+		  public virtual PostingsWriter reset()
+		  {
+			Debug.Assert(buffer.FilePointer == 0);
+			lastDocID = 0;
+			docCount = 0;
+			lastPayloadLen = 0;
+			// force first offset to write its length
+			lastOffsetLength = -1;
+			return this;
+		  }
+		}
+
+		internal PostingsWriter postingsWriter;
+
+		public override PostingsConsumer startTerm(BytesRef text)
+		{
+		  //System.out.println("  startTerm term=" + text.utf8ToString());
+		  return postingsWriter.reset();
+		}
+
+		internal readonly RAMOutputStream buffer2 = new RAMOutputStream();
+		internal readonly BytesRef spare = new BytesRef();
+		internal sbyte[] finalBuffer = new sbyte[128];
+
+		internal readonly IntsRef scratchIntsRef = new IntsRef();
+
+//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
+//ORIGINAL LINE: @Override public void finishTerm(org.apache.lucene.util.BytesRef text, org.apache.lucene.codecs.TermStats stats) throws java.io.IOException
+		public override void finishTerm(BytesRef text, TermStats stats)
+		{
+
+		  Debug.Assert(postingsWriter.docCount == stats.docFreq);
+
+		  Debug.Assert(buffer2.FilePointer == 0);
+
+		  buffer2.writeVInt(stats.docFreq);
+		  if (field.IndexOptions != IndexOptions.DOCS_ONLY)
+		  {
+			buffer2.writeVLong(stats.totalTermFreq - stats.docFreq);
+		  }
+		  int pos = (int) buffer2.FilePointer;
+		  buffer2.writeTo(finalBuffer, 0);
+		  buffer2.reset();
+
+//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
+//ORIGINAL LINE: final int totalBytes = pos + (int) postingsWriter.buffer.getFilePointer();
+		  int totalBytes = pos + (int) postingsWriter.buffer.FilePointer;
+		  if (totalBytes > finalBuffer.Length)
+		  {
+			finalBuffer = ArrayUtil.grow(finalBuffer, totalBytes);
+		  }
+		  postingsWriter.buffer.writeTo(finalBuffer, pos);
+		  postingsWriter.buffer.reset();
+
+		  spare.bytes = finalBuffer;
+		  spare.length = totalBytes;
+
+		  //System.out.println("    finishTerm term=" + text.utf8ToString() + " " + totalBytes + " bytes totalTF=" + stats.totalTermFreq);
+		  //for(int i=0;i<totalBytes;i++) {
+		  //  System.out.println("      " + Integer.toHexString(finalBuffer[i]&0xFF));
+		  //}
+
+		  builder.add(Util.toIntsRef(text, scratchIntsRef), BytesRef.deepCopyOf(spare));
+		  termCount++;
+		}
+
+//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
+//ORIGINAL LINE: @Override public void finish(long sumTotalTermFreq, long sumDocFreq, int docCount) throws java.io.IOException
+		public override void finish(long sumTotalTermFreq, long sumDocFreq, int docCount)
+		{
+		  if (termCount > 0)
+		  {
+			@out.writeVInt(termCount);
+			@out.writeVInt(field.number);
+			if (field.IndexOptions != IndexOptions.DOCS_ONLY)
+			{
+			  @out.writeVLong(sumTotalTermFreq);
+			}
+			@out.writeVLong(sumDocFreq);
+			@out.writeVInt(docCount);
+			FST<BytesRef> fst = builder.finish();
+			fst.save(@out);
+			//System.out.println("finish field=" + field.name + " fp=" + out.getFilePointer());
+		  }
+		}
+
+		public override IComparer<BytesRef> Comparator
+		{
+			get
+			{
+			  return BytesRef.UTF8SortedAsUnicodeComparator;
+			}
+		}
+	  }
+
+	  private static string EXTENSION = "ram";
+	  private const string CODEC_NAME = "MemoryPostings";
+	  private const int VERSION_START = 0;
+	  private const int VERSION_CURRENT = VERSION_START;
+
+//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
+//ORIGINAL LINE: @Override public org.apache.lucene.codecs.FieldsConsumer fieldsConsumer(org.apache.lucene.index.SegmentWriteState state) throws java.io.IOException
+	  public override FieldsConsumer fieldsConsumer(SegmentWriteState state)
+	  {
+
+//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
+//ORIGINAL LINE: final String fileName = org.apache.lucene.index.IndexFileNames.segmentFileName(state.segmentInfo.name, state.segmentSuffix, EXTENSION);
+		string fileName = IndexFileNames.segmentFileName(state.segmentInfo.name, state.segmentSuffix, EXTENSION);
+//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
+//ORIGINAL LINE: final org.apache.lucene.store.IndexOutput out = state.directory.createOutput(fileName, state.context);
+		IndexOutput @out = state.directory.createOutput(fileName, state.context);
+		bool success = false;
+		try
+		{
+		  CodecUtil.writeHeader(@out, CODEC_NAME, VERSION_CURRENT);
+		  success = true;
+		}
+		finally
+		{
+		  if (!success)
+		  {
+			IOUtils.closeWhileHandlingException(@out);
+		  }
+		}
+
+		return new FieldsConsumerAnonymousInnerClassHelper(this, @out);
+	  }
+
+	  private class FieldsConsumerAnonymousInnerClassHelper : FieldsConsumer
+	  {
+		  private readonly MemoryPostingsFormat outerInstance;
+
+		  private IndexOutput @out;
+
+		  public FieldsConsumerAnonymousInnerClassHelper(MemoryPostingsFormat outerInstance, IndexOutput @out)
+		  {
+			  this.outerInstance = outerInstance;
+			  this.@out = @out;
+		  }
+
+		  public override TermsConsumer addField(FieldInfo field)
+		  {
+			//System.out.println("\naddField field=" + field.name);
+			return new TermsWriter(@out, field, outerInstance.doPackFST, outerInstance.acceptableOverheadRatio);
+		  }
+
+//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
+//ORIGINAL LINE: @Override public void close() throws java.io.IOException
+		  public override void close()
+		  {
+			// EOF marker:
+			try
+			{
+			  @out.writeVInt(0);
+			  CodecUtil.writeFooter(@out);
+			}
+			finally
+			{
+			  @out.close();
+			}
+		  }
+	  }
+
+	  private sealed class FSTDocsEnum : DocsEnum
+	  {
+		  internal bool InstanceFieldsInitialized = false;
+
+		  internal void InitializeInstanceFields()
+		  {
+			  @in = new ByteArrayDataInput(buffer);
+		  }
+
+		internal readonly IndexOptions indexOptions;
+		internal readonly bool storePayloads;
+		internal sbyte[] buffer = new sbyte[16];
+		internal ByteArrayDataInput @in;
+
+		internal Bits liveDocs;
+		internal int docUpto;
+		internal int docID_Renamed = -1;
+		internal int accum;
+		internal int freq_Renamed;
+		internal int payloadLen;
+		internal int numDocs;
+
+		public FSTDocsEnum(IndexOptions indexOptions, bool storePayloads)
+		{
+			if (!InstanceFieldsInitialized)
+			{
+				InitializeInstanceFields();
+				InstanceFieldsInitialized = true;
+			}
+		  this.indexOptions = indexOptions;
+		  this.storePayloads = storePayloads;
+		}
+
+		public bool canReuse(IndexOptions indexOptions, bool storePayloads)
+		{
+		  return indexOptions == this.indexOptions && storePayloads == this.storePayloads;
+		}
+
+		public FSTDocsEnum reset(BytesRef bufferIn, Bits liveDocs, int numDocs)
+		{
+		  Debug.Assert(numDocs > 0);
+		  if (buffer.Length < bufferIn.length)
+		  {
+			buffer = ArrayUtil.grow(buffer, bufferIn.length);
+		  }
+		  @in.reset(buffer, 0, bufferIn.length);
+		  Array.Copy(bufferIn.bytes, bufferIn.offset, buffer, 0, bufferIn.length);
+		  this.liveDocs = liveDocs;
+		  docID_Renamed = -1;
+		  accum = 0;
+		  docUpto = 0;
+		  freq_Renamed = 1;
+		  payloadLen = 0;
+		  this.numDocs = numDocs;
+		  return this;
+		}
+
+		public override int nextDoc()
+		{
+		  while (true)
+		  {
+			//System.out.println("  nextDoc cycle docUpto=" + docUpto + " numDocs=" + numDocs + " fp=" + in.getPosition() + " this=" + this);
+			if (docUpto == numDocs)
+			{
+			  // System.out.println("    END");
+			  return docID_Renamed = NO_MORE_DOCS;
+			}
+			docUpto++;
+			if (indexOptions == IndexOptions.DOCS_ONLY)
+			{
+			  accum += @in.readVInt();
+			}
+			else
+			{
+//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
+//ORIGINAL LINE: final int code = in.readVInt();
+			  int code = @in.readVInt();
+			  accum += (int)((uint)code >> 1);
+			  //System.out.println("  docID=" + accum + " code=" + code);
+			  if ((code & 1) != 0)
+			  {
+				freq_Renamed = 1;
+			  }
+			  else
+			  {
+				freq_Renamed = @in.readVInt();
+				Debug.Assert(freq_Renamed > 0);
+			  }
+
+			  if (indexOptions == IndexOptions.DOCS_AND_FREQS_AND_POSITIONS)
+			  {
+				// Skip positions/payloads
+				for (int posUpto = 0;posUpto < freq_Renamed;posUpto++)
+				{
+				  if (!storePayloads)
+				  {
+					@in.readVInt();
+				  }
+				  else
+				  {
+//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
+//ORIGINAL LINE: final int posCode = in.readVInt();
+					int posCode = @in.readVInt();
+					if ((posCode & 1) != 0)
+					{
+					  payloadLen = @in.readVInt();
+					}
+					@in.skipBytes(payloadLen);
+				  }
+				}
+			  }
+			  else if (indexOptions == IndexOptions.DOCS_AND_FREQS_AND_POSITIONS_AND_OFFSETS)
+			  {
+				// Skip positions/offsets/payloads
+				for (int posUpto = 0;posUpto < freq_Renamed;posUpto++)
+				{
+				  int posCode = @in.readVInt();
+				  if (storePayloads && ((posCode & 1) != 0))
+				  {
+					payloadLen = @in.readVInt();
+				  }
+				  if ((@in.readVInt() & 1) != 0)
+				  {
+					// new offset length
+					@in.readVInt();
+				  }
+				  if (storePayloads)
+				  {
+					@in.skipBytes(payloadLen);
+				  }
+				}
+			  }
+			}
+
+			if (liveDocs == null || liveDocs.get(accum))
+			{
+			  //System.out.println("    return docID=" + accum + " freq=" + freq);
+			  return (docID_Renamed = accum);
+			}
+		  }
+		}
+
+		public override int docID()
+		{
+		  return docID_Renamed;
+		}
+
+//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
+//ORIGINAL LINE: @Override public int advance(int target) throws java.io.IOException
+		public override int advance(int target)
+		{
+		  // TODO: we could make more efficient version, but, it
+		  // should be rare that this will matter in practice
+		  // since usually apps will not store "big" fields in
+		  // this codec!
+		  return slowAdvance(target);
+		}
+
+		public override int freq()
+		{
+		  return freq_Renamed;
+		}
+
+		public override long cost()
+		{
+		  return numDocs;
+		}
+	  }
+
+	  private sealed class FSTDocsAndPositionsEnum : DocsAndPositionsEnum
+	  {
+		  internal bool InstanceFieldsInitialized = false;
+
+		  internal void InitializeInstanceFields()
+		  {
+			  @in = new ByteArrayDataInput(buffer);
+		  }
+
+		internal readonly bool storePayloads;
+		internal sbyte[] buffer = new sbyte[16];
+		internal ByteArrayDataInput @in;
+
+		internal Bits liveDocs;
+		internal int docUpto;
+		internal int docID_Renamed = -1;
+		internal int accum;
+		internal int freq_Renamed;
+		internal int numDocs;
+		internal int posPending;
+		internal int payloadLength;
+		internal readonly bool storeOffsets;
+		internal int offsetLength;
+		internal int startOffset_Renamed;
+
+		internal int pos;
+		internal readonly BytesRef payload = new BytesRef();
+
+		public FSTDocsAndPositionsEnum(bool storePayloads, bool storeOffsets)
+		{
+			if (!InstanceFieldsInitialized)
+			{
+				InitializeInstanceFields();
+				InstanceFieldsInitialized = true;
+			}
+		  this.storePayloads = storePayloads;
+		  this.storeOffsets = storeOffsets;
+		}
+
+		public bool canReuse(bool storePayloads, bool storeOffsets)
+		{
+		  return storePayloads == this.storePayloads && storeOffsets == this.storeOffsets;
+		}
+
+		public FSTDocsAndPositionsEnum reset(BytesRef bufferIn, Bits liveDocs, int numDocs)
+		{
+		  Debug.Assert(numDocs > 0);
+
+		  // System.out.println("D&P reset bytes this=" + this);
+		  // for(int i=bufferIn.offset;i<bufferIn.length;i++) {
+		  //   System.out.println("  " + Integer.toHexString(bufferIn.bytes[i]&0xFF));
+		  // }
+
+		  if (buffer.Length < bufferIn.length)
+		  {
+			buffer = ArrayUtil.grow(buffer, bufferIn.length);
+		  }
+		  @in.reset(buffer, 0, bufferIn.length - bufferIn.offset);
+		  Array.Copy(bufferIn.bytes, bufferIn.offset, buffer, 0, bufferIn.length);
+		  this.liveDocs = liveDocs;
+		  docID_Renamed = -1;
+		  accum = 0;
+		  docUpto = 0;
+		  payload.bytes = buffer;
+		  payloadLength = 0;
+		  this.numDocs = numDocs;
+		  posPending = 0;
+		  startOffset_Renamed = storeOffsets ? 0 : -1; // always return -1 if no offsets are stored
+		  offsetLength = 0;
+		  return this;
+		}
+
+		public override int nextDoc()
+		{
+		  while (posPending > 0)
+		  {
+			nextPosition();
+		  }
+		  while (true)
+		  {
+			//System.out.println("  nextDoc cycle docUpto=" + docUpto + " numDocs=" + numDocs + " fp=" + in.getPosition() + " this=" + this);
+			if (docUpto == numDocs)
+			{
+			  //System.out.println("    END");
+			  return docID_Renamed = NO_MORE_DOCS;
+			}
+			docUpto++;
+
+//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
+//ORIGINAL LINE: final int code = in.readVInt();
+			int code = @in.readVInt();
+			accum += (int)((uint)code >> 1);
+			if ((code & 1) != 0)
+			{
+			  freq_Renamed = 1;
+			}
+			else
+			{
+			  freq_Renamed = @in.readVInt();
+			  Debug.Assert(freq_Renamed > 0);
+			}
+
+			if (liveDocs == null || liveDocs.get(accum))
+			{
+			  pos = 0;
+			  startOffset_Renamed = storeOffsets ? 0 : -1;
+			  posPending = freq_Renamed;
+			  //System.out.println("    return docID=" + accum + " freq=" + freq);
+			  return (docID_Renamed = accum);
+			}
+
+			// Skip positions
+			for (int posUpto = 0;posUpto < freq_Renamed;posUpto++)
+			{
+			  if (!storePayloads)
+			  {
+				@in.readVInt();
+			  }
+			  else
+			  {
+//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
+//ORIGINAL LINE: final int skipCode = in.readVInt();
+				int skipCode = @in.readVInt();
+				if ((skipCode & 1) != 0)
+				{
+				  payloadLength = @in.readVInt();
+				  //System.out.println("    new payloadLen=" + payloadLength);
+				}
+			  }
+
+			  if (storeOffsets)
+			  {
+				if ((@in.readVInt() & 1) != 0)
+				{
+				  // new offset length
+				  offsetLength = @in.readVInt();
+				}
+			  }
+
+			  if (storePayloads)
+			  {
+				@in.skipBytes(payloadLength);
+			  }
+			}
+		  }
+		}
+
+		public override int nextPosition()
+		{
+		  //System.out.println("    nextPos storePayloads=" + storePayloads + " this=" + this);
+		  Debug.Assert(posPending > 0);
+		  posPending--;
+		  if (!storePayloads)
+		  {
+			pos += @in.readVInt();
+		  }
+		  else
+		  {
+//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
+//ORIGINAL LINE: final int code = in.readVInt();
+			int code = @in.readVInt();
+			pos += (int)((uint)code >> 1);
+			if ((code & 1) != 0)
+			{
+			  payloadLength = @in.readVInt();
+			  //System.out.println("      new payloadLen=" + payloadLength);
+			  //} else {
+			  //System.out.println("      same payloadLen=" + payloadLength);
+			}
+		  }
+
+		  if (storeOffsets)
+		  {
+			int offsetCode = @in.readVInt();
+			if ((offsetCode & 1) != 0)
+			{
+			  // new offset length
+			  offsetLength = @in.readVInt();
+			}
+			startOffset_Renamed += (int)((uint)offsetCode >> 1);
+		  }
+
+		  if (storePayloads)
+		  {
+			payload.offset = @in.Position;
+			@in.skipBytes(payloadLength);
+			payload.length = payloadLength;
+		  }
+
+		  //System.out.println("      pos=" + pos + " payload=" + payload + " fp=" + in.getPosition());
+		  return pos;
+		}
+
+		public override int startOffset()
+		{
+		  return startOffset_Renamed;
+		}
+
+		public override int endOffset()
+		{
+		  return startOffset_Renamed + offsetLength;
+		}
+
+		public override BytesRef Payload
+		{
+			get
+			{
+			  return payload.length > 0 ? payload : null;
+			}
+		}
+
+		public override int docID()
+		{
+		  return docID_Renamed;
+		}
+
+//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
+//ORIGINAL LINE: @Override public int advance(int target) throws java.io.IOException
+		public override int advance(int target)
+		{
+		  // TODO: we could make more efficient version, but, it
+		  // should be rare that this will matter in practice
+		  // since usually apps will not store "big" fields in
+		  // this codec!
+		  return slowAdvance(target);
+		}
+
+		public override int freq()
+		{
+		  return freq_Renamed;
+		}
+
+		public override long cost()
+		{
+		  return numDocs;
+		}
+	  }
+
+	  private sealed class FSTTermsEnum : TermsEnum
+	  {
+		internal readonly FieldInfo field;
+		internal readonly BytesRefFSTEnum<BytesRef> fstEnum;
+		internal readonly ByteArrayDataInput buffer = new ByteArrayDataInput();
+		internal bool didDecode;
+
+		internal int docFreq_Renamed;
+		internal long totalTermFreq_Renamed;
+		internal BytesRefFSTEnum.InputOutput<BytesRef> current;
+		internal BytesRef postingsSpare = new BytesRef();
+
+		public FSTTermsEnum(FieldInfo field, FST<BytesRef> fst)
+		{
+		  this.field = field;
+		  fstEnum = new BytesRefFSTEnum<>(fst);
+		}
+
+		internal void decodeMetaData()
+		{
+		  if (!didDecode)
+		  {
+			buffer.reset(current.output.bytes, current.output.offset, current.output.length);
+			docFreq_Renamed = buffer.readVInt();
+			if (field.IndexOptions != IndexOptions.DOCS_ONLY)
+			{
+			  totalTermFreq_Renamed = docFreq_Renamed + buffer.readVLong();
+			}
+			else
+			{
+			  totalTermFreq_Renamed = -1;
+			}
+			postingsSpare.bytes = current.output.bytes;
+			postingsSpare.offset = buffer.Position;
+			postingsSpare.length = current.output.length - (buffer.Position - current.output.offset);
+			//System.out.println("  df=" + docFreq + " totTF=" + totalTermFreq + " offset=" + buffer.getPosition() + " len=" + current.output.length);
+			didDecode = true;
+		  }
+		}
+
+//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
+//ORIGINAL LINE: @Override public boolean seekExact(org.apache.lucene.util.BytesRef text) throws java.io.IOException
+		public override bool seekExact(BytesRef text)
+		{
+		  //System.out.println("te.seekExact text=" + field.name + ":" + text.utf8ToString() + " this=" + this);
+		  current = fstEnum.seekExact(text);
+		  didDecode = false;
+		  return current != null;
+		}
+
+//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
+//ORIGINAL LINE: @Override public SeekStatus seekCeil(org.apache.lucene.util.BytesRef text) throws java.io.IOException
+		public override SeekStatus seekCeil(BytesRef text)
+		{
+		  //System.out.println("te.seek text=" + field.name + ":" + text.utf8ToString() + " this=" + this);
+		  current = fstEnum.seekCeil(text);
+		  if (current == null)
+		  {
+			return SeekStatus.END;
+		  }
+		  else
+		  {
+
+			// System.out.println("  got term=" + current.input.utf8ToString());
+			// for(int i=0;i<current.output.length;i++) {
+			//   System.out.println("    " + Integer.toHexString(current.output.bytes[i]&0xFF));
+			// }
+
+			didDecode = false;
+
+			if (text.Equals(current.input))
+			{
+			  //System.out.println("  found!");
+			  return SeekStatus.FOUND;
+			}
+			else
+			{
+			  //System.out.println("  not found: " + current.input.utf8ToString());
+			  return SeekStatus.NOT_FOUND;
+			}
+		  }
+		}
+
+		public override DocsEnum docs(Bits liveDocs, DocsEnum reuse, int flags)
+		{
+		  decodeMetaData();
+		  FSTDocsEnum docsEnum;
+
+		  if (reuse == null || !(reuse is FSTDocsEnum))
+		  {
+			docsEnum = new FSTDocsEnum(field.IndexOptions, field.hasPayloads());
+		  }
+		  else
+		  {
+			docsEnum = (FSTDocsEnum) reuse;
+			if (!docsEnum.canReuse(field.IndexOptions, field.hasPayloads()))
+			{
+			  docsEnum = new FSTDocsEnum(field.IndexOptions, field.hasPayloads());
+			}
+		  }
+		  return docsEnum.reset(this.postingsSpare, liveDocs, docFreq_Renamed);
+		}
+
+		public override DocsAndPositionsEnum docsAndPositions(Bits liveDocs, DocsAndPositionsEnum reuse, int flags)
+		{
+
+		  bool hasOffsets = field.IndexOptions.compareTo(IndexOptions.DOCS_AND_FREQS_AND_POSITIONS_AND_OFFSETS) >= 0;
+		  if (field.IndexOptions.compareTo(IndexOptions.DOCS_AND_FREQS_AND_POSITIONS) < 0)
+		  {
+			return null;
+		  }
+		  decodeMetaData();
+		  FSTDocsAndPositionsEnum docsAndPositionsEnum;
+		  if (reuse == null || !(reuse is FSTDocsAndPositionsEnum))
+		  {
+			docsAndPositionsEnum = new FSTDocsAndPositionsEnum(field.hasPayloads(), hasOffsets);
+		  }
+		  else
+		  {
+			docsAndPositionsEnum = (FSTDocsAndPositionsEnum) reuse;
+			if (!docsAndPositionsEnum.canReuse(field.hasPayloads(), hasOffsets))
+			{
+			  docsAndPositionsEnum = new FSTDocsAndPositionsEnum(field.hasPayloads(), hasOffsets);
+			}
+		  }
+		  //System.out.println("D&P reset this=" + this);
+		  return docsAndPositionsEnum.reset(postingsSpare, liveDocs, docFreq_Renamed);
+		}
+
+		public override BytesRef term()
+		{
+		  return current.input;
+		}
+
+//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
+//ORIGINAL LINE: @Override public org.apache.lucene.util.BytesRef next() throws java.io.IOException
+		public override BytesRef next()
+		{
+		  //System.out.println("te.next");
+		  current = fstEnum.next();
+		  if (current == null)
+		  {
+			//System.out.println("  END");
+			return null;
+		  }
+		  didDecode = false;
+		  //System.out.println("  term=" + field.name + ":" + current.input.utf8ToString());
+		  return current.input;
+		}
+
+		public override int docFreq()
+		{
+		  decodeMetaData();
+		  return docFreq_Renamed;
+		}
+
+		public override long totalTermFreq()
+		{
+		  decodeMetaData();
+		  return totalTermFreq_Renamed;
+		}
+
+		public override IComparer<BytesRef> Comparator
+		{
+			get
+			{
+			  return BytesRef.UTF8SortedAsUnicodeComparator;
+			}
+		}
+
+		public override void seekExact(long ord)
+		{
+		  // NOTE: we could add this...
+		  throw new System.NotSupportedException();
+		}
+
+		public override long ord()
+		{
+		  // NOTE: we could add this...
+		  throw new System.NotSupportedException();
+		}
+	  }
+
+	  private sealed class TermsReader : Terms
+	  {
+
+		internal readonly long sumTotalTermFreq;
+		internal readonly long sumDocFreq;
+		internal readonly int docCount;
+		internal readonly int termCount;
+		internal FST<BytesRef> fst;
+		internal readonly ByteSequenceOutputs outputs = ByteSequenceOutputs.Singleton;
+		internal readonly FieldInfo field;
+
+//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
+//ORIGINAL LINE: public TermsReader(org.apache.lucene.index.FieldInfos fieldInfos, org.apache.lucene.store.IndexInput in, int termCount) throws java.io.IOException
+		public TermsReader(FieldInfos fieldInfos, IndexInput @in, int termCount)
+		{
+		  this.termCount = termCount;
+//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
+//ORIGINAL LINE: final int fieldNumber = in.readVInt();
+		  int fieldNumber = @in.readVInt();
+		  field = fieldInfos.fieldInfo(fieldNumber);
+		  if (field.IndexOptions != IndexOptions.DOCS_ONLY)
+		  {
+			sumTotalTermFreq = @in.readVLong();
+		  }
+		  else
+		  {
+			sumTotalTermFreq = -1;
+		  }
+		  sumDocFreq = @in.readVLong();
+		  docCount = @in.readVInt();
+
+		  fst = new FST<>(@in, outputs);
+		}
+
+		public override long SumTotalTermFreq
+		{
+			get
+			{
+			  return sumTotalTermFreq;
+			}
+		}
+
+		public override long SumDocFreq
+		{
+			get
+			{
+			  return sumDocFreq;
+			}
+		}
+
+		public override int DocCount
+		{
+			get
+			{
+			  return docCount;
+			}
+		}
+
+		public override long size()
+		{
+		  return termCount;
+		}
+
+		public override TermsEnum iterator(TermsEnum reuse)
+		{
+		  return new FSTTermsEnum(field, fst);
+		}
+
+		public override IComparer<BytesRef> Comparator
+		{
+			get
+			{
+			  return BytesRef.UTF8SortedAsUnicodeComparator;
+			}
+		}
+
+		public override bool hasFreqs()
+		{
+		  return field.IndexOptions.compareTo(IndexOptions.DOCS_AND_FREQS) >= 0;
+		}
+
+		public override bool hasOffsets()
+		{
+		  return field.IndexOptions.compareTo(IndexOptions.DOCS_AND_FREQS_AND_POSITIONS_AND_OFFSETS) >= 0;
+		}
+
+		public override bool hasPositions()
+		{
+		  return field.IndexOptions.compareTo(IndexOptions.DOCS_AND_FREQS_AND_POSITIONS) >= 0;
+		}
+
+		public override bool hasPayloads()
+		{
+		  return field.hasPayloads();
+		}
+
+		public long ramBytesUsed()
+		{
+		  return ((fst != null) ? fst.sizeInBytes() : 0);
+		}
+	  }
+
+//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
+//ORIGINAL LINE: @Override public org.apache.lucene.codecs.FieldsProducer fieldsProducer(org.apache.lucene.index.SegmentReadState state) throws java.io.IOException
+	  public override FieldsProducer fieldsProducer(SegmentReadState state)
+	  {
+//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
+//ORIGINAL LINE: final String fileName = org.apache.lucene.index.IndexFileNames.segmentFileName(state.segmentInfo.name, state.segmentSuffix, EXTENSION);
+		string fileName = IndexFileNames.segmentFileName(state.segmentInfo.name, state.segmentSuffix, EXTENSION);
+//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
+//ORIGINAL LINE: final org.apache.lucene.store.ChecksumIndexInput in = state.directory.openChecksumInput(fileName, org.apache.lucene.store.IOContext.READONCE);
+		ChecksumIndexInput @in = state.directory.openChecksumInput(fileName, IOContext.READONCE);
+
+//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
+//ORIGINAL LINE: final java.util.SortedMap<String,TermsReader> fields = new java.util.TreeMap<>();
+		SortedMap<string, TermsReader> fields = new SortedDictionary<string, TermsReader>();
+
+		try
+		{
+		  CodecUtil.checkHeader(@in, CODEC_NAME, VERSION_START, VERSION_CURRENT);
+		  while (true)
+		  {
+//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
+//ORIGINAL LINE: final int termCount = in.readVInt();
+			int termCount = @in.readVInt();
+			if (termCount == 0)
+			{
+			  break;
+			}
+//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
+//ORIGINAL LINE: final TermsReader termsReader = new TermsReader(state.fieldInfos, in, termCount);
+			TermsReader termsReader = new TermsReader(state.fieldInfos, @in, termCount);
+			// System.out.println("load field=" + termsReader.field.name);
+			fields.put(termsReader.field.name, termsReader);
+		  }
+		  CodecUtil.checkFooter(@in);
+		}
+		finally
+		{
+		  @in.close();
+		}
+
+		return new FieldsProducerAnonymousInnerClassHelper(this, fields);
+	  }
+
+	  private class FieldsProducerAnonymousInnerClassHelper : FieldsProducer
+	  {
+		  private readonly MemoryPostingsFormat outerInstance;
+
+		  private SortedMap<string, TermsReader> fields;
+
+		  public FieldsProducerAnonymousInnerClassHelper(MemoryPostingsFormat outerInstance, SortedMap<string, TermsReader> fields)
+		  {
+			  this.outerInstance = outerInstance;
+			  this.fields = fields;
+		  }
+
+		  public override IEnumerator<string> iterator()
+		  {
+			return Collections.unmodifiableSet(fields.Keys).GetEnumerator();
+		  }
+
+		  public override Terms terms(string field)
+		  {
+			return fields.get(field);
+		  }
+
+		  public override int size()
+		  {
+			return fields.size();
+		  }
+
+		  public override void close()
+		  {
+			// Drop ref to FST:
+			foreach (TermsReader termsReader in fields.values())
+			{
+			  termsReader.fst = null;
+			}
+		  }
+
+		  public override long ramBytesUsed()
+		  {
+			long sizeInBytes = 0;
+			foreach (KeyValuePair<string, TermsReader> entry in fields.entrySet())
+			{
+			  sizeInBytes += (entry.Key.length() * RamUsageEstimator.NUM_BYTES_CHAR);
+			  sizeInBytes += entry.Value.ramBytesUsed();
+			}
+			return sizeInBytes;
+		  }
+
+//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
+//ORIGINAL LINE: @Override public void checkIntegrity() throws java.io.IOException
+		  public override void checkIntegrity()
+		  {
+		  }
+	  }
+	}
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/d852d5b0/src/Lucene.Net.Codecs/RectangularArrays.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Codecs/RectangularArrays.cs b/src/Lucene.Net.Codecs/RectangularArrays.cs
new file mode 100644
index 0000000..9b41c8a
--- /dev/null
+++ b/src/Lucene.Net.Codecs/RectangularArrays.cs
@@ -0,0 +1,29 @@
+//----------------------------------------------------------------------------------------
+//	Copyright © 2007 - 2014 Tangible Software Solutions Inc.
+//	This class can be used by anyone provided that the copyright notice remains intact.
+//
+//	This class provides the logic to simulate Java rectangular arrays, which are jagged
+//	arrays with inner arrays of the same length. A size of -1 indicates unknown length.
+//----------------------------------------------------------------------------------------
+internal static partial class RectangularArrays
+{
+    internal static long[][] ReturnRectangularLongArray(int Size1, int Size2)
+    {
+        long[][] Array;
+        if (Size1 > -1)
+        {
+            Array = new long[Size1][];
+            if (Size2 > -1)
+            {
+                for (int Array1 = 0; Array1 < Size1; Array1++)
+                {
+                    Array[Array1] = new long[Size2];
+                }
+            }
+        }
+        else
+            Array = null;
+
+        return Array;
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/d852d5b0/src/Lucene.Net.Codecs/Sep/IntIndexInput.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Codecs/Sep/IntIndexInput.cs b/src/Lucene.Net.Codecs/Sep/IntIndexInput.cs
index 057b25b..d08b7d4 100644
--- a/src/Lucene.Net.Codecs/Sep/IntIndexInput.cs
+++ b/src/Lucene.Net.Codecs/Sep/IntIndexInput.cs
@@ -1,6 +1,4 @@
-package codecs.sep;
-
-/*
+/*
  * Licensed to the Apache Software Foundation (ASF) under one or more
  * contributor license agreements.  See the NOTICE file distributed with
  * this work for additional information regarding copyright ownership.
@@ -17,43 +15,45 @@ package codecs.sep;
  * limitations under the License.
  */
 
-import java.io.Closeable;
-import java.io.IOException;
-
-import store.DataInput;
-
-/** Defines basic API for writing ints to an IndexOutput.
- *  IntBlockCodec interacts with this API. @see
- *  IntBlockReader
- *
- * @lucene.experimental */
-public abstract class IntIndexInput implements Closeable {
-
-  public abstract Reader reader() ;
-
-  @Override
-  public abstract void close() ;
-
-  public abstract Index index() ;
-  
-  /** Records a single skip-point in the {@link IntIndexInput.Reader}. */
-  public abstract static class Index {
-
-    public abstract void read(DataInput indexIn, bool absolute) ;
-
-    /** Seeks primary stream to the last read offset */
-    public abstract void seek(IntIndexInput.Reader stream) ;
-
-    public abstract void copyFrom(Index other);
+namespace Lucene.Net.Codecs.Sep
+{
+    using Store;
+    using System;
+
+    /// <summary>
+    /// Defines basic API for writing ints to an IndexOutput.
+    ///  IntBlockCodec interacts with this API. @see
+    ///  IntBlockReader
+    /// 
+    /// @lucene.experimental 
+    /// </summary>
+    public abstract class IntIndexInput : IDisposable
+    {
+        public abstract IntIndexInputReader Reader();
+        public abstract void Dispose();
+        public abstract IntIndexInputIndex Index();
+
+      
+    }
     
-    @Override
-    public abstract Index clone();
-  }
-
-  /** Reads int values. */
-  public abstract static class Reader {
-
-    /** Reads next single int */
-    public abstract int next() ;
-  }
+    /// <summary>Reads int values</summary>
+    public abstract class IntIndexInputReader
+    {
+        /// <summary>Reads next single int</summary>
+        public abstract int Next();
+    }
+
+    /// <summary>
+    /// Records a single skip-point in the <seealso cref="IntIndexInput.Reader"/>. </summary>
+    public abstract class IntIndexInputIndex
+    {
+        public abstract void Read(DataInput indexIn, bool absolute);
+
+        /// <summary>Seeks primary stream to the last read offset </summary>
+        public abstract void Seek(IntIndexInputReader stream);
+
+        public abstract void CopyFrom(IntIndexInputIndex other);
+
+        public abstract IntIndexInputIndex Clone();
+    }
 }

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/d852d5b0/src/Lucene.Net.Codecs/Sep/IntIndexOutput.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Codecs/Sep/IntIndexOutput.cs b/src/Lucene.Net.Codecs/Sep/IntIndexOutput.cs
index b5fe3f9..901dbe1 100644
--- a/src/Lucene.Net.Codecs/Sep/IntIndexOutput.cs
+++ b/src/Lucene.Net.Codecs/Sep/IntIndexOutput.cs
@@ -1,6 +1,4 @@
-package codecs.sep;
-
-/*
+/*
  * Licensed to the Apache Software Foundation (ASF) under one or more
  * contributor license agreements.  See the NOTICE file distributed with
  * this work for additional information regarding copyright ownership.
@@ -17,45 +15,57 @@ package codecs.sep;
  * limitations under the License.
  */
 
-// TODO: we may want tighter integration w/ IndexOutput --
-// may give better perf:
+namespace Lucene.Net.Codecs.Sep
+{
+    using System;
+    using Store;
 
-import store.DataOutput;
+    /// <summary>
+    /// Defines basic API for writing ints to an IndexOutput.
+    /// IntBlockCodec interacts with this API. @see IntBlockReader.
+    /// 
+    /// NOTE: block sizes could be variable
+    /// 
+    /// @lucene.experimental 
+    /// </summary>
+    /// <remarks>
+    /// TODO: We may want tighter integration w/IndexOutput
+    /// may give better performance
+    /// </remarks>
+    public abstract class IntIndexOutput : IDisposable
+    {
 
-import java.io.IOException;
-import java.io.Closeable;
+        /// <summary>
+        /// Write an int to the primary file.  The value must be
+        /// >= 0.  
+        /// </summary>
+        public abstract void Write(int v);
 
-/** Defines basic API for writing ints to an IndexOutput.
- *  IntBlockCodec interacts with this API. @see
- *  IntBlockReader.
- *
- * <p>NOTE: block sizes could be variable
- *
- * @lucene.experimental */
-public abstract class IntIndexOutput implements Closeable {
+        /// <summary>
+        /// If you are indexing the primary output file, call
+        ///  this and interact with the returned IndexWriter. 
+        /// </summary>
+        public abstract IntIndexOutputIndex Index();
 
-  /** Write an int to the primary file.  The value must be
-   * >= 0.  */
-  public abstract void write(int v) ;
+        public abstract void Dispose();
+    }
 
-  /** Records a single skip-point in the IndexOutput. */
-  public abstract static class Index {
 
-    /** Internally records the current location */
-    public abstract void mark() ;
+    /// <summary>Records a single skip-point in the IndexOutput. </summary>
+    public abstract class IntIndexOutputIndex
+    {
 
-    /** Copies index from other */
-    public abstract void copyFrom(Index other, bool copyLast) ;
+        /// <summary>Internally records the current location </summary>
+        public abstract void Mark();
 
-    /** Writes "location" of current output pointer of primary
-     *  output to different output (out) */
-    public abstract void write(DataOutput indexOut, bool absolute) ;
-  }
+        /// <summary>Copies index from other </summary>
+        public abstract void CopyFrom(IntIndexOutputIndex other, bool copyLast);
 
-  /** If you are indexing the primary output file, call
-   *  this and interact with the returned IndexWriter. */
-  public abstract Index index();
+        /// <summary>
+        /// Writes "location" of current output pointer of primary
+        ///  output to different output (out) 
+        /// </summary>
+        public abstract void Write(DataOutput indexOut, bool absolute);
+    }
 
-  @Override
-  public abstract void close() ;
-}
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/d852d5b0/src/Lucene.Net.Codecs/Sep/IntStreamFactory.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Codecs/Sep/IntStreamFactory.cs b/src/Lucene.Net.Codecs/Sep/IntStreamFactory.cs
index 8e23a76..a718d27 100644
--- a/src/Lucene.Net.Codecs/Sep/IntStreamFactory.cs
+++ b/src/Lucene.Net.Codecs/Sep/IntStreamFactory.cs
@@ -1,6 +1,4 @@
-package codecs.sep;
-
-/*
+/*
  * Licensed to the Apache Software Foundation (ASF) under one or more
  * contributor license agreements.  See the NOTICE file distributed with
  * this work for additional information regarding copyright ownership.
@@ -17,20 +15,28 @@ package codecs.sep;
  * limitations under the License.
  */
 
-import store.Directory;
-import store.IOContext;
+namespace Lucene.Net.Codecs.Sep
+{
 
-import java.io.IOException;
+    using Store;
 
-/** Provides int reader and writer to specified files.
- *
- * @lucene.experimental */
-public abstract class IntStreamFactory {
-  /** Create an {@link IntIndexInput} on the provided
-   *  fileName. */
-  public abstract IntIndexInput openInput(Directory dir, String fileName, IOContext context) ;
+    /// <summary>
+    /// Provides int reader and writer to specified files.
+    /// 
+    /// @lucene.experimental 
+    /// </summary>
+    public abstract class IntStreamFactory
+    {
+
+        /// <summary>
+        /// Create an <seealso cref="IntIndexInput"/> on the provided fileName. 
+        /// </summary>
+        public abstract IntIndexInput OpenInput(Directory dir, string fileName, IOContext context);
+
+        /// <summary>
+        /// Create an <seealso cref="IntIndexOutput"/> on the provided fileName. 
+        /// </summary>
+        public abstract IntIndexOutput CreateOutput(Directory dir, string fileName, IOContext context);
+    }
 
-  /** Create an {@link IntIndexOutput} on the provided
-   *  fileName. */
-  public abstract IntIndexOutput createOutput(Directory dir, String fileName, IOContext context) ;
-}
+}
\ No newline at end of file


Mime
View raw message