package org.ethereum.db;

import org.ethereum.core.BlockHeader;
import org.ethereum.datasource.mapdb.MapDBFactoryImpl;
import org.ethereum.util.FileUtil;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;

import java.io.IOException;
import java.math.BigInteger;
import java.net.URISyntaxException;
import java.util.Arrays;
import java.util.List;
import java.util.Random;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

import static org.ethereum.config.SystemProperties.CONFIG;

/**
 * Created by Anton Nashatyrev on 25.12.2015.
 */
public class HeaderStoreTest {

    static BlockHeader[] createHeaders(int cnt) {
        BlockHeader[] ret = new BlockHeader[cnt];
        for (int i = 0; i < ret.length; i++) {
            ret[i] = new BlockHeader(new byte[0], new byte[0], new byte[0], new byte[0], new byte[0], i, 0, 0, 0,
                    new byte[0], new byte[0], new byte[0]);
        }
        return ret;
    }

    String testDb;
    HeaderStoreImpl hs;

    @Before
    public void setup() throws InstantiationException, IllegalAccessException, URISyntaxException, IOException {
        BigInteger bi = new BigInteger(32, new Random());
        testDb = "test_db_" + bi;
        CONFIG.setDataBaseDir(testDb);
        CONFIG.setDatabaseReset(false);

        hs = new HeaderStoreImpl();
        hs.setMapDBFactory(new MapDBFactoryImpl());
        hs.open();
    }

    @After
    public void cleanup() {
        hs.close();
        FileUtil.recursiveDelete(testDb);
    }

    @Test
    public void test1() {
        hs.addBatch(Arrays.asList(createHeaders(10)));
        List<BlockHeader> bhs = hs.pollBatch(1000);
        Assert.assertEquals(10, bhs.size());

        hs.add(createHeaders(2)[1]);
        BlockHeader bh = hs.poll();
        Assert.assertEquals(1, bh.getNumber());
    }

    @Test
    public void concurrentTest1() throws InterruptedException {
        final CountDownLatch waiter = new CountDownLatch(1);
        new Thread() {
            @Override
            public void run() {
                for (int i = 0; i < 10; i++) {
                    hs.addBatch(Arrays.asList(createHeaders(10)));
                    System.out.println("Added 10");
                }
            }
        }.start();

        new Thread() {
            int cnt = 0;
            @Override
            public void run() {
                while (cnt < 10 * 10) {
                    List<BlockHeader> ret = hs.pollBatch(100000);
                    if (ret.size() > 0) {
                        System.out.println("Polled " + ret.size());
                    }
                    cnt += ret.size();
                }
                waiter.countDown();
            }
        }.start();
        waiter.await(20, TimeUnit.SECONDS);
        Assert.assertTrue(waiter.getCount() == 0);
    }
}

@@ -492,16 +492,66 @@
 imeUnit;
+%0Aimport java.util.concurrent.atomic.AtomicInteger;
 %0A%0Aimport
@@ -690,16 +690,69 @@
 Test %7B%0A%0A
+    static AtomicInteger cnt = new AtomicInteger();%0A%0A
     stat
@@ -786,17 +786,21 @@
 ers(int 
-c
+headC
 nt) %7B%0A  
@@ -841,17 +841,21 @@
 kHeader%5B
-c
+headC
 nt%5D;%0A   
@@ -1003,20 +1003,8 @@
 %5B0%5D,
- i, 0, 0, 0,
 %0A   
@@ -1015,24 +1015,56 @@
             
+ cnt.getAndIncrement(), 0, 0, 0,
  new byte%5B0%5D

Fix test