package test;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.stream.LongStream;
import javax.cache.configuration.FactoryBuilder;
import javax.cache.integration.CacheLoaderException;
import org.apache.ignite.Ignite;
import org.apache.ignite.IgniteCache;
import org.apache.ignite.Ignition;
import org.apache.ignite.cache.CacheMode;
import org.apache.ignite.cache.store.CacheLoadOnlyStoreAdapter;
import org.apache.ignite.configuration.CacheConfiguration;
import org.apache.ignite.configuration.IgniteConfiguration;
import org.apache.ignite.lang.IgniteBiTuple;

/**
 * Can't reproduced.
 */
public class MissedEntries {

    /** */
    private static final int NODES_CNT = 2;

    /** */
    private static final int CACHE_SIZE = 5_000_000;

    /** */
    private static CacheConfiguration cacheConfig(String cacheName) {
        CacheConfiguration<Long, ArrayList> cacheCfg = new CacheConfiguration<>(cacheName);
        cacheCfg.setStartSize(CACHE_SIZE);
        cacheCfg.setCacheMode(CacheMode.LOCAL);
        cacheCfg.setIndexedTypes(Long.class, ArrayList.class);

        cacheCfg.setCacheStoreFactory(FactoryBuilder.factoryOf(MyCacheLoadOnlyStore.class));

        return cacheCfg;
    }

    /** */
    public static void main(String[] args) {
        try {
            Ignite ignite = Ignition.start(new IgniteConfiguration().setGridName("node-0"));

            for(int i = 1; i < NODES_CNT; i++)
                Ignition.start(new IgniteConfiguration().setGridName("node-"+i));

            IgniteCache cache = ignite.createCache(cacheConfig("myCache"));

            cache.loadCache(null);

            int size = cache.size();

            System.out.println("size: " + size);

            if (CACHE_SIZE != size)
                throw new AssertionError("Data lost.");
        }
        finally {
            Ignition.stopAll(true);
        }
    }

    /**
     *
     */
    public static class MyCacheLoadOnlyStore extends CacheLoadOnlyStoreAdapter<Long, ArrayList, Long> {
        /** {@inheritDoc} */
        @Override protected Iterator<Long> inputIterator(Object... args) throws CacheLoaderException {
            return LongStream.range(0,CACHE_SIZE).iterator();
        }

        /** {@inheritDoc} */
        @Override protected IgniteBiTuple<Long, ArrayList> parse(Long rec, Object... args) {
            ArrayList<Object> val1 = new ArrayList<>(1);
            val1.add("val-" + rec);
            return new IgniteBiTuple<>(rec, val1);
        }
    }
}