1 package org.apache.lucene.index;
2
3
19
20 import org.apache.lucene.store.IndexInput;
21
22 import java.io.IOException;
23
24 final class SegmentTermPositions
25 extends SegmentTermDocs implements TermPositions {
26 private IndexInput proxStream;
27 private int proxCount;
28 private int position;
29
30 private int payloadLength;
32 private boolean needToLoadPayload;
35
36 private long lazySkipPointer = -1;
39 private int lazySkipProxCount = 0;
40
41 SegmentTermPositions(SegmentReader p) {
42 super(p);
43 this.proxStream = null; }
45
46 final void seek(TermInfo ti, Term term) throws IOException {
47 super.seek(ti, term);
48 if (ti != null)
49 lazySkipPointer = ti.proxPointer;
50
51 lazySkipProxCount = 0;
52 proxCount = 0;
53 payloadLength = 0;
54 needToLoadPayload = false;
55 }
56
57 public final void close() throws IOException {
58 super.close();
59 if (proxStream != null) proxStream.close();
60 }
61
62 public final int nextPosition() throws IOException {
63 if (currentFieldOmitTf)
64 return 0;
66 lazySkip();
68 proxCount--;
69 return position += readDeltaPosition();
70 }
71
72 private final int readDeltaPosition() throws IOException {
73 int delta = proxStream.readVInt();
74 if (currentFieldStoresPayloads) {
75 if ((delta & 1) != 0) {
80 payloadLength = proxStream.readVInt();
81 }
82 delta >>>= 1;
83 needToLoadPayload = true;
84 }
85 return delta;
86 }
87
88 protected final void skippingDoc() throws IOException {
89 lazySkipProxCount += freq;
91 }
92
93 public final boolean next() throws IOException {
94 lazySkipProxCount += proxCount;
97
98 if (super.next()) { proxCount = freq; position = 0; return true;
102 }
103 return false;
104 }
105
106 public final int read(final int[] docs, final int[] freqs) {
107 throw new UnsupportedOperationException("TermPositions does not support processing multiple documents in one call. Use TermDocs instead.");
108 }
109
110
111
112 protected void skipProx(long proxPointer, int payloadLength) throws IOException {
113 lazySkipPointer = proxPointer;
115 lazySkipProxCount = 0;
116 proxCount = 0;
117 this.payloadLength = payloadLength;
118 needToLoadPayload = false;
119 }
120
121 private void skipPositions(int n) throws IOException {
122 assert !currentFieldOmitTf;
123 for (int f = n; f > 0; f--) { readDeltaPosition();
125 skipPayload();
126 }
127 }
128
129 private void skipPayload() throws IOException {
130 if (needToLoadPayload && payloadLength > 0) {
131 proxStream.seek(proxStream.getFilePointer() + payloadLength);
132 }
133 needToLoadPayload = false;
134 }
135
136 private void lazySkip() throws IOException {
147 if (proxStream == null) {
148 proxStream = (IndexInput)parent.proxStream.clone();
150 }
151
152 skipPayload();
155
156 if (lazySkipPointer != -1) {
157 proxStream.seek(lazySkipPointer);
158 lazySkipPointer = -1;
159 }
160
161 if (lazySkipProxCount != 0) {
162 skipPositions(lazySkipProxCount);
163 lazySkipProxCount = 0;
164 }
165 }
166
167 public int getPayloadLength() {
168 return payloadLength;
169 }
170
171 public byte[] getPayload(byte[] data, int offset) throws IOException {
172 if (!needToLoadPayload) {
173 throw new IOException("Payload cannot be loaded more than once for the same term position.");
174 }
175
176 byte[] retArray;
178 int retOffset;
179 if (data == null || data.length - offset < payloadLength) {
180 retArray = new byte[payloadLength];
183 retOffset = 0;
184 } else {
185 retArray = data;
186 retOffset = offset;
187 }
188 proxStream.readBytes(retArray, retOffset, payloadLength);
189 needToLoadPayload = false;
190 return retArray;
191 }
192
193 public boolean isPayloadAvailable() {
194 return needToLoadPayload && payloadLength > 0;
195 }
196
197 }
198