Tuesday, July 13, 2010

using Btrace to Make sure the filter is using the index you created for Oracle coherence

I am always wondering that Is there any way we can tell the execution plan of the given filter? given the following example.  all in C# code. when the Cache is setup to run in Distributed Mode/Replicated Mode. will the query pickup the index ? will the index get refreshed promptly?
C# sample code,

INamedCache cache = CacheFactory.GetCache(CacheName);
int ctt = 10;
Random rand = new Random();
for (int i = 0; i < ctt; i++)
{
    PurchaseOrder o = new PurchaseOrder();
    o.PoAmount=rand.Next(50000);
    cache.Add( i , o);
}

//Add one Index
INamedCache cache = CacheFactory.GetCache(CacheName);
IValueExtractor extractor = new ReflectionExtractor("getPoAmount");
cache.AddIndex(extractor, true, null);

//Try one Query , like GreatFilter.

INamedCache cache = CacheFactory.GetCache(CacheName);
GreaterFilter filter1 = new GreaterFilter("getPoAmount",10000f);
MessageBox.Show("F" + cache.GetEntries(filter1).Length.ToString() );

I tried several profiling tools. memory profiler,for the question, What’s the memory different after we inserted some objects, and then created some Index. are the replicated mode use different format to store the object. Binary format for the serialized object, or just raw OBJ format.

you can load the jvisualvm.  run two snapshots , and compare it. try searching Index on the comparison report. you will find the following new created objects. Basically, there is one instance called SimpleMapIndex.
  
Then the second question, If there is one Index map, When will the query use it , whether or Not? When will the index get refreshed? say , object update or removal?

Answer: Use Btrace to Inspect the method get called inside SimpleMapIndex.
Here comes my tracing script.

/* BTrace Script Template */

import java.lang.reflect.Field;
import java.util.Map;
import java.util.logging.LogRecord;

import com.sun.btrace.BTraceUtils;
import com.sun.btrace.annotations.*;
import com.tangosol.util.ValueExtractor;

import static com.sun.btrace.BTraceUtils.*;

@BTrace
public class TracingScript {
    /* put your code here */

    @OnMethod(clazz = "com.tangosol.util.SimpleMapIndex", method = "insert", location = @Location(where = Where.BEFORE))
    public static void insert(@Self com.tangosol.util.SimpleMapIndex self,
            Map.Entry a) {
        println("insert Index");
        String s;

    }

    @OnMethod(clazz = "com.tangosol.util.SimpleMapIndex", method = "update", location = @Location(where = Where.BEFORE))
    public static void update(@Self com.tangosol.util.SimpleMapIndex self,
            Map.Entry a) {
        println("update Index");
    }

    @OnMethod(clazz = "com.tangosol.util.SimpleMapIndex", method = "delete", location = @Location(where = Where.BEFORE))
    public static void delete(@Self com.tangosol.util.SimpleMapIndex self,
            Map.Entry a) {
        println("Delete Index");

    }

    // Who is querying index content
    @OnMethod(clazz = "com.tangosol.util.SimpleMapIndex", method = "getIndexContents", location = @Location(value = Kind.RETURN))
    public static void getIndexContents(
            @Self com.tangosol.util.SimpleMapIndex self, @Return Map map) {
             Field msgField = field("com.tangosol.util.SimpleMapIndex", "m_extractor");

        println("getIndexContents");
        println("------------index used ---------------");
        Object o=get(msgField,self);
        println( str(o));
        printFields(o);
        Class cz=classForName("com.tangosol.util.extractor.AbstractCompositeExtractor");
        if(isInstance(cz,get(msgField,self) ))
        {
            println("++++++++++++++++++++++++Chained+++");
            //dump chanied fields;
            Field f2 = field("com.tangosol.util.extractor.AbstractCompositeExtractor", "m_aExtractor");
            Object [] rfs=(Object[])get(f2,o);
            println(BTraceUtils.strcat("Chain Count: ", str(rfs.length)));
            int i=0;
            if(i<rfs.length)
            {
            printFields(rfs[i]);
            i++;
            }
            if(i<rfs.length)
            {
            printFields(rfs[i]);
            i++;
            }
            if(i<rfs.length)
            {
            printFields(rfs[i]);
            i++;
            }
            if(i<rfs.length)
            {
            printFields(rfs[i]);
            i++;
            }

            println("++++++++++++++++++++++++Chained+++");
        }

        println("------------index used ---------------");
        jstack();
    }

}

you may just copy this scipt, and save it to a local folder as TracingScript.java.

run jps to get the cacheserver PID.

   Btrace –cp “path of the coherence.jar” PID “pathofthe sciprt”

then try running the cache in different Mode, i.e replicated mode vs distributed mode.

Answer is interesting, For replicated Mode. all query never pickup the Index.

image

More Coherence Blogs:
 
Locations of visitors to this page