Skip to content

Commit 39bf187

Browse files
idodeclaretarzanek
authored andcommitted
Store IndexAnalysisSettings into a metadata Document
1 parent 42c2989 commit 39bf187

File tree

8 files changed

+409
-54
lines changed

8 files changed

+409
-54
lines changed

src/org/opensolaris/opengrok/analysis/AnalyzerGuru.java

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919

2020
/*
2121
* Copyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved.
22-
* Portions Copyright (c) 2017-2018, Chris Fraire <[email protected]>.
22+
* Portions Copyright (c) 2017, Chris Fraire <[email protected]>.
2323
*/
2424
package org.opensolaris.opengrok.analysis;
2525

@@ -52,7 +52,6 @@
5252
import org.apache.lucene.document.Field.Store;
5353
import org.apache.lucene.document.FieldType;
5454
import org.apache.lucene.document.SortedDocValuesField;
55-
import org.apache.lucene.document.StoredField;
5655
import org.apache.lucene.document.StringField;
5756
import org.apache.lucene.document.TextField;
5857
import org.apache.lucene.util.BytesRef;
@@ -471,9 +470,6 @@ public void populateDocument(Document doc, File file, String path,
471470
doc.add(npstring);
472471
}
473472

474-
doc.add(new StoredField(QueryBuilder.TABSIZE, project != null &&
475-
project.hasTabSizeSetting() ? project.getTabSize() : 0));
476-
477473
if (fa != null) {
478474
Genre g = fa.getGenre();
479475
if (g == Genre.PLAIN || g == Genre.XREFABLE || g == Genre.HTML) {
Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
/*
2+
* CDDL HEADER START
3+
*
4+
* The contents of this file are subject to the terms of the
5+
* Common Development and Distribution License (the "License").
6+
* You may not use this file except in compliance with the License.
7+
*
8+
* See LICENSE.txt included in this distribution for the specific
9+
* language governing permissions and limitations under the License.
10+
*
11+
* When distributing Covered Code, include this CDDL HEADER in each
12+
* file and include the License file at LICENSE.txt.
13+
* If applicable, add the following below this CDDL HEADER, with the
14+
* fields enclosed by brackets "[]" replaced with your own identifying
15+
* information: Portions Copyright [yyyy] [name of copyright owner]
16+
*
17+
* CDDL HEADER END
18+
*/
19+
20+
/*
21+
* Copyright (c) 2018, Chris Fraire <[email protected]>.
22+
*/
23+
24+
package org.opensolaris.opengrok.index;
25+
26+
import java.io.ByteArrayInputStream;
27+
import java.io.ByteArrayOutputStream;
28+
import java.io.IOException;
29+
import java.io.ObjectInputStream;
30+
import java.io.ObjectOutputStream;
31+
import java.io.Serializable;
32+
33+
/**
34+
* Represents a serializable gathering of some top-level metadata concerning the
35+
* operation of {@link IndexDatabase} -- and persisted therein too -- which are
36+
* re-compared upon each indexing run since changes to them might require
37+
* re-indexing particular files or in certain cases all files.
38+
*/
39+
public final class IndexAnalysisSettings implements Serializable {
40+
41+
private static final long serialVersionUID = 1005610724146719938L;
42+
43+
private String projectName;
44+
45+
/**
46+
* (nullable to allow easing this object into existing OpenGrok indexes
47+
* without forcing a re-indexing)
48+
* @serial
49+
*/
50+
private Integer tabSize;
51+
52+
/**
53+
* (nullable to allow easing this object into existing OpenGrok indexes
54+
* without forcing a re-indexing)
55+
* @serial
56+
*/
57+
private Long analyzerGuruVersion;
58+
59+
/**
60+
* Gets the project name to be used to distinguish different instances of
61+
* {@link IndexAnalysisSettings} that might be returned by a Lucene
62+
* {@code MultiReader} search across projects.
63+
* @return projectName
64+
*/
65+
public String getProjectName() {
66+
return projectName;
67+
}
68+
69+
/**
70+
* Sets the project name to be used to distinguish different instances of
71+
* {@link IndexAnalysisSettings} that might be returned by a Lucene
72+
* {@code MultiReader} search across projects.
73+
* @param value
74+
*/
75+
public void setProjectName(String value) {
76+
this.projectName = value;
77+
}
78+
79+
public Integer getTabSize() {
80+
return tabSize;
81+
}
82+
83+
public void setTabSize(Integer value) {
84+
this.tabSize = value;
85+
}
86+
87+
public Long getAnalyzerGuruVersion() {
88+
return analyzerGuruVersion;
89+
}
90+
91+
public void setAnalyzerGuruVersion(Long value) {
92+
this.analyzerGuruVersion = value;
93+
}
94+
95+
/**
96+
* Creates a binary representation of this object.
97+
* @return a byte array representing this object
98+
* @throws IOException Any exception thrown by the underlying
99+
* OutputStream.
100+
*/
101+
public byte[] serialize() throws IOException {
102+
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
103+
new ObjectOutputStream(bytes).writeObject(this);
104+
return bytes.toByteArray();
105+
}
106+
107+
/**
108+
* De-serializes a binary representation of an {@link IndexAnalysisSettings}
109+
* object.
110+
* @param bytes a byte array containing the serialization
111+
* @return a defined instance
112+
* @throws IOException Any of the usual Input/Output related exceptions.
113+
* @throws ClassNotFoundException Class of a serialized object cannot be
114+
* found.
115+
* @throws ClassCastException if the array contains an object of another
116+
* type than {@code IndexAnalysisSettings}
117+
*/
118+
public static IndexAnalysisSettings deserialize(byte[] bytes)
119+
throws IOException, ClassNotFoundException {
120+
ObjectInputStream in = new ObjectInputStream(
121+
new ByteArrayInputStream(bytes));
122+
return (IndexAnalysisSettings)in.readObject();
123+
}
124+
125+
private void readObject(ObjectInputStream in) throws ClassNotFoundException,
126+
IOException {
127+
128+
boolean hasValue = in.readBoolean();
129+
String vstring = in.readUTF();
130+
projectName = hasValue ? vstring : null;
131+
132+
hasValue = in.readBoolean();
133+
int vint = in.readInt();
134+
tabSize = hasValue ? vint : null;
135+
136+
hasValue = in.readBoolean();
137+
long vlong = in.readLong();
138+
analyzerGuruVersion = hasValue ? vlong : null;
139+
}
140+
141+
private void writeObject(ObjectOutputStream out) throws IOException {
142+
out.writeBoolean(projectName != null); // hasValue
143+
out.writeUTF(projectName == null ? "" : projectName);
144+
145+
out.writeBoolean(tabSize != null); // hasValue
146+
out.writeInt(tabSize == null ? 0 : tabSize);
147+
148+
out.writeBoolean(analyzerGuruVersion != null); // hasValue
149+
out.writeLong(analyzerGuruVersion == null ? 0 : analyzerGuruVersion);
150+
}
151+
}
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
/*
2+
* CDDL HEADER START
3+
*
4+
* The contents of this file are subject to the terms of the
5+
* Common Development and Distribution License (the "License").
6+
* You may not use this file except in compliance with the License.
7+
*
8+
* See LICENSE.txt included in this distribution for the specific
9+
* language governing permissions and limitations under the License.
10+
*
11+
* When distributing Covered Code, include this CDDL HEADER in each
12+
* file and include the License file at LICENSE.txt.
13+
* If applicable, add the following below this CDDL HEADER, with the
14+
* fields enclosed by brackets "[]" replaced with your own identifying
15+
* information: Portions Copyright [yyyy] [name of copyright owner]
16+
*
17+
* CDDL HEADER END
18+
*/
19+
20+
/*
21+
* Copyright (c) 2018, Chris Fraire <[email protected]>.
22+
*/
23+
24+
package org.opensolaris.opengrok.index;
25+
26+
import java.io.IOException;
27+
import org.apache.lucene.document.Document;
28+
import org.apache.lucene.document.Field;
29+
import org.apache.lucene.document.StoredField;
30+
import org.apache.lucene.document.StringField;
31+
import org.apache.lucene.index.IndexReader;
32+
import org.apache.lucene.index.IndexWriter;
33+
import org.apache.lucene.index.IndexableField;
34+
import org.apache.lucene.index.Term;
35+
import org.apache.lucene.queryparser.classic.ParseException;
36+
import org.apache.lucene.queryparser.classic.QueryParser;
37+
import org.apache.lucene.search.IndexSearcher;
38+
import org.apache.lucene.search.Query;
39+
import org.apache.lucene.search.TopDocs;
40+
import org.opensolaris.opengrok.analysis.CompatibleAnalyser;
41+
import org.opensolaris.opengrok.search.QueryBuilder;
42+
43+
/**
44+
* Represents a data-access object for {@link IndexAnalysisSettings}.
45+
*/
46+
public class IndexAnalysisSettingsAccessor {
47+
48+
/**
49+
* {@code "uthuslvotkgltggqqjmurqojpjpjjkutkujktnkk"}, the
50+
* {@link QueryBuilder}-normalized value for UUID
51+
* 58859C75-F941-42E5-8D1A-FAF71DDEBBA7
52+
*/
53+
public static final String INDEX_ANALYSIS_SETTINGS_OBJUID =
54+
"uthuslvotkgltggqqjmurqojpjpjjkutkujktnkk";
55+
56+
/**
57+
* Searches for a document with a {@link QueryBuilder#OBJUID} value matching
58+
* {@link #INDEX_ANALYSIS_SETTINGS_OBJUID}.
59+
* @param reader a defined instance
60+
* @return a defined instance or {@code null} if none could be found
61+
* @throws IOException if I/O error occurs while searching Lucene
62+
*/
63+
public IndexAnalysisSettings read(IndexReader reader) throws IOException {
64+
IndexSearcher searcher = new IndexSearcher(reader);
65+
Query q;
66+
try {
67+
q = new QueryParser(QueryBuilder.OBJUID, new CompatibleAnalyser()).
68+
parse(INDEX_ANALYSIS_SETTINGS_OBJUID);
69+
} catch (ParseException ex) {
70+
// This is not expected, so translate to RuntimeException.
71+
throw new RuntimeException(ex);
72+
}
73+
TopDocs top = searcher.search(q, 1);
74+
if (top.totalHits < 1) {
75+
return null;
76+
}
77+
78+
Document doc = searcher.doc(top.scoreDocs[0].doc);
79+
IndexableField objser = doc.getField(QueryBuilder.OBJSER);
80+
try {
81+
return objser == null ? null : IndexAnalysisSettings.deserialize(
82+
objser.binaryValue().bytes);
83+
} catch (ClassNotFoundException ex) {
84+
// This is not expected, so translate to RuntimeException.
85+
throw new RuntimeException(ex);
86+
}
87+
}
88+
89+
/**
90+
* Writes a document to contain the serialized version of {@code settings},
91+
* with a {@link QueryBuilder#OBJUID} value set to
92+
* {@link #INDEX_ANALYSIS_SETTINGS_OBJUID}. An existing version of the
93+
* document is first deleted.
94+
* @param writer a defined, target instance
95+
* @param settings a defined instance
96+
* @throws IOException if I/O error occurs while writing Lucene
97+
*/
98+
public void write(IndexWriter writer, IndexAnalysisSettings settings)
99+
throws IOException {
100+
byte[] objser = settings.serialize();
101+
102+
writer.deleteDocuments(new Term(QueryBuilder.OBJUID,
103+
INDEX_ANALYSIS_SETTINGS_OBJUID));
104+
105+
Document doc = new Document();
106+
StringField uidfield = new StringField(QueryBuilder.OBJUID,
107+
INDEX_ANALYSIS_SETTINGS_OBJUID, Field.Store.NO);
108+
doc.add(uidfield);
109+
doc.add(new StoredField(QueryBuilder.OBJSER, objser));
110+
writer.addDocument(doc);
111+
}
112+
}

0 commit comments

Comments
 (0)