1 package org.apache.lucene.index; 2 3 18 19 import java.io.IOException ; 20 21 import org.apache.lucene.store.Directory; 22 23 26 27 final class TermInfosReader { 28 private Directory directory; 29 private String segment; 30 private FieldInfos fieldInfos; 31 32 private ThreadLocal enumerators = new ThreadLocal (); 33 private SegmentTermEnum origEnum; 34 private long size; 35 36 private Term[] indexTerms = null; 37 private TermInfo[] indexInfos; 38 private long[] indexPointers; 39 40 private SegmentTermEnum indexEnum; 41 42 TermInfosReader(Directory dir, String seg, FieldInfos fis) 43 throws IOException { 44 directory = dir; 45 segment = seg; 46 fieldInfos = fis; 47 48 origEnum = new SegmentTermEnum(directory.openInput(segment + ".tis"), 49 fieldInfos, false); 50 size = origEnum.size; 51 52 indexEnum = 53 new SegmentTermEnum(directory.openInput(segment + ".tii"), 54 fieldInfos, true); 55 } 56 57 protected void finalize() { 58 enumerators.set(null); 60 } 61 62 public int getSkipInterval() { 63 return origEnum.skipInterval; 64 } 65 66 final void close() throws IOException { 67 if (origEnum != null) 68 origEnum.close(); 69 if (indexEnum != null) 70 indexEnum.close(); 71 } 72 73 74 final long size() { 75 return size; 76 } 77 78 private SegmentTermEnum getEnum() { 79 SegmentTermEnum termEnum = (SegmentTermEnum)enumerators.get(); 80 if (termEnum == null) { 81 termEnum = terms(); 82 enumerators.set(termEnum); 83 } 84 return termEnum; 85 } 86 87 private synchronized void ensureIndexIsRead() throws IOException { 88 if (indexTerms != null) return; try { 91 int indexSize = (int)indexEnum.size; 93 indexTerms = new Term[indexSize]; 94 indexInfos = new TermInfo[indexSize]; 95 indexPointers = new long[indexSize]; 96 97 for (int i = 0; indexEnum.next(); i++) { 98 indexTerms[i] = indexEnum.term(); 99 indexInfos[i] = indexEnum.termInfo(); 100 indexPointers[i] = indexEnum.indexPointer; 101 } 102 } finally { 103 indexEnum.close(); 104 indexEnum = null; 105 } 106 } 107 108 109 private final int getIndexOffset(Term term) { 110 int lo = 0; int hi = indexTerms.length - 1; 112 113 while (hi >= lo) { 114 int mid = (lo + hi) >> 1; 115 int delta = term.compareTo(indexTerms[mid]); 116 if (delta < 0) 117 hi = mid - 1; 118 else if (delta > 0) 119 lo = mid + 1; 120 else 121 return mid; 122 } 123 return hi; 124 } 125 126 private final void seekEnum(int indexOffset) throws IOException { 127 getEnum().seek(indexPointers[indexOffset], 128 (indexOffset * getEnum().indexInterval) - 1, 129 indexTerms[indexOffset], indexInfos[indexOffset]); 130 } 131 132 133 TermInfo get(Term term) throws IOException { 134 if (size == 0) return null; 135 136 ensureIndexIsRead(); 137 138 SegmentTermEnum enumerator = getEnum(); 140 if (enumerator.term() != null && ((enumerator.prev() != null && term.compareTo(enumerator.prev())> 0) 142 || term.compareTo(enumerator.term()) >= 0)) { 143 int enumOffset = (int)(enumerator.position/enumerator.indexInterval)+1; 144 if (indexTerms.length == enumOffset || term.compareTo(indexTerms[enumOffset]) < 0) 146 return scanEnum(term); } 148 149 seekEnum(getIndexOffset(term)); 151 return scanEnum(term); 152 } 153 154 155 private final TermInfo scanEnum(Term term) throws IOException { 156 SegmentTermEnum enumerator = getEnum(); 157 enumerator.scanTo(term); 158 if (enumerator.term() != null && term.compareTo(enumerator.term()) == 0) 159 return enumerator.termInfo(); 160 else 161 return null; 162 } 163 164 165 final Term get(int position) throws IOException { 166 if (size == 0) return null; 167 168 SegmentTermEnum enumerator = getEnum(); 169 if (enumerator != null && enumerator.term() != null && 170 position >= enumerator.position && 171 position < (enumerator.position + enumerator.indexInterval)) 172 return scanEnum(position); 174 seekEnum(position / enumerator.indexInterval); return scanEnum(position); 176 } 177 178 private final Term scanEnum(int position) throws IOException { 179 SegmentTermEnum enumerator = getEnum(); 180 while(enumerator.position < position) 181 if (!enumerator.next()) 182 return null; 183 184 return enumerator.term(); 185 } 186 187 188 final long getPosition(Term term) throws IOException { 189 if (size == 0) return -1; 190 191 ensureIndexIsRead(); 192 int indexOffset = getIndexOffset(term); 193 seekEnum(indexOffset); 194 195 SegmentTermEnum enumerator = getEnum(); 196 while(term.compareTo(enumerator.term()) > 0 && enumerator.next()) {} 197 198 if (term.compareTo(enumerator.term()) == 0) 199 return enumerator.position; 200 else 201 return -1; 202 } 203 204 205 public SegmentTermEnum terms() { 206 return (SegmentTermEnum)origEnum.clone(); 207 } 208 209 210 public SegmentTermEnum terms(Term term) throws IOException { 211 get(term); 212 return (SegmentTermEnum)getEnum().clone(); 213 } 214 } 215 | Popular Tags |