001: /*
002: *
003: * Created on 01 June 2003, 08:32
004: */
005:
006: package com.jofti.tree;
007:
008: import java.util.Collection;
009: import java.util.HashMap;
010: import java.util.Iterator;
011: import java.util.Map;
012: import java.util.Properties;
013:
014: import org.apache.commons.logging.Log;
015: import org.apache.commons.logging.LogFactory;
016:
017: import com.jofti.api.IndexQuery;
018: import com.jofti.btree.BTOperations;
019: import com.jofti.btree.BTree;
020: import com.jofti.btree.ValueObject;
021: import com.jofti.core.IParsedQuery;
022: import com.jofti.core.InternalIndex;
023: import com.jofti.core.QueryId;
024: import com.jofti.exception.JoftiException;
025: import com.jofti.introspect.ClassIntrospector;
026: import com.jofti.manager.IndexManagerImpl;
027: import com.jofti.parser.ConvenienceQueryWrapper;
028: import com.jofti.parser.ParserManager;
029: import com.jofti.query.MatchInQuery;
030: import com.jofti.query.MatchNotQuery;
031: import com.jofti.query.MatchQuery;
032: import com.jofti.query.MatchRangeQuery;
033:
034: import edu.emory.mathcs.backport.java.util.concurrent.ConcurrentHashMap;
035: import edu.emory.mathcs.backport.java.util.concurrent.LinkedBlockingQueue;
036: import edu.emory.mathcs.backport.java.util.concurrent.atomic.AtomicLong;
037:
038: /**
039: *
040: *
041: * The wrapper for the IndexCache that integrates the BTree implementation, the introspector
042: * and the query engine.
043: *
044: * @author xenephon (xenephon@jofti.com)
045: */
046: public class TreeIndex implements InternalIndex {
047: public final String KEY_DIMENSION = "com.activescript.KEY_DIMENSION";
048:
049: protected static int DEFAULT_OFFERTIME = 1000;
050:
051: protected long REMOVAL_WATCHER_SLEEP_TIME = 3000;
052:
053: private static Log log = LogFactory.getLog(IndexManagerImpl.class);
054:
055: protected TreeOperationAdapter treeAdapter = null;
056: /** Creates a new instance
057: of BTreeWrapper */
058:
059: BTree tree = null;
060: ClassIntrospector introspector = null;
061:
062: Map indexedDimensions = new ConcurrentHashMap();
063:
064: protected AtomicLong keyNumber = new AtomicLong(0);
065:
066: LinkedBlockingQueue removalCandidateQueue = new LinkedBlockingQueue(
067: 20000);
068:
069: MatchingEngine engine = null;
070:
071: ParserManager parserManager = null;
072:
073: public TreeIndex() {
074:
075: }
076:
077: public TreeIndex(BTree tree, ClassIntrospector parser) {
078:
079: this .tree = tree;
080: this .introspector = parser;
081:
082: }
083:
084: public TreeIndex(BTree tree, ClassIntrospector parser,
085: Map indexedDimensions) {
086:
087: this .tree = tree;
088: this .introspector = parser;
089: this .indexedDimensions = indexedDimensions;
090:
091: }
092:
093: /**
094: * @param props
095: * @throws JoftiException
096: */
097: public void init(Properties props) throws JoftiException {
098: tree.init(props);
099: engine = new TreeMatcherEngine();
100: parserManager = new ParserManager(introspector);
101:
102: this .treeAdapter = new TreeOperationAdapter();
103:
104: }
105:
106: public Map query(IndexQuery query) throws JoftiException {
107: //return engine.query(query, this);
108: TreeMatcherEngine tempEngine = (TreeMatcherEngine) engine;
109: if (query == null) {
110: throw new JoftiException("Query object cannot be null");
111: }
112:
113: QueryId queryId = (QueryId) query;
114:
115: switch (queryId.getQueryType().type) {
116: case 100:
117: return tempEngine.matchProperty(
118: (MatchQuery) ((ConvenienceQueryWrapper) query)
119: .getQuery(), this );
120: case 101:
121: return tempEngine.matchPropertyRange(
122: (MatchRangeQuery) ((ConvenienceQueryWrapper) query)
123: .getQuery(), this );
124: case 102:
125: return tempEngine.matchNotProperty(
126: (MatchNotQuery) ((ConvenienceQueryWrapper) query)
127: .getQuery(), this );
128: case 0:
129: return tempEngine.processQuery((IParsedQuery) query, this );
130: case 103:
131: return tempEngine.matchProperty(
132: (MatchInQuery) ((ConvenienceQueryWrapper) query)
133: .getQuery(), this );
134: default:
135: throw new JoftiException("Query type "
136: + ((ConvenienceQueryWrapper) query).getQuery()
137: .getClass()
138: + " cannot be used for Non nameSpaced IndexCache");
139: }
140:
141: }
142:
143: /* (non-Javadoc)
144: * @see com.jofti.core.InternalIndex#contains(java.lang.Object)
145: */
146: public boolean contains(Object key) throws JoftiException {
147: try {
148: return treeAdapter.contains((Comparable) key, tree,
149: introspector);
150: } catch (Throwable e) {
151: if (!(e instanceof JoftiException)) {
152: while (e.getCause() != null) {
153: System.err.println(e);
154: e = e.getCause();
155: }
156: throw new JoftiException(e);
157: } else {
158: while (e.getCause() != null) {
159: System.err.println(e);
160: e = e.getCause();
161: }
162: throw (JoftiException) e;
163: }
164: }
165: }
166:
167: /* (non-Javadoc)
168: * @see com.jofti.core.InternalIndex#insert(java.lang.Object, java.lang.Object)
169: */
170: public void insert(Object key, Object value)
171: throws IllegalArgumentException, JoftiException {
172: try {
173:
174: treeAdapter.insert((Comparable) key, value, tree,
175: introspector);
176: keyNumber.incrementAndGet();
177: } catch (Throwable e) {
178: if (!(e instanceof JoftiException)) {
179: System.err.println("error at " + keyNumber);
180: while (e.getCause() != null) {
181: System.err.println(e);
182: e = e.getCause();
183: }
184: throw new JoftiException(e);
185: } else {
186: while (e.getCause() != null) {
187: System.err.println(e);
188: e = e.getCause();
189: }
190: throw (JoftiException) e;
191: }
192: }
193: }
194:
195: public void insertEntry(Object key, Object value)
196: throws IllegalArgumentException, JoftiException {
197: try {
198:
199: treeAdapter.insertEntry((Comparable) key, value, tree,
200: introspector);
201: keyNumber.incrementAndGet();
202: } catch (Throwable e) {
203: if (!(e instanceof JoftiException)) {
204: throw new JoftiException(e);
205: } else {
206: throw (JoftiException) e;
207: }
208: }
209: }
210:
211: /* (non-Javadoc)
212: * @see com.jofti.core.InternalIndex#remove(java.lang.Object, java.lang.Object)
213: */
214: public void remove(Object key, Object value)
215: throws IllegalArgumentException, JoftiException {
216: try {
217: treeAdapter.remove((Comparable) key, value, tree,
218: introspector);
219: keyNumber.decrementAndGet();
220: } catch (Throwable e) {
221: if (!(e instanceof JoftiException)) {
222: throw new JoftiException(e);
223: } else {
224: throw (JoftiException) e;
225: }
226:
227: }
228: }
229:
230: /* (non-Javadoc)
231: * @see com.jofti.core.InternalIndex#removeByKey(java.lang.Object)
232: */
233: public void removeByKey(Object key)
234: throws IllegalArgumentException, JoftiException {
235: try {
236: treeAdapter.removeByKey((Comparable) key, tree,
237: introspector);
238: keyNumber.decrementAndGet();
239: } catch (Throwable e) {
240: if (!(e instanceof JoftiException)) {
241: throw new JoftiException(e);
242: } else {
243: throw (JoftiException) e;
244: }
245:
246: }
247: }
248:
249: public String toString() {
250: StringBuffer buf = new StringBuffer();
251: buf.append(" tree:" + tree);
252: return buf.toString();
253: }
254:
255: /* (non-Javadoc)
256: * @see com.jofti.core.InternalIndex#getEntries(java.lang.Comparable)
257: */
258: public Map getEntries(Object key) throws JoftiException {
259: try {
260: return treeAdapter.getAllValuesForKey((Comparable) key,
261: tree, introspector);
262: } catch (Throwable e) {
263: if (!(e instanceof JoftiException)) {
264: throw new JoftiException(e);
265: } else {
266: throw (JoftiException) e;
267: }
268:
269: }
270: }
271:
272: public Map getAllEntries() throws JoftiException {
273: try {
274: return treeAdapter.getAllValuesForTree(tree, introspector);
275:
276: } catch (Throwable e) {
277: if (!(e instanceof JoftiException)) {
278: throw new JoftiException(e);
279: } else {
280: throw (JoftiException) e;
281: }
282:
283: }
284: }
285:
286: /* (non-Javadoc)
287: * @see com.jofti.core.InternalIndex#getAttributesByKey(java.lang.Object)
288: */
289: public Map getAttributesByKey(Object key) throws JoftiException {
290: try {
291: Collection col = treeAdapter.getAttribsByKey(
292: (Comparable) key, tree, introspector);
293: if (col == null || col.size() == 0) {
294: return new HashMap(2);
295: }
296: Map temp = new HashMap(col.size());
297: int size = col.size();
298: Iterator it = col.iterator();
299: for (int i = 0; i < size; i++) {
300: ValueObject obj = (ValueObject) it.next();
301: temp.put(new Integer(obj.getDimension()), obj
302: .getRealValue());
303: }
304: return temp;
305: } catch (Throwable e) {
306: if (!(e instanceof JoftiException)) {
307: throw new JoftiException(e);
308: } else {
309: throw (JoftiException) e;
310: }
311:
312: }
313: }
314:
315: /* (non-Javadoc)
316: * @see com.jofti.core.InternalIndex#removeAll()
317: */
318: public void removeAll() {
319: tree.removeAll();
320: keyNumber = new AtomicLong(0);
321: }
322:
323: /**
324: * @return Returns the tree.
325: */
326: BTree getTree() {
327: return tree;
328: }
329:
330: /**
331: * @param tree The tree to set.
332: */
333: public void setTree(BTree tree) {
334: this .tree = tree;
335: }
336:
337: /**
338: * @return Returns the parser.
339: */
340: public ClassIntrospector getIntrospector() {
341: return introspector;
342: }
343:
344: /**
345: * @param parser The parser to set.
346: */
347: public void setParser(ClassIntrospector parser) {
348: this .introspector = parser;
349: }
350:
351: /**
352: * @return Returns the keyNumber.
353: */
354: public long getKeyNumber() {
355: return keyNumber.get();
356: }
357:
358: public synchronized ParserManager getParserManager() {
359: return parserManager;
360: }
361:
362: }
|