Label Cloud

Tuesday, April 07, 2009

Linq to Coherence + Attributes + MetaData = Cool

First, we got the Linq Provider for Oracle Coherence

Second, we got attribute based serialization

Third, Metadata in the serialization stream

Once we put all that together, what we get is a set of very clean way of storing and querying data in Oracle Coherence.

A Coherence Linq provider now supports passing a CoherenceQueryTranslator as a parameter. I am providing a MetadataCoherenceQueryTranslator that uses getProperty method to access property originally serialized by the Generic Serializer. Here’s almost all relative .Net Code:

Person Class

[POFSerializableObject(StoreMetadata=true)]
    public class Person// : IPortableObject
    {
        [POFSerializableMember(Order=0,WriteAsType=POFWriteAsTypeEnum.Int16)]
        public int ID { get; set; }
        [POFSerializableMember(Order=1)]
        public string FirstName { get; set; }
        [POFSerializableMember(Order = 2)]
        public string LastName { get; set; }
        [POFSerializableMember(Order = 3)]
        public string Address { get; set; }
        [POFSerializableMember(Order = 4)]
        public string Title { get; set; }
        public Person()
        {
        }
    }
Add object function
INamedCache cache = CacheFactory.GetCache("dist-Person");
for (int i = 0; i < 1000; i++)
{
cache.Add(i, new Person()
{
   ID = i,
   FirstName = string.Format("First Name {0}", i),
   LastName = string.Format("LastName {0}", i),
   Address = string.Format("Address {0}" , Guid.NewGuid()) ,
   Title = i % 2  == 1 ? "Mr" : "Mrs"
   });
}

Query using Linq Query:

CoherenceQuery<Person> coherenceData =
 new CoherenceQuery<Person>(
	 new CoherenceQueryProvider(CacheFactory.GetCache("dist-Person"), 
		 new MetadataCoherenceQueryTranslator()));
string likeClause = "%8";
var people = from person in coherenceData
			 where
				(person.FirstName.Like("Test")
				 || person.LastName.Like(likeClause))
				 && person.Title == "Mrs"
			 select new { person.Title, person.ID, person.LastName };
IFilter filter = ((ICoherenceQueryable)people).Filter;
dataGridView1.DataSource = people.ToArray();

Internally, MetadataCoherenceQueryTranslator, will convert the linq query into a filter and execute the query against the Java POFGenericObject


Share/Save/Bookmark

Monday, April 06, 2009

99.9% pure .NET Coherence (100 % No Java Code Required)

Its not 100% .NET Coherence, since a developer is required to modify configuration files on the java service to specify the generic POF Serializer.

So to start: The .NET Class:

 

    [POFSerializableObject(StoreMetadata=true)]
    public class Person
    {
        [POFSerializableMember(Order=0,WriteAsType=POFWriteAsTypeEnum.Int16)]
        public int ID { get; set; }
        [POFSerializableMember(Order=1)]
        public string FirstName { get; set; }
        [POFSerializableMember(Order = 2)]
        public string LastName { get; set; }
        [POFSerializableMember(Order = 3)]
        public string Address { get; set; }
        [POFSerializableMember(Order = 4)]
        public string Title { get; set; }
        public Person()
        {
        }
        
    }

Note the StoreMetadata=true argument. When StoreMetadata is specified, Generic serializer will first first write a string array of property names. On server side, we must specify a Generic Java serializer. This is needed to be able to store objects for filtering. Here’s an interesting note. Unless filters are invoked, the object WILL NOT be deserialized on the java side. That means, Put, Get, GetAll calls without a filter, do not require Metadata to be written into the cache. Now. To specify Java Generic Serializer. Distributed Cache Configuration:

      <distributed-scheme>
      <scheme-name>dist-default</scheme-name>
      <serializer>
		<class-name>com.tangosol.io.pof.ConfigurablePofContext</class-name>
		<init-params>
		  <init-param>
			<param-type>string</param-type>
			<param-value>custom-types-pof-config.xml</param-value>
		  </init-param>
		</init-params>
	  </serializer>
      <backing-map-scheme>
        <local-scheme/>
      </backing-map-scheme>
      <autostart>true</autostart>
    </distributed-scheme>

custom-types-pof-config.xml

<pof-config>
  <user-type-list>
    <!-- include all "standard" Coherence POF user types -->
    <include>coherence-pof-config.xml</include>
    <!-- include all application POF user types -->
    <user-type>
      <type-id>1001</type-id>
      <class-name>com.Coherence.Contrib.POF.POFGenericObject</class-name>
      <serializer>
        <class-name>com.Coherence.Contrib.POF.POFGenericSerializer</class-name>
        <init-params>
           <init-param>
             <param-type>int</param-type>
             <param-value>{type-id}</param-value>
           </init-param>
           <init-param>
            <param-type>boolean</param-type>
             <param-name>LoadMetadata</param-name>
             <param-value>true</param-value>
           </init-param>
         </init-params>        
	  </serializer>
    </user-type>
  </user-type-list>
</pof-config>

For now, you must specify a user-type for each .Net object. On the java side, the server will be using the POFGeneicSerializer, and all values in the object array indexed by the property names. A generic getProperty method is implemented to allow filtering on any property that was used in the serialization. Property evaluation is happening on the server, so only filtered data is returned.

Here’s a simple loop to add an object into the cache

INamedCache cache = CacheFactory.GetCache("dist-Person");
for (int i = 0; i < 1000; i++)
{
    cache.Add(i, new Person()
    {
       ID = i,
       FirstName = string.Format("First Name {0}", i),
       LastName = string.Format("LastName {0}", i),

       Address = string.Format("Address {0}" , Guid.NewGuid()) ,
       Title = i % 2  == 1 ? "Mr" : "Mrs"
    });
}

A cool side effect, data can be accessed from .Net and from Java code in the same fashion.


Share/Save/Bookmark

Attributes based Coherence POF Serializer

As much as I love Oracle Coherence, it is a very much a Java product. .Net has lots of cool tricks that can be used during programming, however, they are not implemented in Coherence .Net

Many .Net developers are used to using attributes to define object serialization. A Coherence Generic serializer allows a developer to specify POF Serialization using object attributes as well. Here’s a simple example

    [POFSerializableObject()]
    public class Person// : IPortableObject
    {
        [POFSerializableMember(Order=0,WriteAsType=POFWriteAsTypeEnum.Int16)]
        public int ID { get; set; }
        [POFSerializableMember(Order=1)]
        public string FirstName { get; set; }
        [POFSerializableMember(Order = 2)]
        public string LastName { get; set; }
        [POFSerializableMember(Order = 3)]
        public string Address { get; set; }
        [POFSerializableMember(Order = 4)]
        public string Title { get; set; }
        public Person()
        {
        }
        //#region IPortableObject Members
        //public void ReadExternal(IPofReader reader)
        //{
        //    ID = reader.ReadInt32(0);
        //    FirstName = reader.ReadString(1);
        //    LastName = reader.ReadString(2);
        //    Address = reader.ReadString(3);
        //    Title = reader.ReadString(4);
        //}
        //public void WriteExternal(IPofWriter writer)
        //{
        //    writer.WriteInt32(0, ID);
        //    writer.WriteString(1, FirstName);
        //    writer.WriteString(2, LastName);
        //    writer.WriteString(3, Address);
        //    writer.WriteString(4, Title);
        //}
        //#endregion
    }

To force Coherence to use the serialization attribute, use the the Coherence Generic Serializer in the POF Configuration File

    <user-type>
      <type-id>1001</type-id>
      <class-name>CoherenceSample.Person, CoherenceSample</class-name>
      <serializer>
        <class-name>Coherence.Contrib.POFGenericSerializer, Coherence.Contrib</class-name>
      </serializer>
    </user-type>

Some important points to mention:

  • Object must include POFSerializableObject attribute
  • Generic Serializer will serialize Properties and Members
  • Objects MUST NOT implement IPortableObject. Doing so will force Coherence to use ReadExternal and WriteExternal functions instead of a custom serializer
  • Order parameter of the attribute is optional. The order of serialization is Order, Alphabetical Ascending. Meaning. Multiple attributes can have the same order argument, and will be serialized in alphabetical order
  • WriteAsType parameter is optional and is usually derived based on the source type.
  • Serializer uses Converter.Convert() to convert between object types.
  • Most (but not all) main types are implemented. Check out the source code for specifics
  • Hardcoding a serializer still provides better performance due to extra boxing and object conversion performed by the serializer.

Please check out the latest code on Google Code: http://code.google.com/p/linqtocoherence

Technorati Tags: ,,,


Share/Save/Bookmark

Friday, April 03, 2009

Glad to have my IPhone back

My IPhone didn’t work this morning, so I wound up using a loaner Blackberry. Now… I’ve used a blackberry for over 5 years before my IPhone, and the interface didn’t change much. However, switching back was definitely an eye opener. Let’s just say I am glad my IPhone is back in business.

What I’ve learned:

Pro IPhone

  • I can type just as fast on the IPhone as I can on the blackberry. Since the IPhone “keys” are actually bigger, I even like IPhone typing more then blackberry typing.
  • I miss all the additional apps that I’ve installed on my IPhone. And they are not available on the blackberry

Pro Blackberry (I really wish IPhone had these)

  • Battery Life – It keeps going, and going, and going. Last time I charged it was 2 days ago. And it still has 2 out of 5 battery bars left
  • Blinking red light tells me I have new emails. I can see that from across the room.
  • EMail Shortcuts (T – Top / B – Bottom / U – Unread email)
  • Some additional email functionality – Mark all as read. Delete All Older EMail (from blackberry)
  • Quiet mode – The IPhone has only Sound and / Vibrate. Blackberry has multiple settings.
  • Brick Breaker – Spent 45 minutes playing it on the bus. I miss it.

At the end, I am glad that I have my IPhone back. Blackberry is a great business device, but a mediocre consumer accessory. I wish IPhone gets a better batter life and a few EMail / Calendar improvements.

Technorati Tags: ,,


Share/Save/Bookmark