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 System.Collections.Generic; 20 using Lucene.Net.Util; 21 22 namespace Lucene.Net.Index 23 { 24 25 /// <summary> Allows you to iterate over the <see cref="TermPositions" /> for multiple <see cref="Term" />s as 26 /// a single <see cref="TermPositions" />. 27 /// 28 /// </summary> 29 public class MultipleTermPositions : TermPositions 30 { 31 private sealed class TermPositionsQueue : PriorityQueue<TermPositions> 32 { TermPositionsQueue(LinkedList<TermPositions> termPositions)33 internal TermPositionsQueue(LinkedList<TermPositions> termPositions) 34 { 35 Initialize(termPositions.Count); 36 37 foreach(TermPositions tp in termPositions) 38 if (tp.Next()) 39 Add(tp); 40 } 41 Peek()42 internal TermPositions Peek() 43 { 44 return Top(); 45 } 46 LessThan(TermPositions a, TermPositions b)47 public override bool LessThan(TermPositions a, TermPositions b) 48 { 49 return a.Doc < b.Doc; 50 } 51 } 52 53 private sealed class IntQueue 54 { IntQueue()55 public IntQueue() 56 { 57 InitBlock(); 58 } InitBlock()59 private void InitBlock() 60 { 61 _array = new int[_arraySize]; 62 } 63 private int _arraySize = 16; 64 private int _index = 0; 65 private int _lastIndex = 0; 66 private int[] _array; 67 add(int i)68 internal void add(int i) 69 { 70 if (_lastIndex == _arraySize) 71 growArray(); 72 73 _array[_lastIndex++] = i; 74 } 75 next()76 internal int next() 77 { 78 return _array[_index++]; 79 } 80 sort()81 internal void sort() 82 { 83 System.Array.Sort(_array, _index, _lastIndex - _index); 84 } 85 clear()86 internal void clear() 87 { 88 _index = 0; 89 _lastIndex = 0; 90 } 91 size()92 internal int size() 93 { 94 return (_lastIndex - _index); 95 } 96 growArray()97 private void growArray() 98 { 99 int[] newArray = new int[_arraySize * 2]; 100 Array.Copy(_array, 0, newArray, 0, _arraySize); 101 _array = newArray; 102 _arraySize *= 2; 103 } 104 } 105 106 private int _doc; 107 private int _freq; 108 private TermPositionsQueue _termPositionsQueue; 109 private IntQueue _posList; 110 111 private bool isDisposed; 112 /// <summary> Creates a new <c>MultipleTermPositions</c> instance. 113 /// 114 /// </summary> 115 /// <exception cref="System.IO.IOException"> 116 /// </exception> MultipleTermPositions(IndexReader indexReader, Term[] terms)117 public MultipleTermPositions(IndexReader indexReader, Term[] terms) 118 { 119 var termPositions = new System.Collections.Generic.LinkedList<TermPositions>(); 120 121 for (int i = 0; i < terms.Length; i++) 122 termPositions.AddLast(indexReader.TermPositions(terms[i])); 123 124 _termPositionsQueue = new TermPositionsQueue(termPositions); 125 _posList = new IntQueue(); 126 } 127 Next()128 public bool Next() 129 { 130 if (_termPositionsQueue.Size() == 0) 131 return false; 132 133 _posList.clear(); 134 _doc = _termPositionsQueue.Peek().Doc; 135 136 TermPositions tp; 137 do 138 { 139 tp = _termPositionsQueue.Peek(); 140 141 for (int i = 0; i < tp.Freq; i++) 142 _posList.add(tp.NextPosition()); 143 144 if (tp.Next()) 145 _termPositionsQueue.UpdateTop(); 146 else 147 { 148 _termPositionsQueue.Pop(); 149 tp.Close(); 150 } 151 } 152 while (_termPositionsQueue.Size() > 0 && _termPositionsQueue.Peek().Doc == _doc); 153 154 _posList.sort(); 155 _freq = _posList.size(); 156 157 return true; 158 } 159 NextPosition()160 public int NextPosition() 161 { 162 return _posList.next(); 163 } 164 SkipTo(int target)165 public bool SkipTo(int target) 166 { 167 while (_termPositionsQueue.Peek() != null && target > _termPositionsQueue.Peek().Doc) 168 { 169 TermPositions tp = _termPositionsQueue.Pop(); 170 if (tp.SkipTo(target)) 171 _termPositionsQueue.Add(tp); 172 else 173 tp.Close(); 174 } 175 return Next(); 176 } 177 178 public int Doc 179 { 180 get { return _doc; } 181 } 182 183 public int Freq 184 { 185 get { return _freq; } 186 } 187 188 [Obsolete("Use Dispose() instead")] Close()189 public void Close() 190 { 191 Dispose(); 192 } 193 Dispose()194 public void Dispose() 195 { 196 Dispose(true); 197 } 198 Dispose(bool disposing)199 protected virtual void Dispose(bool disposing) 200 { 201 if (isDisposed) return; 202 203 if (disposing) 204 { 205 while (_termPositionsQueue.Size() > 0) 206 _termPositionsQueue.Pop().Close(); 207 } 208 209 isDisposed = true; 210 } 211 212 /// <summary> Not implemented.</summary> 213 /// <throws> UnsupportedOperationException </throws> Seek(Term arg0)214 public virtual void Seek(Term arg0) 215 { 216 throw new System.NotSupportedException(); 217 } 218 219 /// <summary> Not implemented.</summary> 220 /// <throws> UnsupportedOperationException </throws> Seek(TermEnum termEnum)221 public virtual void Seek(TermEnum termEnum) 222 { 223 throw new System.NotSupportedException(); 224 } 225 226 /// <summary> Not implemented.</summary> 227 /// <throws> UnsupportedOperationException </throws> Read(int[] arg0, int[] arg1)228 public virtual int Read(int[] arg0, int[] arg1) 229 { 230 throw new System.NotSupportedException(); 231 } 232 233 234 /// <summary> Not implemented.</summary> 235 /// <throws> UnsupportedOperationException </throws> 236 public virtual int PayloadLength 237 { 238 get { throw new System.NotSupportedException(); } 239 } 240 241 /// <summary> Not implemented.</summary> 242 /// <throws> UnsupportedOperationException </throws> GetPayload(byte[] data, int offset)243 public virtual byte[] GetPayload(byte[] data, int offset) 244 { 245 throw new System.NotSupportedException(); 246 } 247 248 /// <summary> </summary> 249 /// <value> false </value> 250 // TODO: Remove warning after API has been finalized 251 public virtual bool IsPayloadAvailable 252 { 253 get { return false; } 254 } 255 } 256 }