ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/CountedCompleterTest.java
(Generate patch)

Comparing jsr166/src/test/tck/CountedCompleterTest.java (file contents):
Revision 1.29 by jsr166, Mon Sep 12 17:49:12 2016 UTC vs.
Revision 1.30 by jsr166, Sat Oct 15 18:51:12 2016 UTC

# Line 17 | Line 17 | import java.util.concurrent.ThreadLocalR
17   import java.util.concurrent.TimeoutException;
18   import java.util.concurrent.atomic.AtomicInteger;
19   import java.util.concurrent.atomic.AtomicReference;
20 import java.util.function.BiConsumer;
21 import java.util.function.Consumer;
20  
21   import junit.framework.Test;
22   import junit.framework.TestSuite;
# Line 1845 | Line 1843 | public class CountedCompleterTest extend
1843          testInvokeOnPool(singletonPool(), a);
1844      }
1845  
1848    /** CountedCompleter class javadoc code sample, version 1. */
1849    public static <E> void forEach1(E[] array, Consumer<E> action) {
1850        class Task extends CountedCompleter<Void> {
1851            final int lo, hi;
1852            Task(Task parent, int lo, int hi) {
1853                super(parent); this.lo = lo; this.hi = hi;
1854            }
1855
1856            public void compute() {
1857                if (hi - lo >= 2) {
1858                    int mid = (lo + hi) >>> 1;
1859                    // must set pending count before fork
1860                    setPendingCount(2);
1861                    new Task(this, mid, hi).fork(); // right child
1862                    new Task(this, lo, mid).fork(); // left child
1863                }
1864                else if (hi > lo)
1865                    action.accept(array[lo]);
1866                tryComplete();
1867            }
1868        }
1869        new Task(null, 0, array.length).invoke();
1870    }
1871
1872    /** CountedCompleter class javadoc code sample, version 2. */
1873    public static <E> void forEach2(E[] array, Consumer<E> action) {
1874        class Task extends CountedCompleter<Void> {
1875            final int lo, hi;
1876            Task(Task parent, int lo, int hi) {
1877                super(parent); this.lo = lo; this.hi = hi;
1878            }
1879
1880            public void compute() {
1881                if (hi - lo >= 2) {
1882                    int mid = (lo + hi) >>> 1;
1883                    setPendingCount(1); // looks off by one, but correct!
1884                    new Task(this, mid, hi).fork(); // right child
1885                    new Task(this, lo, mid).compute(); // direct invoke
1886                } else {
1887                    if (hi > lo)
1888                        action.accept(array[lo]);
1889                    tryComplete();
1890                }
1891            }
1892        }
1893        new Task(null, 0, array.length).invoke();
1894    }
1895
1896    /** CountedCompleter class javadoc code sample, version 3. */
1897    public static <E> void forEach3(E[] array, Consumer<E> action) {
1898        class Task extends CountedCompleter<Void> {
1899            final int lo, hi;
1900            Task(Task parent, int lo, int hi) {
1901                super(parent); this.lo = lo; this.hi = hi;
1902            }
1903
1904            public void compute() {
1905                int n = hi - lo;
1906                for (; n >= 2; n /= 2) {
1907                    addToPendingCount(1);
1908                    new Task(this, lo + n/2, lo + n).fork();
1909                }
1910                if (n > 0)
1911                    action.accept(array[lo]);
1912                propagateCompletion();
1913            }
1914        }
1915        new Task(null, 0, array.length).invoke();
1916    }
1917
1918    /** CountedCompleter class javadoc code sample, version 4. */
1919    public static <E> void forEach4(E[] array, Consumer<E> action) {
1920        class Task extends CountedCompleter<Void> {
1921            final int lo, hi;
1922            Task(Task parent, int lo, int hi) {
1923                super(parent, 31 - Integer.numberOfLeadingZeros(hi - lo));
1924                this.lo = lo; this.hi = hi;
1925            }
1926
1927            public void compute() {
1928                for (int n = hi - lo; n >= 2; n /= 2)
1929                    new Task(this, lo + n/2, lo + n).fork();
1930                action.accept(array[lo]);
1931                propagateCompletion();
1932            }
1933        }
1934        if (array.length > 0)
1935            new Task(null, 0, array.length).invoke();
1936    }
1937
1938    void testRecursiveDecomposition(
1939        BiConsumer<Integer[], Consumer<Integer>> action) {
1940        int n = ThreadLocalRandom.current().nextInt(8);
1941        Integer[] a = new Integer[n];
1942        for (int i = 0; i < n; i++) a[i] = i + 1;
1943        AtomicInteger ai = new AtomicInteger(0);
1944        action.accept(a, (x) -> ai.addAndGet(x));
1945        assertEquals(n * (n + 1) / 2, ai.get());
1946    }
1947
1948    /**
1949     * Variants of divide-by-two recursive decomposition into leaf tasks,
1950     * as described in the CountedCompleter class javadoc code samples
1951     */
1952    public void testRecursiveDecomposition() {
1953        testRecursiveDecomposition(CountedCompleterTest::forEach1);
1954        testRecursiveDecomposition(CountedCompleterTest::forEach2);
1955        testRecursiveDecomposition(CountedCompleterTest::forEach3);
1956        testRecursiveDecomposition(CountedCompleterTest::forEach4);
1957    }
1958
1846   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines