// Path: src/main/java/org/rakam/cache/hazelcast/treemap/operations/TreeMapReplicationOperation.java
// public class TreeMapReplicationOperation extends AbstractOperation implements IdentifiedDataSerializable {
// 
//     private Map<String, OrderedCounterMap> migrationData;
// 
//     public TreeMapReplicationOperation(Map<String, OrderedCounterMap> data) {
//         migrationData = data;
//     }
// 
//     public TreeMapReplicationOperation() {
// 
//     }
// 
//     @Override
//     public void run() throws Exception {
//         TreeMapService service = getService();
//         for (Map.Entry<String, OrderedCounterMap> longEntry : migrationData.entrySet()) {
//             String name = longEntry.getKey();
//             service.setHLL(name, longEntry.getValue());
//         }
//     }
// 
// 
//     @Override
//     protected void readInternal(ObjectDataInput in) throws IOException {
//         migrationData = new HashMap();
//         int len = in.readInt();
//         for(int i=0; i<len; i++) {
//             OrderedCounterMap map = new OrderedCounterMap();
//             int internalLength = in.readInt();
//             for(int a=0; a<internalLength; a++) {
//                 map.increment(in.readUTF(), in.readLong());
//             }
//         }
//     }
// 
//     @Override
//     protected void writeInternal(ObjectDataOutput out) throws IOException {
//         out.writeInt(migrationData.size());
//         for (Map.Entry<String, OrderedCounterMap> entry : migrationData.entrySet()) {
//             out.writeUTF(entry.getKey());
//             OrderedCounterMap val = entry.getValue();
//             out.writeObject(val);
//         }
//     }
// 
// 
//     @Override
//     public int getFactoryId() {
//         return TreeMapSerializerFactory.F_ID;
//     }
// 
//     @Override
//     public int getId() {
//         return TreeMapSerializerFactory.REPLICATION;
//     }
// }


import com.hazelcast.partition.InternalPartitionService;
import com.hazelcast.partition.MigrationEndpoint;
import com.hazelcast.spi.*;
import com.hazelcast.util.ConstructorFunction;
import org.rakam.cache.hazelcast.treemap.operations.TreeMapReplicationOperation;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import static com.hazelcast.partition.strategy.StringPartitioningStrategy.getPartitionKey;
import static com.hazelcast.util.ConcurrencyUtil.getOrPutIfAbsent;

    @Override
    public void shutdown(boolean terminate) {
        reset();
    }

    @Override
    public TreeMapProxy createDistributedObject(String name) {
        return new TreeMapProxy(name, nodeEngine, this);
    }

    @Override
    public void destroyDistributedObject(String name) {
        containers.remove(name);
    }

    @Override
    public void beforeMigration(PartitionMigrationEvent partitionMigrationEvent) {
    }

    @Override
    public Operation prepareReplicationOperation(PartitionReplicationEvent event) {
        Map<String, OrderedCounterMap> data = new HashMap();
        int partitionId = event.getPartitionId();
        for (String name : containers.keySet()) {
            if (partitionId == getPartitionId(name)) {
                OrderedCounterMap number = containers.get(name);
                data.put(name, number);
            }
        }
// Path: src/main/java/org/rakam/cache/hazelcast/treemap/operations/TreeMapReplicationOperation.java
// public class TreeMapReplicationOperation extends AbstractOperation implements IdentifiedDataSerializable {
// 
//     private Map<String, OrderedCounterMap> migrationData;
// 
//     public TreeMapReplicationOperation(Map<String, OrderedCounterMap> data) {
//         migrationData = data;
//     }
// 
//     public TreeMapReplicationOperation() {
// 
//     }
// 
//     @Override
//     public void run() throws Exception {
//         TreeMapService service = getService();
//         for (Map.Entry<String, OrderedCounterMap> longEntry : migrationData.entrySet()) {
//             String name = longEntry.getKey();
//             service.setHLL(name, longEntry.getValue());
//         }
//     }
// 
// 
//     @Override
//     protected void readInternal(ObjectDataInput in) throws IOException {
//         migrationData = new HashMap();
//         int len = in.readInt();
//         for(int i=0; i<len; i++) {
//             OrderedCounterMap map = new OrderedCounterMap();
//             int internalLength = in.readInt();
//             for(int a=0; a<internalLength; a++) {
//                 map.increment(in.readUTF(), in.readLong());
//             }
//         }
//     }
// 
//     @Override
//     protected void writeInternal(ObjectDataOutput out) throws IOException {
//         out.writeInt(migrationData.size());
//         for (Map.Entry<String, OrderedCounterMap> entry : migrationData.entrySet()) {
//             out.writeUTF(entry.getKey());
//             OrderedCounterMap val = entry.getValue();
//             out.writeObject(val);
//         }
//     }
// 
// 
//     @Override
//     public int getFactoryId() {
//         return TreeMapSerializerFactory.F_ID;
//     }
// 
//     @Override
//     public int getId() {
//         return TreeMapSerializerFactory.REPLICATION;
//     }
// }


// Path: src/main/java/org/rakam/cache/hazelcast/treemap/TreeMapService.java
import com.hazelcast.partition.InternalPartitionService;
import com.hazelcast.partition.MigrationEndpoint;
import com.hazelcast.spi.*;
import com.hazelcast.util.ConstructorFunction;
import org.rakam.cache.hazelcast.treemap.operations.TreeMapReplicationOperation;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import static com.hazelcast.partition.strategy.StringPartitioningStrategy.getPartitionKey;
import static com.hazelcast.util.ConcurrencyUtil.getOrPutIfAbsent;


    @Override
    public void shutdown(boolean terminate) {
        reset();
    }

    @Override
    public TreeMapProxy createDistributedObject(String name) {
        return new TreeMapProxy(name, nodeEngine, this);
    }

    @Override
    public void destroyDistributedObject(String name) {
        containers.remove(name);
    }

    @Override
    public void beforeMigration(PartitionMigrationEvent partitionMigrationEvent) {
    }

    @Override
    public Operation prepareReplicationOperation(PartitionReplicationEvent event) {
        Map<String, OrderedCounterMap> data = new HashMap();
        int partitionId = event.getPartitionId();
        for (String name : containers.keySet()) {
            if (partitionId == getPartitionId(name)) {
                OrderedCounterMap number = containers.get(name);
                data.put(name, number);
            }
        }
        return data.isEmpty() ? null : new TreeMapReplicationOperation(data);