package com.onpositive.gae.profiling.rpc;
import java.util.HashMap;
import com.google.appengine.api.memcache.MemcacheServicePb.MemcacheGetRequest;
import com.google.appengine.api.memcache.MemcacheServicePb.MemcacheGetResponse;
import com.google.appengine.api.memcache.MemcacheServicePb.MemcacheGetRequest.Builder;
import com.google.appengine.repackaged.com.google.protobuf.InvalidProtocolBufferException;
import com.google.apphosting.api.DatastorePb.GetResponse;
import com.onpositive.gae.profiling.rpc.MemCacheStorageAttachment.DeleteFromMemcacheRequestInfo;
import com.onpositive.gae.profiling.rpc.MemCacheStorageAttachment.GetFromMemcacheRequestInfo;
import com.onpositive.gae.profiling.rpc.MemCacheStorageAttachment.SetRequestInfo;
import com.onpositive.gae.profiling.rpc.RPCAttachment.RequestInfo;
import com.onpositive.traps.ICallStorageAttachment;
import com.onpositive.traps.Profiler;
public class MemCacheProcessor implements IRPCCallProcessor {
private HashMap<String, ICallInterceptor> interceptors = new HashMap<String, ICallInterceptor>();
static MemCacheStorageAttachment attachment = null;
static HashMap<RequestInfo, RequestInfo> infoMap = null;
static {
init();
}
private static void init() {
ICallStorageAttachment attachment2 = Profiler
.getAttachment(MemCacheStorageAttachment.class);
if (attachment2 == null) {
Profiler.putAttachment(new MemCacheStorageAttachment());
}
attachment = (MemCacheStorageAttachment) Profiler
.getAttachment(MemCacheStorageAttachment.class);
infoMap = attachment.infoMap;
}
public RequestInfo storedInfo(RequestInfo inf) {
RequestInfo requestInfo = infoMap.get(inf);
if (requestInfo == null) {
infoMap.put(inf, inf);
return inf;
}
return requestInfo;
}
public void recordInfo(RequestInfo inf) {
RequestInfo requestInfo = infoMap.get(inf);
if (requestInfo != null) {
inf.merge(requestInfo);
}
infoMap.put(inf, inf);
if (infoMap.size() > 10) {
long min = Long.MAX_VALUE;
RequestInfo mi = null;
for (RequestInfo i : infoMap.keySet()) {
if (i.cost < min) {
mi = i;
min = i.cost;
}
}
if (mi != null) {
infoMap.remove(mi);
}
}
}
public class GetInterCeptor implements ICallInterceptor {
private MemCacheStorageAttachment.GetFromMemcacheRequestInfo requestInfo;
public synchronized void postCall(byte[] result) {
Exception exception = new Exception();
exception.fillInStackTrace();
StackTraceElement[] stackTrace = exception.getStackTrace();
requestInfo = new GetFromMemcacheRequestInfo("Get Request", stackTrace);
if (requestInfo != null) {
try {
MemcacheGetResponse mergeFrom = MemcacheGetResponse.parseFrom(result);
int keyCount = mergeFrom.getItemCount();
requestInfo.successes += keyCount;
requestInfo.totalCount+=this.keyCount;
} catch (InvalidProtocolBufferException e) {
}
requestInfo.count++;
recordInfo(requestInfo);
}
}
int keyCount;
public synchronized void preCall(byte[] call) {
try {
MemcacheGetRequest mergeFrom=MemcacheGetRequest.parseFrom(call);
keyCount=mergeFrom.getKeyCount();
} catch (InvalidProtocolBufferException e) {
keyCount=0;
}
}
public void stat(int delta) {
storedInfo(requestInfo).cost += delta;
}
}
public class PutInterceptor implements ICallInterceptor {
SetRequestInfo requestInfo;
public synchronized void postCall(byte[] result) {
if (requestInfo != null) {
//updateInfo(requestInfo, cost);
recordInfo(requestInfo);
}
}
public synchronized void preCall(byte[] call) {
Exception exception = new Exception();
exception.fillInStackTrace();
StackTraceElement[] stackTrace = exception.getStackTrace();
requestInfo = new SetRequestInfo("Set", stackTrace);
requestInfo.count=1;
}
public void stat(int delta) {
storedInfo(requestInfo).cost += delta;
}
}
public class DeleteInterceptor implements ICallInterceptor {
DeleteFromMemcacheRequestInfo requestInfo;
public synchronized void postCall(byte[] result) {
if (requestInfo != null) {
//updateInfo(requestInfo, cost);
recordInfo(requestInfo);
}
}
public synchronized void preCall(byte[] call) {
Exception exception = new Exception();
exception.fillInStackTrace();
StackTraceElement[] stackTrace = exception.getStackTrace();
requestInfo = new DeleteFromMemcacheRequestInfo("Delete", stackTrace);
requestInfo.count=1;
}
public void stat(int delta) {
storedInfo(requestInfo).cost += delta;
}
}
public MemCacheProcessor() {
interceptors.put("Get", new GetInterCeptor());
interceptors.put("Set", new PutInterceptor());
interceptors.put("Delete", new DeleteInterceptor());
}
public String getPackage() {
return "memcache";
}
public void postCall(String name, byte[] result) {
ICallInterceptor iCallInterceptor = interceptors.get(name);
if (iCallInterceptor != null) {
iCallInterceptor.postCall(result);
}
}
ICallInterceptor interceptor;
public void preCall(String name, byte[] data) {
ICallInterceptor iCallInterceptor = interceptors.get(name);
if (iCallInterceptor != null) {
iCallInterceptor.preCall(data);
interceptor = iCallInterceptor;
}
}
public static void clear() {
init();
}
public void stat(int delta) {
if (interceptor != null) {
interceptor.stat(delta);
}
}
}