~play-developers/play/zdb

« back to all changes in this revision

Viewing changes to src/zdb/core/Indexer.java

  • Committer: Leo West
  • Date: 2008-08-29 14:17:56 UTC
  • Revision ID: lwe@lwe-20080829141756-28zl7cwjpf8wshvl
fix NPE in Store.search occuring on empty results and empty bucket

Show diffs side-by-side

added added

removed removed

Lines of Context:
27
27
public class Indexer {
28
28
 
29
29
    private static Map<File, IndexWriter> indexs = new HashMap<File, IndexWriter>();
 
30
 
30
31
    private static Map<File, IndexSearcher> searchers = new HashMap<File, IndexSearcher>();
 
32
 
31
33
    private static Map<File, Long> writerStats = new HashMap<File, Long>();
 
34
 
32
35
    private static long OPTIMIZE_THRESHOLD;
 
36
 
33
37
    private static String ANALYSER_CLASS;
34
38
    
 
39
 
35
40
    static {
36
 
        OPTIMIZE_THRESHOLD = Long.parseLong(System.getProperty("zdb.optimize","1000"));
37
 
        ANALYSER_CLASS = System.getProperty("zdb.analyser.class","org.apache.lucene.analysis.standard.StandardAnalyzer");
38
 
    }
39
 
    
40
 
    private static Analyzer getAnalyser () {
41
 
                try {
42
 
                        Class clazz = Class.forName(ANALYSER_CLASS);
43
 
                        return (Analyzer) clazz.newInstance();
44
 
                } catch (Exception e) {
45
 
                        throw new RuntimeException(e);
46
 
                }
47
 
    }
48
 
    
 
41
        OPTIMIZE_THRESHOLD = Long.parseLong(System.getProperty("zdb.optimize", "1000"));
 
42
        ANALYSER_CLASS = System.getProperty("zdb.analyser.class", "org.apache.lucene.analysis.standard.StandardAnalyzer");
 
43
    }
 
44
 
 
45
    private static Analyzer getAnalyser() {
 
46
        try {
 
47
            Class clazz = Class.forName(ANALYSER_CLASS);
 
48
            return (Analyzer) clazz.newInstance();
 
49
        } catch (Exception e) {
 
50
            throw new RuntimeException(e);
 
51
        }
 
52
    }
49
53
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Indexs management
50
54
    private static IndexWriter getIndexWriterForBucket(File bucket) {
51
55
        try {
67
71
            }
68
72
            IndexWriter wr = indexs.get(bucket);
69
73
            long count = getStat(bucket).longValue();
70
 
            if( count > OPTIMIZE_THRESHOLD) {
71
 
                long start = System.currentTimeMillis();
72
 
                wr.optimize(true);
73
 
                writerStats.put(bucket, new Long (0));
74
 
                System.out.println("Optimized index "+bucket.getName()+" in "+(System.currentTimeMillis()-start)+" ms");
 
74
            if (count > OPTIMIZE_THRESHOLD) {
 
75
                long start = System.currentTimeMillis();
 
76
                wr.optimize(true);
 
77
                writerStats.put(bucket, new Long(0));
 
78
                System.out.println("Optimized index " + bucket.getName() + " in " + (System.currentTimeMillis() - start) + " ms");
75
79
            }
76
80
            return wr;
77
81
        } catch (Exception e) {
78
82
            throw new UnexpectedException("Cannot open index", e);
79
83
        }
80
84
    }
81
 
    
82
 
    private static Long getStat (File file) {
83
 
        if (!writerStats.containsKey(file))
84
 
                writerStats.put(file, new Long (0));
85
 
        return writerStats.get(file);
 
85
 
 
86
    private static Long getStat(File file) {
 
87
        if (!writerStats.containsKey(file)) {
 
88
            writerStats.put(file, new Long(0));
 
89
        }
 
90
        return writerStats.get(file);
86
91
    }
87
 
    
 
92
 
88
93
    private static IndexSearcher getIndexSearcherForBucket(File bucket, boolean forceRefresh) {
89
94
        try {
90
95
            if (!searchers.containsKey(bucket) || forceRefresh) {
91
96
                synchronized (Indexer.class) {
92
 
                        IndexSearcher old = searchers.get(bucket);
 
97
                    IndexSearcher old = searchers.get(bucket);
93
98
                    File indexRoot = new File(bucket, "_index");
94
99
                    if (indexRoot.exists()) {
95
100
                        IndexSearcher indexSearcher = new IndexSearcher(FSDirectory.getDirectory(indexRoot));
96
101
                        searchers.put(bucket, indexSearcher);
97
102
                    }
98
 
                    if (old!=null) {
99
 
                        old.close();
 
103
                    if (old != null) {
 
104
                        old.close();
100
105
                    }
101
106
                }
102
107
            }
114
119
        String value = indexString.substring(i + 1);
115
120
        String[] parts = declaration.split(";");
116
121
        String key = parts[parts.length - 1];
117
 
        zdb.client.Document.Index index = new zdb.client.Document.Index(key,value);
 
122
        zdb.client.Document.Index index = new zdb.client.Document.Index(key, value);
118
123
        for (String part : parts) {
119
124
            if (part.equals("STORED")) {
120
125
                index.stored = true;
132
137
        return index;
133
138
    }
134
139
 
135
 
   
136
140
    public static Document toDocument(String id, List<String> indexes) {
137
141
        Document luceneDoc = new Document();
138
142
        luceneDoc.add(new Field("_docID", id, Field.Store.YES, Field.Index.UN_TOKENIZED));
139
 
        
 
143
 
140
144
        for (String indexInfos : indexes) {
141
145
            Index newindex = parseIndex(indexInfos);
142
146
            Field.Index luceneIndex = Field.Index.UN_TOKENIZED;
143
 
            if( ! newindex.indexed )
144
 
                luceneDoc.add(new Field( newindex.name, newindex.value.toString(), Field.Store.NO, Field.Index.NO ));
145
 
            else if( newindex.fulltext )
146
 
                luceneDoc.add(new Field( newindex.name, newindex.value.toString(), Field.Store.YES, Field.Index.TOKENIZED ));
147
 
            else
148
 
                luceneDoc.add(new Field( newindex.name, newindex.value.toString(), Field.Store.YES, Field.Index.UN_TOKENIZED ));
 
147
            if (!newindex.indexed) {
 
148
                luceneDoc.add(new Field(newindex.name, newindex.value.toString(), Field.Store.NO, Field.Index.NO));
 
149
            } else if (newindex.fulltext) {
 
150
                luceneDoc.add(new Field(newindex.name, newindex.value.toString(), Field.Store.YES, Field.Index.TOKENIZED));
 
151
            } else {
 
152
                luceneDoc.add(new Field(newindex.name, newindex.value.toString(), Field.Store.YES, Field.Index.UN_TOKENIZED));
149
153
            // Field.Index ==  (Boolean) pi[2] ? ((Boolean) pi[3] ? Field.Index.TOKENIZED : Field.Index.UN_TOKENIZED) : Field.Index.NO;
 
154
            }
150
155
        }
151
156
        return luceneDoc;
152
157
    }
153
158
 
154
159
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ API
155
 
    public static void storeToIndex(File bucket, String id, Document document) throws Exception {
 
160
    public static void storeToIndex(File bucket, String id, Document document) throws 
 
161
            Exception {
156
162
        IndexWriter indexWriter = getIndexWriterForBucket(bucket);
157
163
        indexWriter.deleteDocuments(new Term("_docID", id));
158
164
        indexWriter.addDocument(document);
162
168
        writerStats.put(bucket, new Long(opCount));
163
169
        getIndexSearcherForBucket(bucket, true);
164
170
    }
165
 
    
166
 
    public static void deleteFromIndex (File bucket, String id) throws Exception {
 
171
 
 
172
    public static void deleteFromIndex(File bucket, String id) throws Exception {
167
173
        IndexWriter indexWriter = getIndexWriterForBucket(bucket);
168
174
        indexWriter.deleteDocuments(new Term("_docID", id));
169
175
        indexWriter.flush();
170
176
        getIndexSearcherForBucket(bucket, true);
171
177
    }
172
 
   
173
 
    public static void initialize (File bucket) {
174
 
        getIndexWriterForBucket(bucket);
 
178
 
 
179
    public static void initialize(File bucket) {
 
180
        getIndexWriterForBucket(bucket);
175
181
    }
176
 
    
177
 
    public static Document searchOne (File bucket, Query query) { 
178
 
        try {
 
182
 
 
183
    public static Document searchOne(File bucket, Query query) {
 
184
        try {
179
185
            IndexSearcher searcher = getIndexSearcherForBucket(bucket, false);
180
186
            if (searcher != null) {
181
 
                Hits hits = searcher.search(query);
182
 
                Hit hit = (Hit)hits.iterator().next();
 
187
                Hits hits = searcher.search(query);
 
188
                Hit hit = (Hit) hits.iterator().next();
183
189
                return hit.getDocument();
184
190
            }
185
191
            return null;
187
193
            throw new UnexpectedException("IO error", e);
188
194
        }
189
195
    }
190
 
    
 
196
 
191
197
    public static Hits search(File bucket, Query query, Sort sort) {
192
198
        try {
193
199
            IndexSearcher searcher = getIndexSearcherForBucket(bucket, false);
194
 
            Collection<String> fields = ( Collection<String>)searcher.getIndexReader().getFieldNames(FieldOption.ALL);
 
200
            Collection<String> fields = (Collection<String>) searcher.getIndexReader().getFieldNames(FieldOption.ALL);
195
201
            SortField[] sorts = sort.getSort();
196
202
            for (SortField sortField : sorts) {
197
 
                                if (!fields.contains(sort))
198
 
                                        return searcher.search(query, null, new Sort(new String[0]));
199
 
                        }
 
203
                if (!fields.contains(sort)) {
 
204
                    return searcher.search(query, null, new Sort(new String[0]));
 
205
                }
 
206
            }
200
207
            if (searcher != null) {
201
208
                return searcher.search(query, null, sort);
202
209
            }
205
212
            throw new UnexpectedException("IO error", e);
206
213
        }
207
214
    }
208
 
    
 
215
 
209
216
    public static void shutdown() throws Exception {
210
217
        for (IndexWriter writer : indexs.values()) {
211
218
            writer.close();