Lucene.Net  3.0.3
Lucene.Net is a port of the Lucene search engine library, written in C# and targeted at .NET runtime users.
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Properties Pages
ReaderUtil.cs
Go to the documentation of this file.
1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements. See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License. You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 using System;
19 using Lucene.Net.Support;
20 using IndexReader = Lucene.Net.Index.IndexReader;
21 
22 namespace Lucene.Net.Util
23 {
24  /// <summary>
25  /// Common util methods for dealing with <see cref="IndexReader" />s.
26  /// </summary>
27  public class ReaderUtil
28  {
29  /// <summary>Gathers sub-readers from reader into a List.</summary>
30  /// <param name="allSubReaders"></param>
31  /// <param name="reader"></param>
32  public static void GatherSubReaders(System.Collections.Generic.IList<IndexReader> allSubReaders, IndexReader reader)
33  {
34  IndexReader[] subReaders = reader.GetSequentialSubReaders();
35  if (subReaders == null)
36  {
37  // Add the reader itself, and do not recurse
38  allSubReaders.Add(reader);
39  }
40  else
41  {
42  for (int i = 0; i < subReaders.Length; i++)
43  {
44  GatherSubReaders(allSubReaders, subReaders[i]);
45  }
46  }
47  }
48 
49  /// <summary> Returns sub IndexReader that contains the given document id.
50  ///
51  /// </summary>
52  /// <param name="doc">id of document
53  /// </param>
54  /// <param name="reader">parent reader
55  /// </param>
56  /// <returns> sub reader of parent which contains the specified doc id
57  /// </returns>
58  public static IndexReader SubReader(int doc, IndexReader reader)
59  {
60  var subReadersList = new System.Collections.Generic.List<IndexReader>();
61  ReaderUtil.GatherSubReaders(subReadersList, reader);
62  IndexReader[] subReaders = subReadersList.ToArray();
63  int[] docStarts = new int[subReaders.Length];
64  int maxDoc = 0;
65  for (int i = 0; i < subReaders.Length; i++)
66  {
67  docStarts[i] = maxDoc;
68  maxDoc += subReaders[i].MaxDoc;
69  }
70  return subReaders[ReaderUtil.SubIndex(doc, docStarts)];
71  }
72 
73  /// <summary> Returns sub-reader subIndex from reader.
74  ///
75  /// </summary>
76  /// <param name="reader">parent reader
77  /// </param>
78  /// <param name="subIndex">index of desired sub reader
79  /// </param>
80  /// <returns> the subreader at subINdex
81  /// </returns>
82  public static IndexReader SubReader(IndexReader reader, int subIndex)
83  {
84  var subReadersList = new System.Collections.Generic.List<IndexReader>();
85  ReaderUtil.GatherSubReaders(subReadersList, reader);
86  IndexReader[] subReaders = subReadersList.ToArray();
87  return subReaders[subIndex];
88  }
89 
90 
91  /// <summary> Returns index of the searcher/reader for document <c>n</c> in the
92  /// array used to construct this searcher/reader.
93  /// </summary>
94  public static int SubIndex(int n, int[] docStarts)
95  {
96  // find
97  // searcher/reader for doc n:
98  int size = docStarts.Length;
99  int lo = 0; // search starts array
100  int hi = size - 1; // for first element less than n, return its index
101  while (hi >= lo)
102  {
103  int mid = Number.URShift((lo + hi), 1);
104  int midValue = docStarts[mid];
105  if (n < midValue)
106  hi = mid - 1;
107  else if (n > midValue)
108  lo = mid + 1;
109  else
110  {
111  // found a match
112  while (mid + 1 < size && docStarts[mid + 1] == midValue)
113  {
114  mid++; // scan to last match
115  }
116  return mid;
117  }
118  }
119  return hi;
120  }
121  }
122 }