Example #1
0
        /// <summary>
        /// Returns a single <seealso cref="Fields"/> instance for this
        ///  reader, merging fields/terms/docs/positions on the
        ///  fly.  this method will return null if the reader
        ///  has no postings.
        ///
        ///  <p><b>NOTE</b>: this is a slow way to access postings.
        ///  It's better to get the sub-readers and iterate through them
        ///  yourself.
        /// </summary>
        public static Fields GetFields(IndexReader reader)
        {
            IList<AtomicReaderContext> leaves = reader.Leaves();
            switch (leaves.Count)
            {
                case 0:
                    // no fields
                    return null;

                case 1:
                    // already an atomic reader / reader with one leave
                    return leaves[0].AtomicReader.Fields();

                default:
                    IList<Fields> fields = new List<Fields>();
                    IList<ReaderSlice> slices = new List<ReaderSlice>();
                    foreach (AtomicReaderContext ctx in leaves)
                    {
                        AtomicReader r = ctx.AtomicReader;
                        Fields f = r.Fields();
                        if (f != null)
                        {
                            fields.Add(f);
                            slices.Add(new ReaderSlice(ctx.DocBase, r.MaxDoc(), fields.Count - 1));
                        }
                    }
                    if (fields.Count == 0)
                    {
                        return null;
                    }
                    else if (fields.Count == 1)
                    {
                        return fields[0];
                    }
                    else
                    {
                        return new MultiFields(fields.ToArray(/*Fields.EMPTY_ARRAY*/), slices.ToArray(/*ReaderSlice.EMPTY_ARRAY*/));
                    }
            }
        }
Example #2
0
        /// <summary>
        /// Expert: attempts to delete by document ID, as long as
        ///  the provided reader is a near-real-time reader (from {@link
        ///  DirectoryReader#open(IndexWriter,boolean)}).  If the
        ///  provided reader is an NRT reader obtained from this
        ///  writer, and its segment has not been merged away, then
        ///  the delete succeeds and this method returns true; else, it
        ///  returns false the caller must then separately delete by
        ///  Term or Query.
        ///
        ///  <b>NOTE</b>: this method can only delete documents
        ///  visible to the currently open NRT reader.  If you need
        ///  to delete documents indexed after opening the NRT
        ///  reader you must use the other deleteDocument methods
        ///  (e.g., <seealso cref="#deleteDocuments(Term)"/>).
        /// </summary>
        public virtual bool TryDeleteDocument(IndexReader readerIn, int docID)
        {
            lock (this)
            {
                AtomicReader reader;
                if (readerIn is AtomicReader)
                {
                    // Reader is already atomic: use the incoming docID:
                    reader = (AtomicReader)readerIn;
                }
                else
                {
                    // Composite reader: lookup sub-reader and re-base docID:
                    IList<AtomicReaderContext> leaves = readerIn.Leaves();
                    int subIndex = ReaderUtil.SubIndex(docID, leaves);
                    reader = leaves[subIndex].AtomicReader;
                    docID -= leaves[subIndex].DocBase;
                    Debug.Assert(docID >= 0);
                    Debug.Assert(docID < reader.MaxDoc());
                }

                if (!(reader is SegmentReader))
                {
                    throw new System.ArgumentException("the reader must be a SegmentReader or composite reader containing only SegmentReaders");
                }

                SegmentCommitInfo info = ((SegmentReader)reader).SegmentInfo;

                // TODO: this is a slow linear search, but, number of
                // segments should be contained unless something is
                // seriously wrong w/ the index, so it should be a minor
                // cost:

                if (segmentInfos.IndexOf(info) != -1)
                {
                    ReadersAndUpdates rld = readerPool.Get(info, false);
                    if (rld != null)
                    {
                        lock (BufferedUpdatesStream)
                        {
                            rld.InitWritableLiveDocs();
                            if (rld.Delete(docID))
                            {
                                int fullDelCount = rld.Info.DelCount + rld.PendingDeleteCount;
                                if (fullDelCount == rld.Info.Info.DocCount)
                                {
                                    // If a merge has already registered for this
                                    // segment, we leave it in the readerPool; the
                                    // merge will skip merging it and will then drop
                                    // it once it's done:
                                    if (!mergingSegments.Contains(rld.Info))
                                    {
                                        segmentInfos.Remove(rld.Info);
                                        readerPool.Drop(rld.Info);
                                        Checkpoint();
                                    }
                                }

                                // Must bump changeCount so if no other changes
                                // happened, we still commit this change:
                                Changed();
                            }
                            //System.out.println("  yes " + info.info.name + " " + docID);
                            return true;
                        }
                    }
                    else
                    {
                        //System.out.println("  no rld " + info.info.name + " " + docID);
                    }
                }
                else
                {
                    //System.out.println("  no seg " + info.info.name + " " + docID);
                }
                return false;
            }
        }
Example #3
0
 /// <summary>
 /// Call this to get the (merged) FieldInfos for a
 ///  composite reader.
 ///  <p>
 ///  NOTE: the returned field numbers will likely not
 ///  correspond to the actual field numbers in the underlying
 ///  readers, and codec metadata (<seealso cref="FieldInfo#getAttribute(String)"/>
 ///  will be unavailable.
 /// </summary>
 public static FieldInfos GetMergedFieldInfos(IndexReader reader)
 {
     FieldInfos.Builder builder = new FieldInfos.Builder();
     foreach (AtomicReaderContext ctx in reader.Leaves())
     {
         builder.Add(ctx.AtomicReader.FieldInfos);
     }
     return builder.Finish();
 }
Example #4
0
 /// <summary>
 /// Returns a single <seealso cref="Bits"/> instance for this
 ///  reader, merging live Documents on the
 ///  fly.  this method will return null if the reader
 ///  has no deletions.
 ///
 ///  <p><b>NOTE</b>: this is a very slow way to access live docs.
 ///  For example, each Bits access will require a binary search.
 ///  It's better to get the sub-readers and iterate through them
 ///  yourself.
 /// </summary>
 public static Bits GetLiveDocs(IndexReader reader)
 {
     if (reader.HasDeletions())
     {
         IList<AtomicReaderContext> leaves = reader.Leaves();
         int size = leaves.Count;
         Debug.Assert(size > 0, "A reader with deletions must have at least one leave");
         if (size == 1)
         {
             return leaves[0].AtomicReader.LiveDocs;
         }
         Bits[] liveDocs = new Bits[size];
         int[] starts = new int[size + 1];
         for (int i = 0; i < size; i++)
         {
             // record all liveDocs, even if they are null
             AtomicReaderContext ctx = leaves[i];
             liveDocs[i] = ctx.AtomicReader.LiveDocs;
             starts[i] = ctx.DocBase;
         }
         starts[size] = reader.MaxDoc();
         return new MultiBits(liveDocs, starts, true);
     }
     else
     {
         return null;
     }
 }