I am very impressed with Coherence from Oracle. Coherence provides a distributed in-memory cache and processing fabric. However it is a lot more then just a cache. It can be used for everything from messaging to cross platform communication medium. There is too much to talk say about it, so read more information at Oracle: http://www.oracle.com/technology/products/coherence/index.html
Coherence works very nicely with .Net however, in the days of Linq, I wanted to write a Linq provider for it. My code is based largely on the Linq provider documentation on MSDN (http://msdn.microsoft.com/en-us/library/bb546158.aspx) and excellent series on creating a linq provider by Matt Warren (http://blogs.msdn.com/mattwar/pages/linq-links.aspx)
I am using Google Code to host the project under Artistic License. Please check out the full source code at http://code.google.com/p/linqtocoherence/.
Below is a rundown on two main classes. The main part of the code that deals with Coherence is in two classes CoherenceQueryProvider and CoherenceQueryTranslator.
CoherenceQueryProvider accepts a connection to the INamedCache – a reference to coherence cache that will be queried.
public class CoherenceQueryProvider : IQueryProvider
{
public INamedCache Cache { get; set; }
public CoherenceQueryProvider ()
{
}
public CoherenceQueryProvider(INamedCache cache)
{
Cache = cache;
}
In the Execute method, CoherenceQueryProvider translates the Where clause to a Coherence Filter and executes the filter against the Cache objects to return array of values.
public object Execute(Expression expression)
{
if (Cache == null)
throw new InvalidOperationException("Cache is not properly set");
// Find the call to Where() and get the lambda expression predicate.
InnermostWhereFinder whereFinder = new InnermostWhereFinder();
MethodCallExpression whereExpression = whereFinder.GetInnermostWhere(expression);
LambdaExpression lambdaExpression = (LambdaExpression)((UnaryExpression)(whereExpression.Arguments[1])).Operand;
// Send the lambda expression through the partial evaluator.
lambdaExpression = (LambdaExpression)Evaluator.PartialEval(lambdaExpression);
IFilter filter = new CoherenceQueryTranslator().Translate(lambdaExpression);
object[] data = Cache.GetValues(filter);
Type elementType = TypeSystem.GetElementType(expression.Type);
return data;
}
CoherenceQueryTranslater uses the visitor pattern to convert the Linq Expression from the where clause to Coherence Filter. Coherence filters are nested to converting one to the other is relatively simple
protected override Expression VisitBinary(BinaryExpression b)
{
this.Visit(b.Left);
object lastGlobal1 = globalFilter;
this.Visit(b.Right);
object lastGlobal2 = globalFilter;
switch (b.NodeType)
{
case ExpressionType.AndAlso:
globalFilter = new AndFilter((IFilter) lastGlobal1, (IFilter)lastGlobal2);
break;
case ExpressionType.OrElse:
globalFilter = new OrFilter((IFilter) lastGlobal1, (IFilter)lastGlobal2);
break;
There is a lot more code in the classes to handle other filters, but a lot of it is pretty repetitive. The work on the linq provider is not done and I still have to implement some of the coherence functionality. Full code and usage sample is available on google code http://code.google.com/p/linqtocoherence/
Check it out and post your comments / suggestions.
Linq provider for Oracle Coherence (Linq to Coherence)