Search in sources :

Example 11 with AtomicReferenceArray

use of java.util.concurrent.atomic.AtomicReferenceArray in project neo4j by neo4j.

the class KernelTransactionsTest method shouldBeAbleToSnapshotDuringHeavyLoad.

@Test
public void shouldBeAbleToSnapshotDuringHeavyLoad() throws Throwable {
    // GIVEN
    final KernelTransactions transactions = newKernelTransactions();
    Race race = new Race();
    final int threads = 50;
    final AtomicBoolean end = new AtomicBoolean();
    final AtomicReferenceArray<KernelTransactionsSnapshot> snapshots = new AtomicReferenceArray<>(threads);
    // Representing "transaction" threads
    for (int i = 0; i < threads; i++) {
        final int threadIndex = i;
        race.addContestant(() -> {
            ThreadLocalRandom random = ThreadLocalRandom.current();
            while (!end.get()) {
                try (KernelTransaction transaction = getKernelTransaction(transactions)) {
                    parkNanos(MILLISECONDS.toNanos(random.nextInt(3)));
                    if (snapshots.get(threadIndex) == null) {
                        snapshots.set(threadIndex, transactions.get());
                        parkNanos(MILLISECONDS.toNanos(random.nextInt(3)));
                    }
                } catch (TransactionFailureException e) {
                    throw new RuntimeException(e);
                }
            }
        });
    }
    // Just checks snapshots
    race.addContestant(() -> {
        ThreadLocalRandom random = ThreadLocalRandom.current();
        int snapshotsLeft = 1_000;
        while (snapshotsLeft > 0) {
            int threadIndex = random.nextInt(threads);
            KernelTransactionsSnapshot snapshot = snapshots.get(threadIndex);
            if (snapshot != null && snapshot.allClosed()) {
                snapshotsLeft--;
                snapshots.set(threadIndex, null);
            }
        }
        // End condition of this test can be described as:
        //   when 1000 snapshots have been seen as closed.
        // setting this boolean to true will have all other threads end as well so that race.go() will end
        end.set(true);
    });
    // WHEN
    race.go();
}
Also used : AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) KernelTransaction(org.neo4j.kernel.api.KernelTransaction) TransactionFailureException(org.neo4j.kernel.api.exceptions.TransactionFailureException) Race(org.neo4j.test.Race) AtomicReferenceArray(java.util.concurrent.atomic.AtomicReferenceArray) ThreadLocalRandom(java.util.concurrent.ThreadLocalRandom) Test(org.junit.Test)

Example 12 with AtomicReferenceArray

use of java.util.concurrent.atomic.AtomicReferenceArray in project gocd by gocd.

the class ConcurrentHashMapV8 method internalCompute.

/**
 * Implementation for compute
 */
@SuppressWarnings("unchecked")
private final Object internalCompute(K k, boolean onlyIfPresent, BiFun<? super K, ? super V, ? extends V> mf) {
    int h = spread(k.hashCode());
    Object val = null;
    int delta = 0;
    int count = 0;
    for (AtomicReferenceArray<Node> tab = table; ; ) {
        Node f;
        int i, fh;
        Object fk;
        if (tab == null)
            tab = initTable();
        else if ((f = tabAt(tab, i = (tab.length() - 1) & h)) == null) {
            if (onlyIfPresent)
                break;
            Node node = new Node(fh = h | LOCKED, k, null, null);
            if (casTabAt(tab, i, null, node)) {
                try {
                    count = 1;
                    if ((val = mf.apply(k, null)) != null) {
                        node.val = val;
                        delta = 1;
                    }
                } finally {
                    if (delta == 0)
                        setTabAt(tab, i, null);
                    if (!node.casHash(fh, h)) {
                        node.hash = h;
                        synchronized (node) {
                            node.notifyAll();
                        }
                        ;
                    }
                }
            }
            if (count != 0)
                break;
        } else if ((fh = f.hash) == MOVED) {
            if ((fk = f.key) instanceof TreeBin) {
                TreeBin t = (TreeBin) fk;
                t.acquire(0);
                try {
                    if (tabAt(tab, i) == f) {
                        count = 1;
                        TreeNode p = t.getTreeNode(h, k, t.root);
                        Object pv;
                        if (p == null) {
                            if (onlyIfPresent)
                                break;
                            pv = null;
                        } else
                            pv = p.val;
                        if ((val = mf.apply(k, (V) pv)) != null) {
                            if (p != null)
                                p.val = val;
                            else {
                                count = 2;
                                delta = 1;
                                t.putTreeNode(h, k, val);
                            }
                        } else if (p != null) {
                            delta = -1;
                            t.deleteTreeNode(p);
                        }
                    }
                } finally {
                    t.release(0);
                }
                if (count != 0)
                    break;
            } else
                tab = (AtomicReferenceArray<Node>) fk;
        } else if ((fh & LOCKED) != 0) {
            checkForResize();
            f.tryAwaitLock(tab, i);
        } else if (f.casHash(fh, fh | LOCKED)) {
            try {
                if (tabAt(tab, i) == f) {
                    count = 1;
                    for (Node e = f, pred = null; ; ++count) {
                        Object ek, ev;
                        if ((e.hash & HASH_BITS) == h && (ev = e.val) != null && ((ek = e.key) == k || k.equals(ek))) {
                            val = mf.apply(k, (V) ev);
                            if (val != null)
                                e.val = val;
                            else {
                                delta = -1;
                                Node en = e.next;
                                if (pred != null)
                                    pred.next = en;
                                else
                                    setTabAt(tab, i, en);
                            }
                            break;
                        }
                        pred = e;
                        if ((e = e.next) == null) {
                            if (!onlyIfPresent && (val = mf.apply(k, null)) != null) {
                                pred.next = new Node(h, k, val, null);
                                delta = 1;
                                if (count >= TREE_THRESHOLD)
                                    replaceWithTreeBin(tab, i, k);
                            }
                            break;
                        }
                    }
                }
            } finally {
                if (!f.casHash(fh | LOCKED, fh)) {
                    f.hash = fh;
                    synchronized (f) {
                        f.notifyAll();
                    }
                    ;
                }
            }
            if (count != 0) {
                if (tab.length() <= 64)
                    count = 2;
                break;
            }
        }
    }
    if (delta != 0) {
        counter.add((long) delta);
        if (count > 1)
            checkForResize();
    }
    return val;
}
Also used : AtomicReferenceArray(java.util.concurrent.atomic.AtomicReferenceArray) RubyObject(org.jruby.RubyObject) IRubyObject(org.jruby.runtime.builtin.IRubyObject)

Example 13 with AtomicReferenceArray

use of java.util.concurrent.atomic.AtomicReferenceArray in project gocd by gocd.

the class ConcurrentHashMapV8 method internalMerge.

/**
 * Implementation for merge
 */
@SuppressWarnings("unchecked")
private final Object internalMerge(K k, V v, BiFun<? super V, ? super V, ? extends V> mf) {
    int h = spread(k.hashCode());
    Object val = null;
    int delta = 0;
    int count = 0;
    for (AtomicReferenceArray<Node> tab = table; ; ) {
        int i;
        Node f;
        int fh;
        Object fk, fv;
        if (tab == null)
            tab = initTable();
        else if ((f = tabAt(tab, i = (tab.length() - 1) & h)) == null) {
            if (casTabAt(tab, i, null, new Node(h, k, v, null))) {
                delta = 1;
                val = v;
                break;
            }
        } else if ((fh = f.hash) == MOVED) {
            if ((fk = f.key) instanceof TreeBin) {
                TreeBin t = (TreeBin) fk;
                t.acquire(0);
                try {
                    if (tabAt(tab, i) == f) {
                        count = 1;
                        TreeNode p = t.getTreeNode(h, k, t.root);
                        val = (p == null) ? v : mf.apply((V) p.val, v);
                        if (val != null) {
                            if (p != null)
                                p.val = val;
                            else {
                                count = 2;
                                delta = 1;
                                t.putTreeNode(h, k, val);
                            }
                        } else if (p != null) {
                            delta = -1;
                            t.deleteTreeNode(p);
                        }
                    }
                } finally {
                    t.release(0);
                }
                if (count != 0)
                    break;
            } else
                tab = (AtomicReferenceArray<Node>) fk;
        } else if ((fh & LOCKED) != 0) {
            checkForResize();
            f.tryAwaitLock(tab, i);
        } else if (f.casHash(fh, fh | LOCKED)) {
            try {
                if (tabAt(tab, i) == f) {
                    count = 1;
                    for (Node e = f, pred = null; ; ++count) {
                        Object ek, ev;
                        if ((e.hash & HASH_BITS) == h && (ev = e.val) != null && ((ek = e.key) == k || k.equals(ek))) {
                            val = mf.apply((V) ev, v);
                            if (val != null)
                                e.val = val;
                            else {
                                delta = -1;
                                Node en = e.next;
                                if (pred != null)
                                    pred.next = en;
                                else
                                    setTabAt(tab, i, en);
                            }
                            break;
                        }
                        pred = e;
                        if ((e = e.next) == null) {
                            val = v;
                            pred.next = new Node(h, k, val, null);
                            delta = 1;
                            if (count >= TREE_THRESHOLD)
                                replaceWithTreeBin(tab, i, k);
                            break;
                        }
                    }
                }
            } finally {
                if (!f.casHash(fh | LOCKED, fh)) {
                    f.hash = fh;
                    synchronized (f) {
                        f.notifyAll();
                    }
                    ;
                }
            }
            if (count != 0) {
                if (tab.length() <= 64)
                    count = 2;
                break;
            }
        }
    }
    if (delta != 0) {
        counter.add((long) delta);
        if (count > 1)
            checkForResize();
    }
    return val;
}
Also used : AtomicReferenceArray(java.util.concurrent.atomic.AtomicReferenceArray) RubyObject(org.jruby.RubyObject) IRubyObject(org.jruby.runtime.builtin.IRubyObject)

Example 14 with AtomicReferenceArray

use of java.util.concurrent.atomic.AtomicReferenceArray in project gocd by gocd.

the class ConcurrentHashMapV8 method internalPutIfAbsent.

/**
 * Implementation for putIfAbsent
 */
private final Object internalPutIfAbsent(Object k, Object v) {
    int h = spread(k.hashCode());
    int count = 0;
    for (AtomicReferenceArray<Node> tab = table; ; ) {
        int i;
        Node f;
        int fh;
        Object fk, fv;
        if (tab == null)
            tab = initTable();
        else if ((f = tabAt(tab, i = (tab.length() - 1) & h)) == null) {
            if (casTabAt(tab, i, null, new Node(h, k, v, null)))
                break;
        } else if ((fh = f.hash) == MOVED) {
            if ((fk = f.key) instanceof TreeBin) {
                TreeBin t = (TreeBin) fk;
                Object oldVal = null;
                t.acquire(0);
                try {
                    if (tabAt(tab, i) == f) {
                        count = 2;
                        TreeNode p = t.putTreeNode(h, k, v);
                        if (p != null)
                            oldVal = p.val;
                    }
                } finally {
                    t.release(0);
                }
                if (count != 0) {
                    if (oldVal != null)
                        return oldVal;
                    break;
                }
            } else
                tab = (AtomicReferenceArray<Node>) fk;
        } else if ((fh & HASH_BITS) == h && (fv = f.val) != null && ((fk = f.key) == k || k.equals(fk)))
            return fv;
        else {
            Node g = f.next;
            if (g != null) {
                // at least 2 nodes -- search and maybe resize
                for (Node e = g; ; ) {
                    Object ek, ev;
                    if ((e.hash & HASH_BITS) == h && (ev = e.val) != null && ((ek = e.key) == k || k.equals(ek)))
                        return ev;
                    if ((e = e.next) == null) {
                        checkForResize();
                        break;
                    }
                }
            }
            if (((fh = f.hash) & LOCKED) != 0) {
                checkForResize();
                f.tryAwaitLock(tab, i);
            } else if (tabAt(tab, i) == f && f.casHash(fh, fh | LOCKED)) {
                Object oldVal = null;
                try {
                    if (tabAt(tab, i) == f) {
                        count = 1;
                        for (Node e = f; ; ++count) {
                            Object ek, ev;
                            if ((e.hash & HASH_BITS) == h && (ev = e.val) != null && ((ek = e.key) == k || k.equals(ek))) {
                                oldVal = ev;
                                break;
                            }
                            Node last = e;
                            if ((e = e.next) == null) {
                                last.next = new Node(h, k, v, null);
                                if (count >= TREE_THRESHOLD)
                                    replaceWithTreeBin(tab, i, k);
                                break;
                            }
                        }
                    }
                } finally {
                    if (!f.casHash(fh | LOCKED, fh)) {
                        f.hash = fh;
                        synchronized (f) {
                            f.notifyAll();
                        }
                        ;
                    }
                }
                if (count != 0) {
                    if (oldVal != null)
                        return oldVal;
                    if (tab.length() <= 64)
                        count = 2;
                    break;
                }
            }
        }
    }
    counter.add(1L);
    if (count > 1)
        checkForResize();
    return null;
}
Also used : AtomicReferenceArray(java.util.concurrent.atomic.AtomicReferenceArray) RubyObject(org.jruby.RubyObject) IRubyObject(org.jruby.runtime.builtin.IRubyObject)

Example 15 with AtomicReferenceArray

use of java.util.concurrent.atomic.AtomicReferenceArray in project ignite by apache.

the class IgniteCacheCreatePutMultiNodeSelfTest method testStartNodes.

/**
 * @throws Exception If failed.
 */
public void testStartNodes() throws Exception {
    try {
        Collection<IgniteInternalFuture<?>> futs = new ArrayList<>(GRID_CNT);
        int scale = 3;
        final CyclicBarrier barrier = new CyclicBarrier(GRID_CNT * scale);
        final AtomicReferenceArray<Exception> err = new AtomicReferenceArray<>(GRID_CNT * scale);
        for (int i = 0; i < GRID_CNT * scale; i++) {
            if (i < GRID_CNT)
                startGrid(i);
            final int idx = i;
            IgniteInternalFuture<Void> fut = GridTestUtils.runAsync(new Callable<Void>() {

                @Override
                public Void call() throws Exception {
                    Ignite ignite = ignite(idx % GRID_CNT);
                    try {
                        for (int k = 0; k < 50; k++) {
                            barrier.await();
                            String cacheName = "cache-" + k;
                            IgniteCache<Integer, Integer> cache = getCache(ignite, cacheName);
                            for (int i = 0; i < 100; i++) cache.getAndPut(i, i);
                            barrier.await();
                            ignite.destroyCache(cacheName);
                        }
                    } catch (Exception e) {
                        err.set(idx, e);
                    }
                    return null;
                }
            });
            futs.add(fut);
        }
        for (IgniteInternalFuture<?> fut : futs) fut.get(getTestTimeout());
        info("Errors: " + err);
        for (int i = 0; i < err.length(); i++) {
            Exception ex = err.get(i);
            if (ex != null)
                throw ex;
        }
    } finally {
        stopAllGrids();
    }
}
Also used : ArrayList(java.util.ArrayList) IgniteCache(org.apache.ignite.IgniteCache) IgniteInternalFuture(org.apache.ignite.internal.IgniteInternalFuture) CyclicBarrier(java.util.concurrent.CyclicBarrier) AtomicReferenceArray(java.util.concurrent.atomic.AtomicReferenceArray) Ignite(org.apache.ignite.Ignite)

Aggregations

AtomicReferenceArray (java.util.concurrent.atomic.AtomicReferenceArray)32 CountDownLatch (java.util.concurrent.CountDownLatch)13 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)10 AtomicBoolean (java.util.concurrent.atomic.AtomicBoolean)7 RubyObject (org.jruby.RubyObject)6 IRubyObject (org.jruby.runtime.builtin.IRubyObject)6 Config (com.hazelcast.config.Config)4 HazelcastInstance (com.hazelcast.core.HazelcastInstance)4 Random (java.util.Random)4 Test (org.junit.Test)4 Thread.currentThread (java.lang.Thread.currentThread)3 ExecutorService (java.util.concurrent.ExecutorService)3 Ignite (org.apache.ignite.Ignite)3 IgniteCache (org.apache.ignite.IgniteCache)3 JoinConfig (com.hazelcast.config.JoinConfig)2 MulticastConfig (com.hazelcast.config.MulticastConfig)2 NetworkConfig (com.hazelcast.config.NetworkConfig)2 TcpIpConfig (com.hazelcast.config.TcpIpConfig)2 IMap (com.hazelcast.core.IMap)2 TestHazelcastInstanceFactory (com.hazelcast.test.TestHazelcastInstanceFactory)2