1 |
| |
2 |
| |
3 |
| |
4 |
| |
5 |
| |
6 |
| |
7 |
| |
8 |
| |
9 |
| |
10 |
| |
11 |
| |
12 |
| |
13 |
| |
14 |
| |
15 |
| |
16 |
| |
17 |
| |
18 |
| |
19 |
| |
20 |
| package org.apache.xindice.core.indexer; |
21 |
| |
22 |
| import org.apache.commons.logging.Log; |
23 |
| import org.apache.commons.logging.LogFactory; |
24 |
| import org.apache.xindice.core.Collection; |
25 |
| import org.apache.xindice.core.DBException; |
26 |
| import org.apache.xindice.core.data.Key; |
27 |
| import org.apache.xindice.core.data.Value; |
28 |
| import org.apache.xindice.core.filer.BTree; |
29 |
| import org.apache.xindice.core.filer.BTreeCallback; |
30 |
| import org.apache.xindice.core.filer.BTreeCorruptException; |
31 |
| import org.apache.xindice.util.Configuration; |
32 |
| import org.apache.xindice.xml.SymbolTable; |
33 |
| |
34 |
| import java.io.File; |
35 |
| import java.io.IOException; |
36 |
| import java.util.ArrayList; |
37 |
| import java.util.List; |
38 |
| |
39 |
| |
40 |
| |
41 |
| |
42 |
| |
43 |
| |
44 |
| |
45 |
| |
46 |
| public final class NameIndexer extends BTree implements Indexer { |
47 |
| |
48 |
| private static final Log log = LogFactory.getLog(NameIndexer.class); |
49 |
| |
50 |
| private static final String NAME = "name"; |
51 |
| private static final String PATTERN = "pattern"; |
52 |
| |
53 |
| private Collection collection; |
54 |
| private SymbolTable symbols; |
55 |
| |
56 |
| private String name; |
57 |
| private IndexPattern pattern; |
58 |
| private boolean wildcard; |
59 |
| private IndexerEventHandler handler; |
60 |
| |
61 |
| |
62 |
27
| public NameIndexer() {
|
63 |
| } |
64 |
| |
65 |
27
| public void setCollection(Collection collection) {
|
66 |
27
| this.collection = collection;
|
67 |
27
| this.symbols = collection.getSymbols();
|
68 |
| } |
69 |
| |
70 |
27
| private void setLocation(String location) {
|
71 |
27
| setFile(new File(collection.getCollectionRoot(), location + ".idx"));
|
72 |
| } |
73 |
| |
74 |
27
| public void setConfig(Configuration config) {
|
75 |
27
| super.setConfig(config);
|
76 |
27
| try {
|
77 |
27
| name = config.getAttribute(NAME);
|
78 |
| |
79 |
27
| String pattern = config.getAttribute(PATTERN);
|
80 |
27
| wildcard = pattern.indexOf('*') != -1;
|
81 |
27
| this.pattern = new IndexPattern(symbols, pattern, null);
|
82 |
| |
83 |
27
| setLocation(name);
|
84 |
27
| setupHandler();
|
85 |
| } catch (Exception e) { |
86 |
0
| if (log.isWarnEnabled()) {
|
87 |
0
| log.warn("ignored exception", e);
|
88 |
| } |
89 |
| } |
90 |
| } |
91 |
| |
92 |
27
| private void setupHandler() {
|
93 |
27
| handler = new BasicIndexerEventHandler() {
|
94 |
3088
| public void onNameAdded(IndexPattern pattern, Key key, short elemID, short attrID) throws DBException {
|
95 |
3088
| try {
|
96 |
3088
| addValue(getCombinedValue(key, elemID, attrID), 0);
|
97 |
| } catch (IOException e) { |
98 |
0
| throw new BTreeCorruptException("Corruption detected on add", e);
|
99 |
| } |
100 |
| } |
101 |
| |
102 |
0
| public void onNameDeleted(IndexPattern pattern, Key key, short elemID, short attrID) throws DBException {
|
103 |
0
| try {
|
104 |
0
| removeValue(getCombinedValue(key, elemID, attrID));
|
105 |
| } catch (IOException e) { |
106 |
0
| throw new BTreeCorruptException("Corruption detected on remove", e);
|
107 |
| } |
108 |
| } |
109 |
| }; |
110 |
| } |
111 |
| |
112 |
143
| public String getName() {
|
113 |
143
| return name;
|
114 |
| } |
115 |
| |
116 |
120
| public String getIndexStyle() {
|
117 |
120
| return STYLE_NODENAME;
|
118 |
| } |
119 |
| |
120 |
32101
| public IndexPattern[] getPatterns() {
|
121 |
32101
| return new IndexPattern[] { pattern };
|
122 |
| } |
123 |
| |
124 |
3088
| private Value getCombinedValue(Key key, short elemID, short attrID) {
|
125 |
3088
| int l = key.getLength();
|
126 |
3088
| byte[] b = new byte[l + 5];
|
127 |
| |
128 |
| |
129 |
3088
| key.copyTo(b, 0, l);
|
130 |
3088
| b[l] = 0;
|
131 |
| |
132 |
| |
133 |
3088
| b[l + 1] = (byte) ((elemID >>> 8) & 0xFF);
|
134 |
3088
| b[l + 2] = (byte) ( elemID & 0xFF);
|
135 |
| |
136 |
| |
137 |
3088
| b[l + 3] = (byte) ((attrID >>> 8) & 0xFF);
|
138 |
3088
| b[l + 4] = (byte) ( attrID & 0xFF);
|
139 |
| |
140 |
3088
| return new Value(b);
|
141 |
| } |
142 |
| |
143 |
8713
| private IndexMatch getIndexMatch(Value v) {
|
144 |
8713
| int l = v.getLength() - 5;
|
145 |
8713
| Key key = v.keyAt(0, l);
|
146 |
8713
| short elemID = v.shortAt(l + 1);
|
147 |
8713
| short attrID = v.shortAt(l + 3);
|
148 |
| |
149 |
8713
| return new IndexMatch(key, elemID, attrID);
|
150 |
| } |
151 |
| |
152 |
68
| public IndexMatch[] queryMatches(final IndexQuery query) throws DBException {
|
153 |
68
| final List results = new ArrayList();
|
154 |
68
| final IndexPattern pattern = query.getPattern();
|
155 |
| |
156 |
68
| try {
|
157 |
68
| query(query, new BTreeCallback() {
|
158 |
8713
| public boolean indexInfo(Value value, long pos) {
|
159 |
8713
| IndexMatch match = getIndexMatch(value);
|
160 |
8713
| if (wildcard) {
|
161 |
8667
| IndexPattern matchElement = new IndexPattern(symbols, match.getElement(), match.getAttribute());
|
162 |
8667
| IndexPattern queryElement = new IndexPattern(symbols, pattern.getElementID(), pattern.getAttributeID());
|
163 |
8667
| if (matchElement.getMatchLevel(queryElement) > 0) {
|
164 |
63
| results.add(match);
|
165 |
| } |
166 |
| } else { |
167 |
46
| results.add(match);
|
168 |
| } |
169 |
8713
| return true;
|
170 |
| } |
171 |
| }); |
172 |
| } catch (DBException e) { |
173 |
0
| throw e;
|
174 |
| } catch (Exception e) { |
175 |
0
| if (log.isWarnEnabled()) {
|
176 |
0
| log.warn("ignored exception", e);
|
177 |
| } |
178 |
| } |
179 |
| |
180 |
68
| return (IndexMatch[]) results.toArray(new IndexMatch[results.size()]);
|
181 |
| } |
182 |
| |
183 |
5294
| public IndexerEventHandler getIndexerEventHandler() {
|
184 |
5294
| return handler;
|
185 |
| } |
186 |
| } |