All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.objectfabric.TMapSimple Maven / Gradle / Ivy

There is a newer version: 0.9.1
Show newest version
/**
 * This file is part of ObjectFabric (http://objectfabric.org).
 *
 * ObjectFabric is licensed under the Apache License, Version 2.0, the terms
 * of which may be found at http://www.apache.org/licenses/LICENSE-2.0.html.
 * 
 * Copyright ObjectFabric Inc.
 * 
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
 * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */

package org.objectfabric;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.atomic.AtomicInteger;

import org.junit.Assert;
import org.junit.Test;

public class TMapSimple extends TestsHelper {

    private static final boolean LOG = false;

    private static final int CYCLES = Debug.ENABLED ? 10 : 100;

    @Test
    public void run() throws Exception {
        final Workspace workspace = Platform.newTestWorkspace();

        Logger logger = null;

        if (LOG)
            logger = new Logger(workspace, workspace.callbackExecutor());

        final TMap map = new TMap(workspace.resolve(""));
        final CyclicBarrier barrier = new CyclicBarrier(2);
        final CountDownLatch latch = new CountDownLatch(1);
        final AtomicInteger attempts = new AtomicInteger();

        Thread thread = new Thread() {

            @Override
            public void run() {
                workspace.atomic(new Runnable() {

                    @Override
                    public void run() {
                        map.put(0, "A");
                        map.put(1, "B");

                        Assert.assertEquals("A", map.get(0));
                        Assert.assertEquals("B", map.get(1));
                        Assert.assertEquals(2, map.size());

                        try {
                            barrier.await();
                        } catch (Exception e) {
                            throw new RuntimeException(e);
                        }

                        try {
                            latch.await();
                        } catch (InterruptedException e) {
                            throw new RuntimeException(e);
                        }

                        attempts.incrementAndGet();
                    }
                });
            }
        };

        thread.start();
        barrier.await();

        Assert.assertEquals(null, map.get(0));
        Assert.assertEquals(null, map.get(1));
        Assert.assertEquals(0, map.size());

        map.put(0, "X");
        map.put(1, "Y");

        Assert.assertEquals("X", map.get(0));
        Assert.assertEquals("Y", map.get(1));
        Assert.assertEquals(2, map.size());

        latch.countDown();
        barrier.await();
        thread.join();

        Assert.assertEquals("A", map.get(0));
        Assert.assertEquals("B", map.get(1));
        Assert.assertEquals(2, map.size());
        Assert.assertEquals(2, attempts.get());

        map.put(10, "test");

        Assert.assertEquals(3, map.size());

        try {
            workspace.atomic(new Runnable() {

                @Override
                public void run() {
                    map.remove(0);
                    map.remove(1);
                    Assert.assertEquals(1, map.size());
                    map.remove(10);
                    Assert.assertEquals(0, map.size());
                    ExpectedExceptionThrower.expectException();
                    ExpectedExceptionThrower.throwRuntimeException("");
                }
            });
        } catch (RuntimeException ex) {
        }

        //

        Assert.assertEquals(3, map.size());

        map.remove(0);
        map.remove(1);

        Assert.assertEquals("test", map.get(10));
        Assert.assertEquals(1, map.size());

        final CyclicBarrier barrier1 = new CyclicBarrier(2);
        final CyclicBarrier barrier2 = new CyclicBarrier(2);
        attempts.set(0);

        thread = new Thread() {

            @Override
            public void run() {
                workspace.atomic(new Runnable() {

                    @Override
                    public void run() {
                        map.put(0, "A");

                        try {
                            barrier1.await();
                        } catch (Exception e) {
                            throw new RuntimeException(e);
                        }

                        Assert.assertEquals("A", map.get(0));
                        attempts.incrementAndGet();

                        try {
                            barrier2.await();
                        } catch (Exception e) {
                            throw new RuntimeException(e);
                        }
                    }
                });
            }
        };

        thread.start();
        barrier1.await();
        map.put(0, "X");
        barrier2.await();
        barrier1.await();
        barrier2.await();
        thread.join();
        Assert.assertEquals("A", map.get(0));
        Assert.assertEquals(2, attempts.get());
        Assert.assertEquals(2, map.size());

        if (LOG)
            logger.close();

        workspace.close();
    }

    @Test
    public void sizePrivatePublic() {
        final Workspace workspace = Platform.newTestWorkspace();
        final TMap map = new TMap(workspace.resolve(""));

        map.put("A", 0);
        map.put("B", 1);
        map.put("C", 2);

        workspace.atomic(new Runnable() {

            @Override
            public void run() {
                map.remove("A");
                map.remove("B");
                map.remove("C");
                Assert.assertEquals(0, map.size());
            }
        });

        Assert.assertEquals(0, map.size());

        workspace.atomic(new Runnable() {

            @Override
            public void run() {
                map.put("A", 0);
                map.remove("A");
                Assert.assertEquals(0, map.size());
            }
        });

        Assert.assertEquals(0, map.size());
        workspace.close();
    }

    @Test
    public void loop1() {
        final Workspace workspace = Platform.newTestWorkspace();
        final TMap map = new TMap(workspace.resolve(""));

        for (int i = 0; i < CYCLES; i++) {
            workspace.atomic(new Runnable() {

                @Override
                public void run() {
                    addRemove1(map);
                }
            });
        }

        workspace.close();
    }

    @Test
    public void loop2() {
        final Workspace workspace = Platform.newTestWorkspace();
        final TMap map = new TMap(workspace.resolve(""));

        for (int i = 0; i < CYCLES; i++) {
            workspace.atomic(new Runnable() {

                @Override
                public void run() {
                    addRemove2(map);
                }
            });
        }

        workspace.close();
    }

    @Test
    public void loop3() {
        final Workspace workspace = Platform.newTestWorkspace();
        final TMap map = new TMap(workspace.resolve(""));

        for (int i = 0; i < CYCLES; i++) {
            map.clear();

            workspace.atomic(new Runnable() {

                @Override
                public void run() {
                    addRemove3(map);
                }
            });
        }

        workspace.close();
    }

    @Test
    public void loop3_bis() {
        final Workspace workspace = Platform.newTestWorkspace();
        final TMap map = new TMap(workspace.resolve(""));

        for (int i = 0; i < CYCLES; i++) {
            workspace.atomic(new Runnable() {

                @Override
                public void run() {
                    for (Iterator it = map.entrySet().iterator(); it.hasNext();) {
                        it.next();
                        it.remove();
                    }
                }
            });

            workspace.atomic(new Runnable() {

                @Override
                public void run() {
                    addRemove3(map);
                }
            });
        }

        workspace.close();
    }

    @Test
    public void threads1() {
        final Workspace workspace = Platform.newTestWorkspace();
        final TMap map = new TMap(workspace.resolve(""));
        int threads = Runtime.getRuntime().availableProcessors();

        new TMapExtended(workspace).run(threads, new Runnable() {

            public void run() {
                TMapSimple.addRemove1(map);
            }
        }, CYCLES / threads);

        workspace.close();
    }

    @Test
    public void threads2() {
        final Workspace workspace = Platform.newTestWorkspace();
        final TMap map = new TMap(workspace.resolve(""));
        int threads = Runtime.getRuntime().availableProcessors();

        new TMapExtended(workspace).run(threads, new Runnable() {

            public void run() {
                TMapSimple.addRemove2(map);
            }
        }, CYCLES / threads);

        workspace.close();
    }

    @Test
    public void threads3() {
        final Workspace workspace = Platform.newTestWorkspace();
        final TMap map = new TMap(workspace.resolve(""));
        int threads = Runtime.getRuntime().availableProcessors();

        new TMapExtended(workspace).run(threads, new Runnable() {

            public void run() {
                map.clear();
                TMapSimple.addRemove3(map);
            }
        }, CYCLES / threads);

        workspace.close();
    }

    @Test
    public void threads3_bis() {
        final Workspace workspace = Platform.newTestWorkspace();
        final TMap map = new TMap(workspace.resolve(""));

        int threads = Runtime.getRuntime().availableProcessors();

        new TMapExtended(workspace).run(threads, new Runnable() {

            public void run() {
                for (Iterator it = map.entrySet().iterator(); it.hasNext();) {
                    it.next();
                    it.remove();
                }

                TMapSimple.addRemove3(map);
            }
        }, CYCLES / threads);

        workspace.close();
    }

    private static void addRemove1(TMap map) {
        final int MAP_SIZE = 80;

        for (int i = 0; i < MAP_SIZE; i++)
            map.put(i, i);

        Assert.assertEquals(MAP_SIZE, map.size());

        for (int i = 0; i < MAP_SIZE; i++)
            Assert.assertTrue(i == map.get(i));

        for (int i = MAP_SIZE - 1; i >= 0; i--) {
            map.remove(i);
            Assert.assertEquals(i, map.size());
        }
    }

    private static void addRemove2(final TMap map) {
        final int MAP_SIZE = 40;

        for (int i = 0; i < MAP_SIZE; i++) {
            final int i_ = i;

            map.atomic(new Runnable() {

                @Override
                public void run() {
                    Assert.assertEquals(i_, map.size());
                    map.put(i_, i_);
                    Assert.assertEquals(i_ + 1, map.size());
                }
            });

            Assert.assertEquals(i + 1, map.size());
        }

        for (int i = MAP_SIZE - 1; i >= 0; i--) {
            final int i_ = i;

            map.atomic(new Runnable() {

                @Override
                public void run() {
                    map.remove(i_);
                    Assert.assertEquals(i_, map.size());
                }
            });

            Assert.assertEquals(i, map.size());
        }
    }

    private static void addRemove3(final TMap map) {
        final HashMap ref = new HashMap();
        final AtomicInteger id = new AtomicInteger();

        check(map, ref);

        for (int i = 0; i < 10; i++) {
            record("Transaction.start();");
            map.workspace().atomic(new Runnable() {

                @Override
                public void run() {

                    for (int t = 0; t < 100; t++) {
                        int size = map.size();
                        boolean insert = size == 0 || Platform.get().randomInt(10) < 8;
                        int index;

                        if (insert) {
                            index = Platform.get().randomInt(size + 1);
                            record("map.add(" + index + ", " + id + ");");
                            record("ref.add(" + index + ", " + id + ");");
                            map.put(index, id.get());
                            ref.put(index, id.getAndIncrement());
                        } else {
                            index = Platform.get().randomInt(size);
                            record("map.remove(" + index + ");");
                            record("ref.remove(" + index + ");");
                            map.remove(index);
                            ref.remove(index);
                        }

                        check(map, ref);
                    }

                    record("Transaction.getCurrent().commit();");
                }
            });

            check(map, ref);
        }
    }

    /**
     * @param message
     */
    private static void record(String message) {
        // System.out.println(message);
    }

    private static  void check(TMap map, HashMap ref) {
        Assert.assertEquals(ref.size(), map.size());

        for (Map.Entry entry : map.entrySet())
            Assert.assertTrue(ref.get(entry.getKey()).equals(entry.getValue()));

        for (Map.Entry entry : ref.entrySet())
            Assert.assertTrue(map.get(entry.getKey()).equals(entry.getValue()));
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy