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

org.javimmutable.collections.util.RandomLoop Maven / Gradle / Ivy

///###////////////////////////////////////////////////////////////////////////
//
// Burton Computer Corporation
// http://www.burton-computer.com
//
// Copyright (c) 2014, Burton Computer Corporation
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
//     Redistributions of source code must retain the above copyright
//     notice, this list of conditions and the following disclaimer.
//
//     Redistributions in binary form must reproduce the above copyright
//     notice, this list of conditions and the following disclaimer in
//     the documentation and/or other materials provided with the
//     distribution.
//
//     Neither the name of the Burton Computer Corporation nor the names
//     of its contributors may be used to endorse or promote products
//     derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

package org.javimmutable.collections.util;

import org.javimmutable.collections.JImmutableArray;
import org.javimmutable.collections.JImmutableList;
import org.javimmutable.collections.JImmutableMap;
import org.javimmutable.collections.JImmutableRandomAccessList;
import org.javimmutable.collections.JImmutableSet;
import org.javimmutable.collections.JImmutableStack;
import org.javimmutable.collections.Sequence;
import org.javimmutable.collections.list.JImmutableArrayList;

import javax.annotation.Nonnull;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;
import java.util.StringTokenizer;

/**
 * Test program to run an infinite loop feeding data to a PersistentMap, querying the
 * data, and deleting the data to verify the map always contains what it should.
 */
public class RandomLoop
{
    private static class MapFactory
    {
        private int count;

        private JImmutableMap createMap()
        {
            count += 1;
            if (count % 2 == 0) {
                return JImmutables.map();
            } else {
                return JImmutables.sortedMap();
            }
        }
    }

    public void execute(String[] filenames)
            throws Exception
    {
        MapFactory factory = new MapFactory();
        long seed = System.currentTimeMillis();
        System.out.printf("Starting with initial seed %d%n", seed);
        Random random = new Random(seed);
        JImmutableList tokens = loadTokens(filenames);
        System.out.printf("Loaded %d tokens from %d files%n", tokens.size(), filenames.length);
        //noinspection InfiniteLoopStatement
        while (true) {
            testStack(random);
            testList(random);
            testRandomAccessList(random);
            testSets(tokens, random);
            testMaps(factory, tokens, random);
            testBadHashMap(tokens, random);
            testComparableBadHashMap(tokens, random);
            testArray(tokens, random);
        }
    }

    public static void main(String[] argv)
            throws Exception
    {
        new RandomLoop().execute(argv);
    }

    private void testStack(Random random)
    {
        JImmutableStack stack = JImmutables.stack();
        LinkedList expected = new LinkedList();
        int size = random.nextInt(1000);
        System.out.printf("Testing PersistentStack of size %d%n", size);
        for (int i = 0; i < size; ++i) {
            int value = random.nextInt(999999999);
            stack = stack.insert(value);
            expected.add(0, value);
        }
        Sequence seq = stack;
        for (Integer value : expected) {
            if (!value.equals(seq.getHead())) {
                throw new RuntimeException(String.format("found mismatch expected %d found %d", value, seq.getHead()));
            }
            seq = seq.getTail();
        }
        if (!seq.isEmpty()) {
            throw new RuntimeException("expected to be at end of stack but found more values");
        }
        System.out.println("PersistentStack test completed without errors");
    }

    private void testList(Random random)
    {
        JImmutableArrayList list = JImmutableArrayList.of();
        ArrayList expected = new ArrayList();
        int size = random.nextInt(100000);
        System.out.printf("Testing PersistentList of size %d%n", size);

        for (int loops = 1; loops <= 6; ++loops) {
            System.out.printf("growing %d%n", list.size());
            for (int i = 0; i < size / 3; ++i) {
                int value = random.nextInt(999999999);
                switch (random.nextInt(3)) {
                case 0:
                    list = list.insert(value);
                    expected.add(value);
                    break;
                case 1:
                    list = list.insertLast(value);
                    expected.add(value);
                    break;
                case 2:
                    list = list.insertFirst(value);
                    expected.add(0, value);
                    break;
                default:
                    throw new RuntimeException();
                }
            }
            list.checkInvariants();
            verifyContents(expected, list);
            System.out.printf("shrinking %d%n", list.size());
            for (int i = 0; i < size / 6; ++i) {
                if (random.nextInt(2) == 0) {
                    list = list.deleteLast();
                    expected.remove(expected.size() - 1);
                } else {
                    list = list.deleteFirst();
                    expected.remove(0);
                }
            }
            verifyContents(expected, list);
            list.checkInvariants();
        }
        System.out.printf("cleanup %d%n", expected.size());
        while (list.size() > 0) {
            list = list.deleteLast();
            expected.remove(expected.size() - 1);
        }
        verifyContents(expected, list);
        System.out.println("PersistentList test completed without errors");
    }

    private void testRandomAccessList(Random random)
    {
        JImmutableRandomAccessList list = JImmutables.ralist();
        ArrayList expected = new ArrayList();
        int size = random.nextInt(10000);
        System.out.printf("Testing PersistentRandomAccessList of size %d%n", size);

        for (int loops = 1; loops <= 6; ++loops) {
            System.out.printf("growing %d%n", list.size());
            for (int i = 0; i < size / 3; ++i) {
                int value = random.nextInt(999999999);
                if (list.isEmpty()) {
                    list = list.insert(value);
                    expected.add(value);
                } else {
                    switch (random.nextInt(8)) {
                    case 0:
                        list = list.insert(value);
                        expected.add(value);
                        break;
                    case 1:
                        list = list.insertLast(value);
                        expected.add(value);
                        break;
                    case 2:
                        list = list.insertFirst(value);
                        expected.add(0, value);
                        break;
                    default:
                        int index = random.nextInt(list.size());
                        list = list.insert(index, value);
                        expected.add(index, value);
                        break;
                    }
                }
            }
            verifyContents(expected, list);
            System.out.printf("shrinking %d%n", list.size());
            for (int i = 0; i < size / 6; ++i) {
                if (list.size() == 1) {
                    list = list.deleteLast();
                    expected.remove(expected.size() - 1);
                } else {
                    switch (random.nextInt(8)) {
                    case 0:
                        list = list.deleteLast();
                        expected.remove(expected.size() - 1);
                        break;
                    case 1:
                        list = list.deleteFirst();
                        expected.remove(0);
                        break;
                    default:
                        int index = random.nextInt(list.size());
                        list = list.delete(index);
                        expected.remove(index);
                    }
                }
            }
            verifyContents(expected, list);
        }
        System.out.printf("cleanup %d%n", expected.size());
        while (list.size() > 0) {
            list = list.delete(0);
            expected.remove(0);
        }
        verifyContents(expected, list);
        System.out.println("PersistentRandomAccessList test completed without errors");
    }

    private void testSets(JImmutableList tokens,
                          Random random)
    {
        JImmutableSet hset = JImmutables.set();
        JImmutableSet tset = JImmutables.sortedSet();
        Set expected = new HashSet();
        int size = random.nextInt(100000);
        JImmutableRandomAccessList values = JImmutables.ralist();

        System.out.printf("Testing PersistentSet of size %d%n", size);

        for (int loops = 1; loops <= 6; ++loops) {
            System.out.printf("growing %d%n", hset.size());
            for (int i = 0; i < size / 3; ++i) {
                String value = makeKey(tokens, random);
                values = values.insert(value);
                hset = hset.insert(value);
                tset = tset.insert(value);
                expected.add(value);
            }
            verifyContents(expected, hset);
            verifyContents(expected, tset);
            System.out.printf("shrinking %d%n", hset.size());
            for (int i = 0; i < size / 6; ++i) {
                int keyIndex = random.nextInt(values.size());
                String key = values.get(keyIndex);
                expected.remove(key);
                hset = hset.delete(key);
                tset = tset.delete(key);
                values = values.delete(keyIndex);
            }
            verifyContents(expected, hset);
            verifyContents(expected, tset);
        }
        System.out.printf("cleanup %d%n", expected.size());
        while (values.size() > 0) {
            String value = values.get(0);
            hset = hset.delete(value);
            tset = tset.delete(value);
            expected.remove(value);
            values = values.delete(0);
        }
        verifyContents(expected, hset);
        verifyContents(expected, tset);
        System.out.println("PersistentSet test completed without errors");
    }

    private void testMaps(MapFactory factory,
                          JImmutableList tokens,
                          Random random)
    {
        final int tokenCount = 1 + random.nextInt(100000);
        final List keys = new ArrayList();
        final Map expected = new HashMap();
        JImmutableMap map = factory.createMap();
        JImmutableRandomAccessList pkeys = JImmutables.ralist();
        System.out.printf("starting %s test with %d tokens and factory %s%n", map.getClass().getSimpleName(), tokenCount, map.getClass().getSimpleName());
        for (int loops = 1; loops <= 6; ++loops) {
            System.out.printf("growing %d%n", map.size());
            for (int i = 0; i < tokenCount / 3; ++i) {
                String key = makeKey(tokens, random);
                keys.add(key);
                pkeys = pkeys.insert(key);
                expected.put(key, key);
                map = map.assign(key, key);
            }
            verifyContents(expected, map);
            System.out.printf("updating %d%n", map.size());
            for (int i = 0; i < map.size(); ++i) {
                int keyIndex = random.nextInt(keys.size());
                String key = pkeys.get(keyIndex);
                int valueIndex = random.nextInt(keys.size());
                String value = pkeys.get(valueIndex);
                expected.put(key, value);
                map = map.assign(key, value);
            }
            verifyContents(expected, map);
            System.out.printf("shrinking %d%n", map.size());
            for (int i = 0; i < tokenCount / 6; ++i) {
                int keyIndex = random.nextInt(keys.size());
                String key = pkeys.get(keyIndex);
                expected.remove(key);
                map = map.delete(key);
                keys.remove(keyIndex);
                pkeys = pkeys.delete(keyIndex);
            }
            verifyContents(expected, map);
        }
        if (keys.size() != pkeys.size()) {
            throw new RuntimeException(String.format("key size mismatch - expected %d found %d%n", keys.size(), pkeys.size()));
        }
        System.out.printf("comparing %d keys%n", pkeys.size());
        for (int i = 0; i < pkeys.size(); ++i) {
            String key = keys.get(i);
            String pkey = pkeys.get(i);
            if (!key.equals(pkey)) {
                throw new RuntimeException(String.format("key mismatch - expected %s found %s%n", key, pkey));
            }
        }
        System.out.printf("cleanup %d%n", map.size());
        for (String key : keys) {
            expected.remove(key);
            map = map.delete(key);
        }
        if (map.size() != 0) {
            throw new RuntimeException(String.format("expected map to be empty but it contained %d keys%n", map.size()));
        }
        verifyContents(expected, map);
        System.out.printf("completed %s test without errors%n", map.getClass().getSimpleName());
    }

    private void testArray(JImmutableList tokens,
                           Random random)
    {
        final int tokenCount = 1 + random.nextInt(100000);
        final List keys = new ArrayList();
        final Map expected = new HashMap();
        JImmutableArray map = JImmutables.array();
        JImmutableRandomAccessList pkeys = JImmutables.ralist();
        JImmutableRandomAccessList pvalues = JImmutables.ralist();
        System.out.printf("starting %s test with %d tokens and factory %s%n", map.getClass().getSimpleName(), tokenCount, map.getClass().getSimpleName());
        for (int loops = 1; loops <= 6; ++loops) {
            System.out.printf("growing %d%n", map.size());
            for (int i = 0; i < tokenCount / 3; ++i) {
                int key = random.nextInt();
                String value = makeKey(tokens, random);
                keys.add(key);
                pkeys = pkeys.insert(key);
                pvalues = pvalues.insert(value);
                expected.put(key, value);
                map = map.assign(key, value);
            }
            verifyContents(expected, map);
            System.out.printf("updating %d%n", map.size());
            for (int i = 0; i < map.size(); ++i) {
                int keyIndex = random.nextInt(keys.size());
                int key = pkeys.get(keyIndex);
                int valueIndex = random.nextInt(keys.size());
                String value = pvalues.get(valueIndex);
                expected.put(key, value);
                pvalues = pvalues.assign(keyIndex, value);
                map = map.assign(key, value);
            }
            verifyContents(expected, map);
            System.out.printf("shrinking %d%n", map.size());
            for (int i = 0; i < tokenCount / 6; ++i) {
                int keyIndex = random.nextInt(keys.size());
                int key = pkeys.get(keyIndex);
                expected.remove(key);
                map = map.delete(key);
                keys.remove(keyIndex);
                pkeys = pkeys.delete(keyIndex);
                pvalues = pvalues.delete(keyIndex);
            }
            verifyContents(expected, map);
        }
        if (keys.size() != pkeys.size()) {
            throw new RuntimeException(String.format("key size mismatch - expected %d found %d%n", keys.size(), pkeys.size()));
        }
        System.out.printf("comparing %d keys%n", pkeys.size());
        for (int i = 0; i < pkeys.size(); ++i) {
            int key = keys.get(i);
            int pkey = pkeys.get(i);
            if (key != pkey) {
                throw new RuntimeException(String.format("key mismatch - expected %s found %s%n", key, pkey));
            }
        }
        System.out.printf("cleanup %d%n", map.size());
        for (Integer key : keys) {
            expected.remove(key);
            map = map.delete(key);
        }
        if (map.size() != 0) {
            throw new RuntimeException(String.format("expected map to be empty but it contained %d keys%n", map.size()));
        }
        verifyContents(expected, map);
        System.out.printf("completed %s test without errors%n", map.getClass().getSimpleName());
    }

    private void testBadHashMap(JImmutableList tokens,
                                Random random)
    {
        final int tokenCount = 1 + random.nextInt(100000);
        final List> keys = new ArrayList>();
        final Map, String> expected = new HashMap, String>();
        JImmutableMap, String> map = JImmutables.map();
        JImmutableRandomAccessList> pkeys = JImmutables.ralist();
        System.out.printf("starting %s BadHash test with %d tokens and factory %s%n", map.getClass().getSimpleName(), tokenCount, map.getClass().getSimpleName());
        for (int loops = 1; loops <= 6; ++loops) {
            System.out.printf("growing %d%n", map.size());
            for (int i = 0; i < tokenCount / 3; ++i) {
                BadHash key = new BadHash(makeKey(tokens, random));
                keys.add(key);
                pkeys = pkeys.insert(key);
                expected.put(key, key.value);
                map = map.assign(key, key.value);
            }
            verifyContents(expected, map);
            System.out.printf("updating %d%n", map.size());
            for (int i = 0; i < map.size(); ++i) {
                int keyIndex = random.nextInt(keys.size());
                BadHash key = pkeys.get(keyIndex);
                int valueIndex = random.nextInt(keys.size());
                String value = pkeys.get(valueIndex).value;
                expected.put(key, value);
                map = map.assign(key, value);
            }
            verifyContents(expected, map);
            System.out.printf("shrinking %d%n", map.size());
            for (int i = 0; i < tokenCount / 6; ++i) {
                int keyIndex = random.nextInt(keys.size());
                BadHash key = pkeys.get(keyIndex);
                expected.remove(key);
                map = map.delete(key);
                keys.remove(keyIndex);
                pkeys = pkeys.delete(keyIndex);
            }
            verifyContents(expected, map);
        }
        if (keys.size() != pkeys.size()) {
            throw new RuntimeException(String.format("key size mismatch - expected %d found %d%n", keys.size(), pkeys.size()));
        }
        System.out.printf("comparing %d keys%n", pkeys.size());
        for (int i = 0; i < pkeys.size(); ++i) {
            BadHash key = keys.get(i);
            BadHash pkey = pkeys.get(i);
            if (!key.equals(pkey)) {
                throw new RuntimeException(String.format("key mismatch - expected %s found %s%n", key, pkey));
            }
        }
        System.out.printf("cleanup %d%n", map.size());
        for (BadHash key : keys) {
            expected.remove(key);
            map = map.delete(key);
        }
        if (map.size() != 0) {
            throw new RuntimeException(String.format("expected map to be empty but it contained %d keys%n", map.size()));
        }
        verifyContents(expected, map);
        System.out.printf("completed %s test without errors%n", map.getClass().getSimpleName());
    }

    private void testComparableBadHashMap(JImmutableList tokens,
                                          Random random)
    {
        final int tokenCount = 1 + random.nextInt(100000);
        final List> keys = new ArrayList>();
        final Map, String> expected = new HashMap, String>();
        JImmutableMap, String> map = JImmutables.map();
        JImmutableRandomAccessList> pkeys = JImmutables.ralist();
        System.out.printf("starting %s ComparableBadHash test with %d tokens and factory %s%n", map.getClass().getSimpleName(), tokenCount, map.getClass().getSimpleName());
        for (int loops = 1; loops <= 6; ++loops) {
            System.out.printf("growing %d%n", map.size());
            for (int i = 0; i < tokenCount / 3; ++i) {
                ComparableBadHash key = new ComparableBadHash(makeKey(tokens, random));
                keys.add(key);
                pkeys = pkeys.insert(key);
                expected.put(key, key.value);
                map = map.assign(key, key.value);
            }
            verifyContents(expected, map);
            System.out.printf("updating %d%n", map.size());
            for (int i = 0; i < map.size(); ++i) {
                int keyIndex = random.nextInt(keys.size());
                ComparableBadHash key = pkeys.get(keyIndex);
                int valueIndex = random.nextInt(keys.size());
                String value = pkeys.get(valueIndex).value;
                expected.put(key, value);
                map = map.assign(key, value);
            }
            verifyContents(expected, map);
            System.out.printf("shrinking %d%n", map.size());
            for (int i = 0; i < tokenCount / 6; ++i) {
                int keyIndex = random.nextInt(keys.size());
                ComparableBadHash key = pkeys.get(keyIndex);
                expected.remove(key);
                map = map.delete(key);
                keys.remove(keyIndex);
                pkeys = pkeys.delete(keyIndex);
            }
            verifyContents(expected, map);
        }
        if (keys.size() != pkeys.size()) {
            throw new RuntimeException(String.format("key size mismatch - expected %d found %d%n", keys.size(), pkeys.size()));
        }
        System.out.printf("comparing %d keys%n", pkeys.size());
        for (int i = 0; i < pkeys.size(); ++i) {
            ComparableBadHash key = keys.get(i);
            ComparableBadHash pkey = pkeys.get(i);
            if (!key.equals(pkey)) {
                throw new RuntimeException(String.format("key mismatch - expected %s found %s%n", key, pkey));
            }
        }
        System.out.printf("cleanup %d%n", map.size());
        for (ComparableBadHash key : keys) {
            expected.remove(key);
            map = map.delete(key);
        }
        if (map.size() != 0) {
            throw new RuntimeException(String.format("expected map to be empty but it contained %d keys%n", map.size()));
        }
        verifyContents(expected, map);
        System.out.printf("completed %s test without errors%n", map.getClass().getSimpleName());
    }

    private void verifyContents(List expected,
                                JImmutableList list)
    {
        System.out.printf("checking contents with size %d%n", list.size());
        if (list.size() != expected.size()) {
            throw new RuntimeException(String.format("size mismatch - expected %d found %d", expected.size(), list.size()));
        }
        int index = 0;
        for (Integer expectedValue : expected) {
            Integer listValue = list.get(index);
            if (!expectedValue.equals(listValue)) {
                throw new RuntimeException(String.format("value mismatch - expected %d found %d%n", expectedValue, listValue));
            }
            index += 1;
        }
        index = 0;
        for (Integer listValue : list) {
            Integer expectedValue = expected.get(index);
            if (!expectedValue.equals(listValue)) {
                throw new RuntimeException(String.format("value mismatch - expected %d found %d%n", expectedValue, listValue));
            }
            index += 1;
        }
    }

    private void verifyContents(Set expected,
                                JImmutableSet set)
    {
        System.out.printf("checking contents with size %d%n", set.size());
        if (set.size() != expected.size()) {
            throw new RuntimeException(String.format("size mismatch - expected %d found %d", expected.size(), set.size()));
        }
        for (String expectedValue : expected) {
            if (!set.contains(expectedValue)) {
                throw new RuntimeException(String.format("value mismatch - expected %s but not in %s%n", expectedValue, set.getClass().getSimpleName()));
            }
        }
        for (String expectedValue : set) {
            if (!expected.contains(expectedValue)) {
                throw new RuntimeException(String.format("value mismatch - expected %s but not in Set%n", expectedValue));
            }
        }
    }

    private  void verifyContents(Map expected,
                                       JImmutableMap map)
    {
        System.out.printf("checking contents with size %d%n", map.size());
        if (map.size() != expected.size()) {
            throw new RuntimeException(String.format("size mismatch - expected %d found %d", expected.size(), map.size()));
        }
        for (JImmutableMap.Entry entry : map) {
            V mapValue = map.find(entry.getKey()).getValueOrNull();
            V expectedValue = expected.get(entry.getKey());
            if (!mapValue.equals(expectedValue)) {
                throw new RuntimeException(String.format("value mismatch - expected %s found %s%n", expectedValue, mapValue));
            }
        }
        for (Map.Entry entry : expected.entrySet()) {
            V mapValue = map.find(entry.getKey()).getValueOrNull();
            V expectedValue = expected.get(entry.getKey());
            if (!mapValue.equals(expectedValue)) {
                throw new RuntimeException(String.format("value mismatch - expected %s found %s%n", expectedValue, mapValue));
            }
        }
    }

    private  void verifyContents(Map expected,
                                    JImmutableArray map)
    {
        System.out.printf("checking contents with size %d%n", map.size());
        if (map.size() != expected.size()) {
            throw new RuntimeException(String.format("size mismatch - expected %d found %d", expected.size(), map.size()));
        }
        for (JImmutableMap.Entry entry : map) {
            V mapValue = map.find(entry.getKey()).getValueOrNull();
            V expectedValue = expected.get(entry.getKey());
            if (!mapValue.equals(expectedValue)) {
                throw new RuntimeException(String.format("value mismatch - expected %s found %s%n", expectedValue, mapValue));
            }
        }
        for (Map.Entry entry : expected.entrySet()) {
            V mapValue = map.find(entry.getKey()).getValueOrNull();
            V expectedValue = expected.get(entry.getKey());
            if (!mapValue.equals(expectedValue)) {
                throw new RuntimeException(String.format("value mismatch - expected %s found %s%n", expectedValue, mapValue));
            }
        }
    }

    private String makeKey(JImmutableList tokens,
                           Random random)
    {
        int length = 1 + random.nextInt(250);
        StringBuilder sb = new StringBuilder();
        while (sb.length() < length) {
            sb.append(tokens.get(random.nextInt(tokens.size())));
        }
        return sb.toString();
    }

    private JImmutableList loadTokens(String[] filenames)
            throws IOException
    {
        JImmutableSet tokens = JImmutables.set();
        for (String filename : filenames) {
            tokens = addTokensFromFile(tokens, filename);
        }
        return JImmutables.list(tokens);
    }

    private JImmutableSet addTokensFromFile(JImmutableSet tokens,
                                                    String filename)
            throws IOException
    {
        BufferedReader inp = new BufferedReader(new InputStreamReader(new FileInputStream(filename), "UTF-8"));
        try {
            for (String line = inp.readLine(); line != null; line = inp.readLine()) {
                StringTokenizer tokenizer = new StringTokenizer(line);
                while (tokenizer.hasMoreTokens()) {
                    tokens = tokens.insert(tokenizer.nextToken());
                }
            }
        } finally {
            inp.close();
        }
        return tokens;
    }

    @SuppressWarnings("unchecked")
    private static class BadHash
    {
        private final T value;

        private BadHash(T value)
        {
            this.value = value;
        }

        @Override
        public int hashCode()
        {
            return value.hashCode() >>> 8;
        }

        @Override
        public boolean equals(Object o)
        {
            return (o instanceof BadHash) && value.equals(((BadHash)o).value);
        }
    }

    @SuppressWarnings("unchecked")
    private static class ComparableBadHash>
            implements Comparable>
    {
        private final T value;

        private ComparableBadHash(T value)
        {
            this.value = value;
        }

        @Override
        public int hashCode()
        {
            return value.hashCode() >>> 8;
        }

        @Override
        public boolean equals(Object o)
        {
            return (o instanceof ComparableBadHash) && value.equals(((ComparableBadHash)o).value);
        }

        @Override
        public int compareTo(@Nonnull ComparableBadHash other)
        {
            return value.compareTo(other.value);
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy