/** * */ package com.meidusa.amoeba.mongodb.handler.merge; import java.util.ArrayList; import java.util.List; import org.apache.commons.collections.map.LRUMap; import org.bson.BSONObject; import com.meidusa.amoeba.mongodb.packet.QueryMongodbPacket; import com.meidusa.amoeba.mongodb.packet.RequestMongodbPacket; import com.meidusa.amoeba.mongodb.packet.ResponseMongodbPacket; /** * * @author Struct */ public class GroupFunctionMerge implements FunctionMerge{ private static LRUMap groupReducerMap = new LRUMap(1000); @SuppressWarnings("unchecked") @Override public ResponseMongodbPacket mergeResponse(RequestMongodbPacket requestPacket, List<ResponseMongodbPacket> multiResponsePacket) { QueryMongodbPacket queryPacket = (QueryMongodbPacket)requestPacket; ResponseMongodbPacket result = null; List inputs = new ArrayList(); for(ResponseMongodbPacket response : multiResponsePacket){ if(response.numberReturned >0 && response.documents != null){ List list = (List)response.documents.get(0).get("retval"); if(list != null && list.size()>0){ if(result == null){ result = response; } inputs.add(list); } } } BSONObject groupBSONObject = (BSONObject)queryPacket.query.get("group"); BSONObject keys = (BSONObject)groupBSONObject.get("key"); String reduce = (String)groupBSONObject.get("$reduce"); String finalize = (String)groupBSONObject.get("finalize"); long key = (keys != null?(keys.hashCode()<<16):0)+(reduce != null?(reduce.hashCode()<<8):0)+(finalize != null?(finalize.hashCode()):0); GroupReducer groupReducer = (GroupReducer) groupReducerMap.get(key); if(groupReducer == null){ synchronized (groupReducerMap) { groupReducer = (GroupReducer) groupReducerMap.get(key); if(groupReducer == null){ groupReducer = new GroupReducer(); groupReducer.initial(keys, reduce, finalize); groupReducerMap.put(key, groupReducer); } } } BSONObject res = result.documents.get(0); res.put("retval",groupReducer.reduce(inputs)); result.responseTo = requestPacket.requestID; result.numberReturned = (result.documents == null?0:result.documents.size()); return result; } }