[infinispan-commits] Infinispan SVN: r1209 - in trunk/query/src/main/java/org/infinispan/query: backend and 1 other directories.
infinispan-commits at lists.jboss.org
infinispan-commits at lists.jboss.org
Tue Nov 24 06:43:35 EST 2009
Author: manik.surtani at jboss.com
Date: 2009-11-24 06:43:34 -0500 (Tue, 24 Nov 2009)
New Revision: 1209
Added:
trunk/query/src/main/java/org/infinispan/query/KeyTransformationHandler.java
trunk/query/src/main/java/org/infinispan/query/Transformable.java
trunk/query/src/main/java/org/infinispan/query/Transformer.java
Modified:
trunk/query/src/main/java/org/infinispan/query/backend/LocalQueryInterceptor.java
trunk/query/src/main/java/org/infinispan/query/backend/QueryHelper.java
trunk/query/src/main/java/org/infinispan/query/backend/QueryInterceptor.java
trunk/query/src/main/java/org/infinispan/query/impl/CacheQueryImpl.java
Log:
Starting to implement multiple key types
Added: trunk/query/src/main/java/org/infinispan/query/KeyTransformationHandler.java
===================================================================
--- trunk/query/src/main/java/org/infinispan/query/KeyTransformationHandler.java (rev 0)
+++ trunk/query/src/main/java/org/infinispan/query/KeyTransformationHandler.java 2009-11-24 11:43:34 UTC (rev 1209)
@@ -0,0 +1,75 @@
+package org.infinispan.query;
+
+import org.infinispan.util.Util;
+import org.infinispan.CacheException;
+
+/**
+ * // TODO: Manik: Document this
+ *
+ * @author Manik Surtani
+ * @since 4.0
+ */
+public class KeyTransformationHandler {
+ public static Object stringToKey(String s) {
+ char type = s.charAt(0);
+ switch (type) {
+ case 'S':
+ // this is a normal String
+ return s.substring(2);
+ case 'I':
+ // This is an Integer
+ return Integer.parseInt(s.substring(2));
+ case 'T':
+ // this is a custom transformable.
+ int indexOfSecondDelimiter = s.indexOf(":", 2);
+ String transformerClassName = s.substring(2, indexOfSecondDelimiter);
+ String keyAsString = s.substring(indexOfSecondDelimiter + 1);
+ Transformer t = null;
+ // try and locate class
+ try {
+ t = (Transformer) Util.getInstance(transformerClassName);
+ } catch (Exception e) {
+ // uh oh, cannot load this class! What now?
+ throw new CacheException(e);
+ }
+
+ return t.fromString(keyAsString);
+ }
+ throw new CacheException("Unknown type metadata " + type);
+ }
+
+ public static String keyToString(Object key) {
+ if (validKey(key)) {
+ // this string should be in the format of
+ // "<TYPE>:(TRANSFORMER):<KEY>"
+ // e.g.:
+ // "S:my string key"
+ // "I:75"
+ // "D:5.34"
+ // "B:f"
+ // "T:com.myorg.MyTransformer:STRING_GENERATED_BY_MY_TRANSFORMER"
+ return key.toString();
+ }
+ else
+ throw new IllegalArgumentException("Indexing only works with entries keyed on Strings!");
+ }
+
+ private static boolean validKey(Object key) {
+ // we support String and JDK primitives and their wrappers.
+ if (key instanceof String ||
+ key instanceof Integer ||
+ key instanceof Long ||
+ key instanceof Float ||
+ key instanceof Double ||
+ key instanceof Boolean ||
+ key instanceof Short ||
+ key instanceof Byte
+ )
+ return true;
+ if (key.getClass().isAnnotationPresent(Transformable.class))
+ return true;
+
+ return false;
+ }
+
+}
Property changes on: trunk/query/src/main/java/org/infinispan/query/KeyTransformationHandler.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:eol-style
+ LF
Added: trunk/query/src/main/java/org/infinispan/query/Transformable.java
===================================================================
--- trunk/query/src/main/java/org/infinispan/query/Transformable.java (rev 0)
+++ trunk/query/src/main/java/org/infinispan/query/Transformable.java 2009-11-24 11:43:34 UTC (rev 1209)
@@ -0,0 +1,18 @@
+package org.infinispan.query;
+
+import java.lang.annotation.Target;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * If you annotate your object with this, it can be used as a valid key for Infinispan to index.
+ *
+ * @author Manik Surtani
+ * @since 4.0
+ */
+ at Target(ElementType.TYPE)
+ at Retention(RetentionPolicy.RUNTIME)
+public @interface Transformable {
+ Class<? extends Transformer> transformer();
+}
Property changes on: trunk/query/src/main/java/org/infinispan/query/Transformable.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:eol-style
+ LF
Added: trunk/query/src/main/java/org/infinispan/query/Transformer.java
===================================================================
--- trunk/query/src/main/java/org/infinispan/query/Transformer.java (rev 0)
+++ trunk/query/src/main/java/org/infinispan/query/Transformer.java 2009-11-24 11:43:34 UTC (rev 1209)
@@ -0,0 +1,16 @@
+package org.infinispan.query;
+
+/**
+ * The task of this interface is to convert keys from their original types to a String representation (which can be
+ * used in Lucene) and vice versa.
+ *
+ * @author Manik Surtani
+ * @since 4.0
+ */
+public interface Transformer {
+
+ Object fromString(String s);
+
+ String toString(Object customType);
+
+}
Property changes on: trunk/query/src/main/java/org/infinispan/query/Transformer.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:eol-style
+ LF
Modified: trunk/query/src/main/java/org/infinispan/query/backend/LocalQueryInterceptor.java
===================================================================
--- trunk/query/src/main/java/org/infinispan/query/backend/LocalQueryInterceptor.java 2009-11-24 11:42:32 UTC (rev 1208)
+++ trunk/query/src/main/java/org/infinispan/query/backend/LocalQueryInterceptor.java 2009-11-24 11:43:34 UTC (rev 1209)
@@ -1,15 +1,10 @@
package org.infinispan.query.backend;
import org.hibernate.search.engine.SearchFactoryImplementor;
-import org.infinispan.commands.write.PutKeyValueCommand;
-import org.infinispan.commands.write.PutMapCommand;
-import org.infinispan.commands.write.RemoveCommand;
-import org.infinispan.commands.write.ReplaceCommand;
import org.infinispan.context.InvocationContext;
import org.infinispan.factories.annotations.Inject;
import javax.transaction.TransactionManager;
-import java.util.Map;
/**
* <p/>
@@ -36,93 +31,8 @@
this.transactionManager = transactionManager;
}
-
@Override
- public Object visitPutKeyValueCommand(InvocationContext ctx, PutKeyValueCommand command) throws Throwable {
-
- // This method will get the put() calls on the cache and then send them into Lucene once it's successful.
-
- if (log.isDebugEnabled()) log.debug("Entered the LocalQueryInterceptor visitPutKeyValueCommand()");
-
- // do the actual put first.
- Object toReturn = invokeNextInterceptor(ctx, command);
-
- // Since this is going to index if local only, then we must first check to see if the
- // context is local.
-
- Object value = checkForMarshalledValue(command.getValue());
-
- if (ctx.isOriginLocal()) {
- if (log.isDebugEnabled()) log.debug("Origin is local");
- addToIndexes(value, checkForMarshalledValue(command.getKey()).toString());
- }
-
- return toReturn;
+ protected boolean shouldModifyIndexes(InvocationContext ctx) {
+ return ctx.isOriginLocal();
}
-
- @Override
- public Object visitRemoveCommand(InvocationContext ctx, RemoveCommand command) throws Throwable {
-
- if (log.isDebugEnabled()) log.debug("Entered the LocalQueryInterceptor visitRemoveCommand()");
-
- // remove the object out of the cache first.
- Object valueRemoved = invokeNextInterceptor(ctx, command);
-
-
- // Check to make sure that the context is local as well as successful.
- if (command.isSuccessful() && ctx.isOriginLocal()) {
- log.debug("Origin is local");
- removeFromIndexes(checkForMarshalledValue(valueRemoved), checkForMarshalledValue(command.getKey()).toString());
- }
-
- return valueRemoved;
-
- }
-
-
- @Override
- public Object visitReplaceCommand(InvocationContext ctx, ReplaceCommand command) throws Throwable {
- if (log.isDebugEnabled()) log.debug("Entered the LocalQueryInterceptor visitReplaceCommand()");
-
- Object valueReplaced = invokeNextInterceptor(ctx, command);
-
- // Checking for local as well as making sure that the valueReplaced is not null.
-
- if (valueReplaced != null && ctx.isOriginLocal()) {
-
- if (log.isDebugEnabled()) log.debug("Origin is local");
- Object[] parameters = command.getParameters();
- String keyString = checkForMarshalledValue(command.getKey()).toString();
-
- removeFromIndexes(checkForMarshalledValue(parameters[1]), keyString);
- addToIndexes(checkForMarshalledValue(parameters[2]), keyString);
- }
-
- return valueReplaced;
- }
-
- @Override
- public Object visitPutMapCommand(InvocationContext ctx, PutMapCommand command) throws Throwable {
-
- if (log.isDebugEnabled()) log.debug("Entered LocalQueryInterceptor visitPutMapCommand()");
-
- Object mapPut = invokeNextInterceptor(ctx, command);
-
- // Check to make sure the origin is local.
-
- if (ctx.isOriginLocal()) {
-
- if (log.isDebugEnabled()) log.debug("Origin is local");
- Map<Object, Object> dataMap = command.getMap();
-
- // Loop through all the keys and put those key, value pairings into lucene.
-
- for (Map.Entry entry : dataMap.entrySet()) {
- addToIndexes(entry.getValue(), entry.getKey().toString());
- }
- }
-
- return mapPut;
- }
-
}
Modified: trunk/query/src/main/java/org/infinispan/query/backend/QueryHelper.java
===================================================================
--- trunk/query/src/main/java/org/infinispan/query/backend/QueryHelper.java 2009-11-24 11:42:32 UTC (rev 1208)
+++ trunk/query/src/main/java/org/infinispan/query/backend/QueryHelper.java 2009-11-24 11:43:34 UTC (rev 1209)
@@ -117,13 +117,13 @@
try {
if (indexLocal) {
// Add a LocalQueryInterceptor to the chain
- addInterceptor(LocalQueryInterceptor.class);
+ initComponents(LocalQueryInterceptor.class);
}
// We're indexing data even if it comes from other sources
else {
// Add in a QueryInterceptor to the chain
- addInterceptor(QueryInterceptor.class);
+ initComponents(QueryInterceptor.class);
}
} catch (Exception e) {
throw new CacheException("Unable to add interceptor", e);
@@ -166,7 +166,7 @@
// Private method that adds the interceptor from the classname parameter.
- private void addInterceptor(Class<? extends QueryInterceptor> interceptorClass)
+ private void initComponents(Class<? extends QueryInterceptor> interceptorClass)
throws IllegalAccessException, InstantiationException {
// get the component registry and then register the searchFactory.
Modified: trunk/query/src/main/java/org/infinispan/query/backend/QueryInterceptor.java
===================================================================
--- trunk/query/src/main/java/org/infinispan/query/backend/QueryInterceptor.java 2009-11-24 11:42:32 UTC (rev 1208)
+++ trunk/query/src/main/java/org/infinispan/query/backend/QueryInterceptor.java 2009-11-24 11:43:34 UTC (rev 1209)
@@ -12,6 +12,7 @@
import org.infinispan.factories.annotations.Inject;
import org.infinispan.interceptors.base.CommandInterceptor;
import org.infinispan.marshall.MarshalledValue;
+import static org.infinispan.query.KeyTransformationHandler.keyToString;
import javax.transaction.TransactionManager;
import java.util.Map;
@@ -41,19 +42,22 @@
this.transactionManager = transactionManager;
}
+ protected boolean shouldModifyIndexes(InvocationContext ctx) {
+ return true;
+ }
@Override
public Object visitPutKeyValueCommand(InvocationContext ctx, PutKeyValueCommand command) throws Throwable {
// This method will get the put() calls on the cache and then send them into Lucene once it's successful.
-
- if (log.isDebugEnabled()) log.debug("Entered the searchable core interceptor visitPutKeyValueCommand()");
-
// do the actual put first.
Object toReturn = invokeNextInterceptor(ctx, command);
- addToIndexes(checkForMarshalledValue(command.getValue()), checkForMarshalledValue(command.getKey()).toString());
+ if (shouldModifyIndexes(ctx)) {
+ addToIndexes(extractValue(command.getKey()), extractValue(command.getValue()));
+ }
+
return toReturn;
}
@@ -67,8 +71,8 @@
if (log.isDebugEnabled()) log.debug("Transaction Manager is " + transactionManager);
- if (command.isSuccessful()) {
- removeFromIndexes(checkForMarshalledValue(valueRemoved), checkForMarshalledValue(command.getKey()).toString());
+ if (command.isSuccessful() && shouldModifyIndexes(ctx)) {
+ removeFromIndexes(extractValue(valueRemoved), extractValue(command.getKey()));
}
return valueRemoved;
@@ -82,13 +86,13 @@
if (log.isDebugEnabled()) log.debug("Entered the searchable core interceptor visitReplaceCommand()");
Object valueReplaced = invokeNextInterceptor(ctx, command);
- if (valueReplaced != null) {
+ if (valueReplaced != null && shouldModifyIndexes(ctx)) {
Object[] parameters = command.getParameters();
- String keyString = checkForMarshalledValue(command.getKey()).toString();
+ Object key = extractValue(command.getKey());
- removeFromIndexes(checkForMarshalledValue(parameters[1]), keyString);
- addToIndexes(checkForMarshalledValue(parameters[2]), keyString);
+ removeFromIndexes(extractValue(parameters[1]), key);
+ addToIndexes(extractValue(parameters[2]), key);
}
return valueReplaced;
@@ -101,48 +105,47 @@
Object mapPut = invokeNextInterceptor(ctx, command);
+ if (shouldModifyIndexes(ctx)) {
+ Map<Object, Object> dataMap = command.getMap();
- Map<Object, Object> dataMap = command.getMap();
+ // Loop through all the keys and put those key, value pairings into lucene.
- // Loop through all the keys and put those key, value pairings into lucene.
-
- for (Map.Entry entry : dataMap.entrySet()) {
- addToIndexes(checkForMarshalledValue(entry.getValue()), checkForMarshalledValue(entry.getKey()).toString());
+ for (Map.Entry entry : dataMap.entrySet()) {
+ addToIndexes(extractValue(entry.getValue()), extractValue(entry.getKey()));
+ }
}
return mapPut;
}
// Method that will be called when data needs to be added into Lucene.
- protected void addToIndexes(Object value, String key) {
+ protected void addToIndexes(Object value, Object key) {
+ if (log.isDebugEnabled()) log.debug("Adding to indexes for key [{0}] and value [{0}]", key, value);
// The key here is the String representation of the key that is stored in the cache.
// The key is going to be the documentID for Lucene.
// The object parameter is the actual value that needs to be put into lucene.
TransactionContext transactionContext = new TransactionalEventTransactionContext(transactionManager);
- searchFactory.getWorker().performWork(new Work(value, key, WorkType.ADD), transactionContext);
+ searchFactory.getWorker().performWork(new Work<Object>(value, keyToString(key), WorkType.ADD), transactionContext);
}
// Method that will be called when data needs to be removed from Lucene.
- protected void removeFromIndexes(Object value, String key) {
+ protected void removeFromIndexes(Object value, Object key) {
// The key here is the String representation of the key that is stored in the cache.
// The key is going to be the documentID for Lucene.
// The object parameter is the actual value that needs to be removed from lucene.
TransactionContext transactionContext = new TransactionalEventTransactionContext(transactionManager);
- searchFactory.getWorker().performWork(new Work(value, key, WorkType.DELETE), transactionContext);
+ searchFactory.getWorker().performWork(new Work<Object>(value, keyToString(key), WorkType.DELETE), transactionContext);
}
- // Check to see if a given object is a marshalled value or not.
- protected Object checkForMarshalledValue(Object o) {
- if (o instanceof MarshalledValue) {
- return ((MarshalledValue) o).get();
- } else {
- return o;
- }
+ private Object extractValue(Object wrappedValue) {
+ if (wrappedValue instanceof MarshalledValue)
+ return ((MarshalledValue) wrappedValue).get();
+ else
+ return wrappedValue;
}
-
}
Modified: trunk/query/src/main/java/org/infinispan/query/impl/CacheQueryImpl.java
===================================================================
--- trunk/query/src/main/java/org/infinispan/query/impl/CacheQueryImpl.java 2009-11-24 11:42:32 UTC (rev 1208)
+++ trunk/query/src/main/java/org/infinispan/query/impl/CacheQueryImpl.java 2009-11-24 11:43:34 UTC (rev 1209)
@@ -47,6 +47,7 @@
import org.infinispan.Cache;
import org.infinispan.query.CacheQuery;
import org.infinispan.query.QueryIterator;
+import org.infinispan.query.KeyTransformationHandler;
import org.infinispan.query.backend.IndexSearcherCloser;
import java.io.IOException;
@@ -290,21 +291,21 @@
DocumentExtractor extractor = new DocumentExtractor(queryHits, searchFactory, indexProjection, idFieldNames, allowFieldSelectionInProjection);
- List<Object> keysForCache = new ArrayList<Object>(size);
+ List<String> keysForCache = new ArrayList<String>(size);
for (int index = first; index <= max; index++) {
// Since the documentId is same thing as the key in each key, value pairing. We can just get the documentId
// from Lucene and then get it from the cache.
// The extractor.extract.id gives me the documentId that we need.
- Object cacheKey = extractor.extract(index).id;
+ String cacheKey = extractor.extract(index).id.toString(); // these are always strings
keysForCache.add(cacheKey);
}
// Loop through my list of keys and get it from the cache. Put each object that I get into a separate list.
List<Object> listToReturn = new ArrayList<Object>(size);
- for (Object key : keysForCache) {
- listToReturn.add(cache.get(key));
+ for (String key : keysForCache) {
+ listToReturn.add(cache.get(KeyTransformationHandler.stringToKey(key)));
}
More information about the infinispan-commits
mailing list