/*
 *  Licensed to the Apache Software Foundation (ASF) under one or more
 *  contributor license agreements.  See the NOTICE file distributed with
 *  this work for additional information regarding copyright ownership.
 *  The ASF licenses this file to You under the Apache License, Version 2.0
 *  (the "License"); you may not use this file except in compliance with
 *  the License.  You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

package org.apache.ignite.lang;

import java.util.UUID;
import org.apache.ignite.internal.IgniteInterruptedCheckedException;
import org.apache.ignite.internal.processors.cache.eviction.GridCacheMockEntry;
import org.apache.ignite.internal.util.typedef.internal.U;
import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
import org.junit.Test;

/**
 * Check how much memory and time required to fill 1_000_000 entries with meta.
 * Do not include this test to suits.
 */
public class GridMetadataAwareAdapterLoadTest extends GridCommonAbstractTest {
    /** Creates test. */
    public GridMetadataAwareAdapterLoadTest() {
        super(/*start grid*/false);
    }

    private static final String KEY_VALUE = "test";

    /**
     * Junit.
     *
     * @throws Exception
     */
    @Test
    public void test() throws Exception {
        String[] dic = new String[1_000_000];

        for (int i = 0; i < 1_000_000; i++)
            dic[i] = String.valueOf(i);

        doTest(-1, "all 10 keys     ", dic);
        doTest(0, "all 3 keys      ", dic);
        doTest(1, "first key only  ", dic);
        doTest(2, "second key only ", dic);
        doTest(3, "third key only  ", dic);
        doTest(4, "tenth key only  ", dic);
        doTest(5, "random (1-3) key", dic);
        doTest(6, "no meta         ", dic);
    }

    public void doTest(int c, String message, String[] dic) throws IgniteInterruptedCheckedException {
        UUID[] uuids = new UUID[10];

        for (int j = 0; j < 10; j++)
            uuids[j] = UUID.randomUUID();

        for (int t = 0; t < 2; t++) {
            long mTotal = 0;
            long tTotal = 0;

            for (int k = 0; k < 20; k++) {
                System.gc();

                U.sleep(500);

                GridCacheMockEntry[] entries = new GridCacheMockEntry[1_000_000];

                long mBefore = Runtime.getRuntime().freeMemory();
                long tBefore = System.currentTimeMillis();

                for (int i = 0; i < 1_000_000; i++) {
                    GridCacheMockEntry<String, String> entry = new GridCacheMockEntry<>(KEY_VALUE);
                    switch (c) { //commented lines for old API
                        case -1:
                            for (int j = 9; j >= 0; j--)
                                //entry.addMeta(uuids[j], dic[i]);
                            entry.addMeta(j, dic[i]);
                            break;
                        case 0:
                            for (int j = 2; j >= 0; j--)
                                //entry.addMeta(uuids[j], dic[i]);
                            entry.addMeta(j, dic[i]);
                            break;
                        case 1:
                            //entry.addMeta(uuids[0], dic[i]);
                            entry.addMeta(0, dic[i]);
                            break;
                        case 2:
                            //entry.addMeta(uuids[1], dic[i]);
                            entry.addMeta(1, dic[i]);
                            break;
                        case 3:
                            //entry.addMeta(uuids[2], dic[i]);
                            entry.addMeta(2, dic[i]);
                            break;
                        case 4:
                            //entry.addMeta(uuids[9], dic[i]);
                            entry.addMeta(9, dic[i]);
                            break;
                        case 5:
                            //entry.addMeta(uuids[i % 3], dic[i]);
                            entry.addMeta(i % 3, dic[i]);
                            break;
                        case 6:

                            break;
                    }

                    entries[i] = entry;
                }

                long mAfter = Runtime.getRuntime().freeMemory();
                long tAfter = System.currentTimeMillis();

                if (k >= 10) {
                    mTotal += (mBefore - mAfter);
                    tTotal += (tAfter - tBefore);
                }
            }

            log.info(message + " [time=" + tTotal + " ms, memory=" + mTotal / 1_000_000_0 + "." + mTotal % 1_000_000_0 + " mb]");
        }

        log.info(" ");
    }
}
