1 17 package org.alfresco.repo.search.impl.lucene; 18 19 import java.io.IOException ; 20 import java.util.BitSet ; 21 import java.util.Set ; 22 23 import org.alfresco.error.AlfrescoRuntimeException; 24 import org.alfresco.service.cmr.repository.NodeRef; 25 import org.apache.lucene.index.FilterIndexReader; 26 import org.apache.lucene.index.IndexReader; 27 import org.apache.lucene.index.Term; 28 import org.apache.lucene.index.TermDocs; 29 import org.apache.lucene.index.TermEnum; 30 import org.apache.lucene.index.TermPositions; 31 32 public class FilterIndexReaderByNodeRefs extends FilterIndexReader 33 { 34 BitSet deletedDocuments; 35 36 public FilterIndexReaderByNodeRefs(IndexReader reader, Set <NodeRef> deletions) 37 { 38 super(reader); 39 deletedDocuments = new BitSet (reader.maxDoc()); 40 41 try 42 { 43 for (NodeRef nodeRef : deletions) 44 { 45 TermDocs td = reader.termDocs(new Term("ID", nodeRef.toString())); 46 while (td.next()) 47 { 48 deletedDocuments.set(td.doc(), true); 49 } 50 } 51 } 52 catch (IOException e) 53 { 54 throw new AlfrescoRuntimeException("Failed to construct filtering index reader", e); 55 } 56 } 57 58 public static class FilterTermDocs implements TermDocs 59 { 60 BitSet deletedDocuments; 61 62 protected TermDocs in; 63 64 public FilterTermDocs(TermDocs in, BitSet deletedDocuments) 65 { 66 this.in = in; 67 this.deletedDocuments = deletedDocuments; 68 } 69 70 public void seek(Term term) throws IOException 71 { 72 in.seek(term); 74 } 75 76 public void seek(TermEnum termEnum) throws IOException 77 { 78 in.seek(termEnum); 80 } 81 82 public int doc() 83 { 84 return in.doc(); 86 } 87 88 public int freq() 89 { 90 return in.freq(); 92 } 93 94 public boolean next() throws IOException 95 { 96 while(in.next()) 97 { 98 if(!deletedDocuments.get(in.doc())) 99 { 100 return true; 102 } 103 } 104 return false; 105 } 106 107 public int read(int[] docs, int[] freqs) throws IOException 108 { 109 int[] innerDocs = new int[docs.length]; 110 int[] innerFreq = new int[docs.length]; 111 int count = in.read(innerDocs, innerFreq); 112 113 if (count == 0) 115 { 116 return 0; 117 } 118 119 if(allDeleted(innerDocs, count)) 120 { 121 return read(docs, freqs); 123 } 124 125 127 int insertPosition = 0; 128 for(int i = 0; i < count; i++) 129 { 130 if(!deletedDocuments.get(innerDocs[i])) 131 { 132 docs[insertPosition] = innerDocs[i]; 133 freqs[insertPosition] = innerFreq[i]; 134 insertPosition++; 135 } 136 } 137 138 return insertPosition; 139 } 140 141 private boolean allDeleted(int[] docs, int fillSize) 142 { 143 for(int i = 0; i < fillSize; i++) 144 { 145 if(!deletedDocuments.get(docs[i])) 146 { 147 return false; 148 } 149 } 150 return true; 151 } 152 153 public boolean skipTo(int i) throws IOException 154 { 155 boolean result = in.skipTo(i); 156 if(result == false) 157 { 158 return false; 159 } 160 161 if(deletedDocuments.get(in.doc())) 162 { 163 return skipTo(i); 164 } 165 else 166 { 167 return true; 168 } 169 } 170 171 public void close() throws IOException 172 { 173 in.close(); 175 } 176 } 177 178 179 public static class FilterTermPositions extends FilterTermDocs implements TermPositions 180 { 181 182 public FilterTermPositions(TermPositions in, BitSet deletedDocuements) 183 { 184 super(in, deletedDocuements); 185 } 186 187 public int nextPosition() throws IOException 188 { 189 return ((TermPositions) this.in).nextPosition(); 190 } 191 } 192 193 @Override 194 public int numDocs() 195 { 196 return super.numDocs() - deletedDocuments.cardinality(); 197 } 198 199 @Override 200 public TermDocs termDocs() throws IOException 201 { 202 return new FilterTermDocs(super.termDocs(), deletedDocuments); 203 } 204 205 @Override 206 public TermPositions termPositions() throws IOException 207 { 208 return new FilterTermPositions(super.termPositions(), deletedDocuments); 209 } 210 } 211 | Popular Tags |