From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: wangxyper Date: Sun, 15 Jan 2023 09:56:52 +0800 Subject: [PATCH] Hearse: Add mcmt collections Original license: MIT Original project: https://github.com/Era4FunMC/Hearse diff --git a/src/main/java/net/himeki/mcmtfabric/parallelised/ConcurrentArrayDeque.java b/src/main/java/net/himeki/mcmtfabric/parallelised/ConcurrentArrayDeque.java new file mode 100644 index 0000000000000000000000000000000000000000..3c29129dc02ddcfaad026d1f81e5da879a0d64cb --- /dev/null +++ b/src/main/java/net/himeki/mcmtfabric/parallelised/ConcurrentArrayDeque.java @@ -0,0 +1,4 @@ +package net.himeki.mcmtfabric.parallelised; + +public class ConcurrentArrayDeque { +} diff --git a/src/main/java/net/himeki/mcmtfabric/parallelised/ConcurrentCollections.java b/src/main/java/net/himeki/mcmtfabric/parallelised/ConcurrentCollections.java new file mode 100644 index 0000000000000000000000000000000000000000..67dd5fe624fe4428d8907000cb23a33485fd6bd9 --- /dev/null +++ b/src/main/java/net/himeki/mcmtfabric/parallelised/ConcurrentCollections.java @@ -0,0 +1,41 @@ +package net.himeki.mcmtfabric.parallelised; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import java.util.*; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentLinkedDeque; +import java.util.concurrent.CopyOnWriteArrayList; +import java.util.stream.Collector; +import java.util.stream.Collectors; + +public class ConcurrentCollections { + + private static final Logger LOGGER = LogManager.getLogger(); + + public static Set newHashSet() { + //LOGGER.info("Concurrent hash set created"); + return Collections.newSetFromMap(new ConcurrentHashMap()); + } + + public static Map newHashMap() { + //LOGGER.info("Concurrent hash map created"); + return new ConcurrentHashMap(); + } + + public static List newLinkedList() { + LOGGER.info("Concurrent \"linked\" list created"); + return new CopyOnWriteArrayList(); + } + + public static Collector> toList() { + return Collectors.toCollection(CopyOnWriteArrayList::new); + } + + public static Queue newArrayDeque() { + LOGGER.info("Concurrent \"array\" deque created"); + return new ConcurrentLinkedDeque(); + } + +} diff --git a/src/main/java/net/himeki/mcmtfabric/parallelised/ConcurrentDoublyLinkedList.java b/src/main/java/net/himeki/mcmtfabric/parallelised/ConcurrentDoublyLinkedList.java new file mode 100644 index 0000000000000000000000000000000000000000..fec1f280c72c5b519173017877812ec3f7149ec5 --- /dev/null +++ b/src/main/java/net/himeki/mcmtfabric/parallelised/ConcurrentDoublyLinkedList.java @@ -0,0 +1,937 @@ +package net.himeki.mcmtfabric.parallelised; + +/* + * From: http://www.java2s.com/Code/Java/Collections-Data-Structure/ConcurrentDoublyLinkedList.htm + * + * Written by Doug Lea with assistance from members of JCP JSR-166 + * Expert Group and released to the public domain, as explained at + * http://creativecommons.org/licenses/publicdomain + * + * Modified to actually implement List + */ + +import org.apache.commons.lang3.NotImplementedException; + +import java.util.*; +import java.util.concurrent.atomic.AtomicReference; + +/** + * A concurrent linked-list implementation of a {@link Deque} (double-ended + * queue). Concurrent insertion, removal, and access operations execute safely + * across multiple threads. Iterators are weakly consistent, returning + * elements reflecting the state of the deque at some point at or since the + * creation of the iterator. They do not throw + * {@link ConcurrentModificationException}, and may proceed concurrently with + * other operations. + * + *

+ * This class and its iterators implement all of the optional methods + * of the {@link Collection} and {@link Iterator} interfaces. Like most other + * concurrent collection implementations, this class does not permit the use of + * null elements. because some null arguments and return values cannot + * be reliably distinguished from the absence of elements. Arbitrarily, the + * {@link Collection#remove} method is mapped to removeFirstOccurrence, + * and {@link Collection#add} is mapped to addLast. + * + *

+ * Beware that, unlike in most collections, the size method is + * NOT a constant-time operation. Because of the asynchronous nature of + * these deques, determining the current number of elements requires a traversal + * of the elements. + * + *

+ * This class is Serializable, but relies on default serialization + * mechanisms. Usually, it is a better idea for any serializable class using a + * ConcurrentLinkedDeque to instead serialize a snapshot of the + * elements obtained by method toArray. + * + * @author Doug Lea + * @param the type of elements held in this collection + */ + +public class ConcurrentDoublyLinkedList extends AbstractCollection implements List, java.io.Serializable { + + /* + * This is an adaptation of an algorithm described in Paul Martin's "A Practical + * Lock-Free Doubly-Linked List". Sun Labs Tech report. The basic idea is to + * primarily rely on next-pointers to ensure consistency. Prev-pointers are in + * part optimistic, reconstructed using forward pointers as needed. The main + * forward list uses a variant of HM-list algorithm similar to the one used in + * ConcurrentSkipListMap class, but a little simpler. It is also basically + * similar to the approach in Edya Ladan-Mozes and Nir Shavit "An Optimistic + * Approach to Lock-Free FIFO Queues" in DISC04. + * + * Quoting a summary in Paul Martin's tech report: + * + * All cleanups work to maintain these invariants: (1) forward pointers are the + * ground truth. (2) forward pointers to dead nodes can be improved by swinging + * them further forward around the dead node. (2.1) forward pointers are still + * correct when pointing to dead nodes, and forward pointers from dead nodes are + * left as they were when the node was deleted. (2.2) multiple dead nodes may + * point forward to the same node. (3) backward pointers were correct when they + * were installed (3.1) backward pointers are correct when pointing to any node + * which points forward to them, but since more than one forward pointer may + * point to them, the live one is best. (4) backward pointers that are out of + * date due to deletion point to a deleted node, and need to point further back + * until they point to the live node that points to their source. (5) backward + * pointers that are out of date due to insertion point too far backwards, so + * shortening their scope (by searching forward) fixes them. (6) backward + * pointers from a dead node cannot be "improved" since there may be no live + * node pointing forward to their origin. (However, it does no harm to try to + * improve them while racing with a deletion.) + * + * + * Notation guide for local variables n, b, f : a node, its predecessor, and + * successor s : some other successor + */ + + // Minor convenience utilities + + /** + * Returns true if given reference is non-null and isn't a header, trailer, or + * marker. + * + * @param n (possibly null) node + * @return true if n exists as a user node + */ + private static boolean usable(Node n) { + return n != null && !n.isSpecial(); + } + + /** + * Throws NullPointerException if argument is null + * + * @param v the element + */ + private static void checkNullArg(Object v) { + if (v == null) + throw new NullPointerException(); + } + + /** + * Returns element unless it is null, in which case throws + * NoSuchElementException. + * + * @param v the element + * @return the element + */ + private E screenNullResult(E v) { + if (v == null) + throw new NoSuchElementException(); + return v; + } + + /** + * Creates an array list and fills it with elements of this list. Used by + * toArray. + * + * @return the arrayList + */ + private ArrayList toArrayList() { + ArrayList c = new ArrayList(); + for (Node n = header.forward(); n != null; n = n.forward()) + c.add(n.element); + return c; + } + + // Fields and constructors + + private static final long serialVersionUID = 876323262645176354L; + + /** + * List header. First usable node is at header.forward(). + */ + private final Node header; + + /** + * List trailer. Last usable node is at trailer.back(). + */ + private final Node trailer; + + /** + * Constructs an empty deque. + */ + public ConcurrentDoublyLinkedList() { + Node h = new Node(null, null, null); + Node t = new Node(null, null, h); + h.setNext(t); + header = h; + trailer = t; + } + + /** + * Constructs a deque containing the elements of the specified collection, in + * the order they are returned by the collection's iterator. + * + * @param c the collection whose elements are to be placed into this deque. + * @throws NullPointerException if c or any element within it is + * null + */ + public ConcurrentDoublyLinkedList(Collection c) { + this(); + addAll(c); + } + + /** + * Prepends the given element at the beginning of this deque. + * + * @param o the element to be inserted at the beginning of this deque. + * @throws NullPointerException if the specified element is null + */ + public void addFirst(E o) { + checkNullArg(o); + while (header.append(o) == null) + ; + } + + /** + * Appends the given element to the end of this deque. This is identical in + * function to the add method. + * + * @param o the element to be inserted at the end of this deque. + * @throws NullPointerException if the specified element is null + */ + public void addLast(E o) { + checkNullArg(o); + while (trailer.prepend(o) == null) + ; + } + + /** + * Prepends the given element at the beginning of this deque. + * + * @param o the element to be inserted at the beginning of this deque. + * @return true always + * @throws NullPointerException if the specified element is null + */ + public boolean offerFirst(E o) { + addFirst(o); + return true; + } + + /** + * Appends the given element to the end of this deque. (Identical in function to + * the add method; included only for consistency.) + * + * @param o the element to be inserted at the end of this deque. + * @return true always + * @throws NullPointerException if the specified element is null + */ + public boolean offerLast(E o) { + addLast(o); + return true; + } + + /** + * Retrieves, but does not remove, the first element of this deque, or returns + * null if this deque is empty. + * + * @return the first element of this queue, or null if empty. + */ + public E peekFirst() { + Node n = header.successor(); + return (n == null) ? null : n.element; + } + + /** + * Retrieves, but does not remove, the last element of this deque, or returns + * null if this deque is empty. + * + * @return the last element of this deque, or null if empty. + */ + public E peekLast() { + Node n = trailer.predecessor(); + return (n == null) ? null : n.element; + } + + /** + * Returns the first element in this deque. + * + * @return the first element in this deque. + * @throws NoSuchElementException if this deque is empty. + */ + public E getFirst() { + return screenNullResult(peekFirst()); + } + + /** + * Returns the last element in this deque. + * + * @return the last element in this deque. + * @throws NoSuchElementException if this deque is empty. + */ + public E getLast() { + return screenNullResult(peekLast()); + } + + /** + * Retrieves and removes the first element of this deque, or returns null if + * this deque is empty. + * + * @return the first element of this deque, or null if empty. + */ + public E pollFirst() { + for (;;) { + Node n = header.successor(); + if (!usable(n)) + return null; + if (n.delete()) + return n.element; + } + } + + /** + * Retrieves and removes the last element of this deque, or returns null if this + * deque is empty. + * + * @return the last element of this deque, or null if empty. + */ + public E pollLast() { + for (;;) { + Node n = trailer.predecessor(); + if (!usable(n)) + return null; + if (n.delete()) + return n.element; + } + } + + /** + * Removes and returns the first element from this deque. + * + * @return the first element from this deque. + * @throws NoSuchElementException if this deque is empty. + */ + public E removeFirst() { + return screenNullResult(pollFirst()); + } + + /** + * Removes and returns the last element from this deque. + * + * @return the last element from this deque. + * @throws NoSuchElementException if this deque is empty. + */ + public E removeLast() { + return screenNullResult(pollLast()); + } + + // *** Queue and stack methods *** + public boolean offer(E e) { + return offerLast(e); + } + + public boolean add(E e) { + return offerLast(e); + } + + public E poll() { + return pollFirst(); + } + + public E remove() { + return removeFirst(); + } + + public E peek() { + return peekFirst(); + } + + public E element() { + return getFirst(); + } + + public void push(E e) { + addFirst(e); + } + + public E pop() { + return removeFirst(); + } + + /** + * Removes the first element e such that o.equals(e), if such + * an element exists in this deque. If the deque does not contain the element, + * it is unchanged. + * + * @param o element to be removed from this deque, if present. + * @return true if the deque contained the specified element. + * @throws NullPointerException if the specified element is null + */ + public boolean removeFirstOccurrence(Object o) { + checkNullArg(o); + for (;;) { + Node n = header.forward(); + for (;;) { + if (n == null) + return false; + if (o.equals(n.element)) { + if (n.delete()) + return true; + else + break; // restart if interference + } + n = n.forward(); + } + } + } + + /** + * Removes the last element e such that o.equals(e), if such + * an element exists in this deque. If the deque does not contain the element, + * it is unchanged. + * + * @param o element to be removed from this deque, if present. + * @return true if the deque contained the specified element. + * @throws NullPointerException if the specified element is null + */ + public boolean removeLastOccurrence(Object o) { + checkNullArg(o); + for (;;) { + Node s = trailer; + for (;;) { + Node n = s.back(); + if (s.isDeleted() || (n != null && n.successor() != s)) + break; // restart if pred link is suspect. + if (n == null) + return false; + if (o.equals(n.element)) { + if (n.delete()) + return true; + else + break; // restart if interference + } + s = n; + } + } + } + + /** + * Returns true if this deque contains at least one element e + * such that o.equals(e). + * + * @param o element whose presence in this deque is to be tested. + * @return true if this deque contains the specified element. + */ + public boolean contains(Object o) { + if (o == null) + return false; + for (Node n = header.forward(); n != null; n = n.forward()) + if (o.equals(n.element)) + return true; + return false; + } + + /** + * Returns true if this collection contains no elements. + *

+ * + * @return true if this collection contains no elements. + */ + public boolean isEmpty() { + return !usable(header.successor()); + } + + /** + * Returns the number of elements in this deque. If this deque contains more + * than Integer.MAX_VALUE elements, it returns + * Integer.MAX_VALUE. + * + *

+ * Beware that, unlike in most collections, this method is NOT a + * constant-time operation. Because of the asynchronous nature of these deques, + * determining the current number of elements requires traversing them all to + * count them. Additionally, it is possible for the size to change during + * execution of this method, in which case the returned result will be + * inaccurate. Thus, this method is typically not very useful in concurrent + * applications. + * + * @return the number of elements in this deque. + */ + public int size() { + long count = 0; + for (Node n = header.forward(); n != null; n = n.forward()) + ++count; + return (count >= Integer.MAX_VALUE) ? Integer.MAX_VALUE : (int) count; + } + + /** + * Removes the first element e such that o.equals(e), if such + * an element exists in this deque. If the deque does not contain the element, + * it is unchanged. + * + * @param o element to be removed from this deque, if present. + * @return true if the deque contained the specified element. + * @throws NullPointerException if the specified element is null + */ + public boolean remove(Object o) { + return removeFirstOccurrence(o); + } + + /** + * Appends all of the elements in the specified collection to the end of this + * deque, in the order that they are returned by the specified collection's + * iterator. The behavior of this operation is undefined if the specified + * collection is modified while the operation is in progress. (This implies that + * the behavior of this call is undefined if the specified Collection is this + * deque, and this deque is nonempty.) + * + * @param c the elements to be inserted into this deque. + * @return true if this deque changed as a result of the call. + * @throws NullPointerException if c or any element within it is + * null + */ + public boolean addAll(Collection c) { + Iterator it = c.iterator(); + if (!it.hasNext()) + return false; + do { + addLast(it.next()); + } while (it.hasNext()); + return true; + } + + /** + * Removes all of the elements from this deque. + */ + public void clear() { + while (pollFirst() != null) + ; + } + + /** + * Returns an array containing all of the elements in this deque in the correct + * order. + * + * @return an array containing all of the elements in this deque in the correct + * order. + */ + public Object[] toArray() { + return toArrayList().toArray(); + } + + /** + * Returns an array containing all of the elements in this deque in the correct + * order; the runtime type of the returned array is that of the specified array. + * If the deque fits in the specified array, it is returned therein. Otherwise, + * a new array is allocated with the runtime type of the specified array and the + * size of this deque. + *

+ * + * If the deque fits in the specified array with room to spare (i.e., the array + * has more elements than the deque), the element in the array immediately + * following the end of the collection is set to null. This is useful in + * determining the length of the deque only if the caller knows that the + * deque does not contain any null elements. + * + * @param a the array into which the elements of the deque are to be stored, if + * it is big enough; otherwise, a new array of the same runtime type is + * allocated for this purpose. + * @return an array containing the elements of the deque. + * @throws ArrayStoreException if the runtime type of a is not a supertype of + * the runtime type of every element in this deque. + * @throws NullPointerException if the specified array is null. + */ + public T[] toArray(T[] a) { + return toArrayList().toArray(a); + } + + /** + * Returns a weakly consistent iterator over the elements in this deque, in + * first-to-last order. The next method returns elements reflecting the + * state of the deque at some point at or since the creation of the iterator. + * The method does not throw {@link ConcurrentModificationException}, + * and may proceed concurrently with other operations. + * + * @return an iterator over the elements in this deque + */ + public Iterator iterator() { + return new CLDIterator(); + } + + final class CLDIterator implements Iterator { + Node last; + + Node next = header.forward(); + + public boolean hasNext() { + return next != null; + } + + public E next() { + Node l = last = next; + if (l == null) + throw new NoSuchElementException(); + next = next.forward(); + return l.element; + } + + public void remove() { + Node l = last; + if (l == null) + throw new IllegalStateException(); + while (!l.delete() && !l.isDeleted()) + ; + } + } + + @Override + public boolean addAll(int index, Collection c) { + throw new NotImplementedException("TODO"); + } + + @Override + public E get(int index) { + Node current = header.successor(); + if (current == null) { + throw new IndexOutOfBoundsException(); + } + for (; index > 0; index --) { + current = current.successor(); + if (current == null) { + throw new IndexOutOfBoundsException(); + } + } + return current.element; + } + + @Override + public E set(int index, E element) { + throw new NotImplementedException("INVALID"); + } + + @Override + public void add(int index, E element) { + throw new NotImplementedException("INVALID"); + } + + @Override + public E remove(int index) { + throw new NotImplementedException("INVALID"); + } + + @Override + public int indexOf(Object o) { + throw new NotImplementedException("INVALID"); + } + + @Override + public int lastIndexOf(Object o) { + throw new NotImplementedException("INVALID"); + } + + @Override + public ListIterator listIterator() { + throw new NotImplementedException("INVALID"); + } + + @Override + public ListIterator listIterator(int index) { + throw new NotImplementedException("INVALID"); + } + + @Override + public List subList(int fromIndex, int toIndex) { + throw new NotImplementedException("INVALID"); + } + +} + +/** + * Linked Nodes. As a minor efficiency hack, this class opportunistically + * inherits from AtomicReference, with the atomic ref used as the "next" link. + * + * Nodes are in doubly-linked lists. There are three kinds of special nodes, + * distinguished by: * The list header has a null prev link * The list trailer + * has a null next link * A deletion marker has a prev link pointing to itself. + * All three kinds of special nodes have null element fields. + * + * Regular nodes have non-null element, next, and prev fields. To avoid visible + * inconsistencies when deletions overlap element replacement, replacements are + * done by replacing the node, not just setting the element. + * + * Nodes can be traversed by read-only ConcurrentLinkedDeque class operations + * just by following raw next pointers, so long as they ignore any special nodes + * seen along the way. (This is automated in method forward.) However, traversal + * using prev pointers is not guaranteed to see all live nodes since a prev + * pointer of a deleted node can become unrecoverably stale. + */ + +class Node extends AtomicReference> { + + private static final long serialVersionUID = 6640557564507962862L; + + private volatile Node prev; + + final E element; + + /** Creates a node with given contents */ + Node(E element, Node next, Node prev) { + super(next); + this.prev = prev; + this.element = element; + } + + /** Creates a marker node with given successor */ + Node(Node next) { + super(next); + this.prev = this; + this.element = null; + } + + /** + * Gets next link (which is actually the value held as atomic reference). + */ + private Node getNext() { + return get(); + } + + /** + * Sets next link + * + * @param n the next node + */ + void setNext(Node n) { + set(n); + } + + /** + * compareAndSet next link + */ + private boolean casNext(Node cmp, Node val) { + return compareAndSet(cmp, val); + } + + /** + * Gets prev link + */ + private Node getPrev() { + return prev; + } + + /** + * Sets prev link + * + * @param b the previous node + */ + void setPrev(Node b) { + prev = b; + } + + /** + * Returns true if this is a header, trailer, or marker node + */ + boolean isSpecial() { + return element == null; + } + + /** + * Returns true if this is a trailer node + */ + boolean isTrailer() { + return getNext() == null; + } + + /** + * Returns true if this is a header node + */ + boolean isHeader() { + return getPrev() == null; + } + + /** + * Returns true if this is a marker node + */ + boolean isMarker() { + return getPrev() == this; + } + + /** + * Returns true if this node is followed by a marker, meaning that it is + * deleted. + * + * @return true if this node is deleted + */ + boolean isDeleted() { + Node f = getNext(); + return f != null && f.isMarker(); + } + + /** + * Returns next node, ignoring deletion marker + */ + private Node nextNonmarker() { + Node f = getNext(); + return (f == null || !f.isMarker()) ? f : f.getNext(); + } + + /** + * Returns the next non-deleted node, swinging next pointer around any + * encountered deleted nodes, and also patching up successor''s prev link to + * point back to this. Returns null if this node is trailer so has no successor. + * + * @return successor, or null if no such + */ + Node successor() { + Node f = nextNonmarker(); + for (;;) { + if (f == null) + return null; + if (!f.isDeleted()) { + if (f.getPrev() != this && !isDeleted()) + f.setPrev(this); // relink f's prev + return f; + } + Node s = f.nextNonmarker(); + if (f == getNext()) + casNext(f, s); // unlink f + f = s; + } + } + + /** + * Returns the apparent predecessor of target by searching forward for it + * starting at this node, patching up pointers while traversing. Used by + * predecessor(). + * + * @return target's predecessor, or null if not found + */ + private Node findPredecessorOf(Node target) { + Node n = this; + for (;;) { + Node f = n.successor(); + if (f == target) + return n; + if (f == null) + return null; + n = f; + } + } + + /** + * Returns the previous non-deleted node, patching up pointers as needed. + * Returns null if this node is header so has no successor. May also return null + * if this node is deleted, so doesn't have a distinct predecessor. + * + * @return predecessor or null if not found + */ + Node predecessor() { + Node n = this; + for (;;) { + Node b = n.getPrev(); + if (b == null) + return n.findPredecessorOf(this); + Node s = b.getNext(); + if (s == this) + return b; + if (s == null || !s.isMarker()) { + Node p = b.findPredecessorOf(this); + if (p != null) + return p; + } + n = b; + } + } + + /** + * Returns the next node containing a nondeleted user element. Use for forward + * list traversal. + * + * @return successor, or null if no such + */ + Node forward() { + Node f = successor(); + return (f == null || f.isSpecial()) ? null : f; + } + + /** + * Returns previous node containing a nondeleted user element, if possible. Use + * for backward list traversal, but beware that if this method is called from a + * deleted node, it might not be able to determine a usable predecessor. + * + * @return predecessor, or null if no such could be found + */ + Node back() { + Node f = predecessor(); + return (f == null || f.isSpecial()) ? null : f; + } + + /** + * Tries to insert a node holding element as successor, failing if this node is + * deleted. + * + * @param element the element + * @return the new node, or null on failure. + */ + Node append(E element) { + for (;;) { + Node f = getNext(); + if (f == null || f.isMarker()) + return null; + Node x = new Node(element, f, this); + if (casNext(f, x)) { + f.setPrev(x); // optimistically link + return x; + } + } + } + + /** + * Tries to insert a node holding element as predecessor, failing if no live + * predecessor can be found to link to. + * + * @param element the element + * @return the new node, or null on failure. + */ + Node prepend(E element) { + for (;;) { + Node b = predecessor(); + if (b == null) + return null; + Node x = new Node(element, this, b); + if (b.casNext(this, x)) { + setPrev(x); // optimistically link + return x; + } + } + } + + /** + * Tries to mark this node as deleted, failing if already deleted or if this + * node is header or trailer + * + * @return true if successful + */ + boolean delete() { + Node b = getPrev(); + Node f = getNext(); + if (b != null && f != null && !f.isMarker() && casNext(f, new Node(f))) { + if (b.casNext(this, f)) + f.setPrev(b); + return true; + } + return false; + } + + /** + * Tries to insert a node holding element to replace this node. failing if + * already deleted. + * + * @param newElement the new element + * @return the new node, or null on failure. + */ + Node replace(E newElement) { + for (;;) { + Node b = getPrev(); + Node f = getNext(); + if (b == null || f == null || f.isMarker()) + return null; + Node x = new Node(newElement, f, b); + if (casNext(f, new Node(x))) { + b.successor(); // to relink b + x.successor(); // to relink f + return x; + } + } + } +} \ No newline at end of file diff --git a/src/main/java/net/himeki/mcmtfabric/parallelised/fastutil/ConcurrentLongLinkedOpenHashSet.java b/src/main/java/net/himeki/mcmtfabric/parallelised/fastutil/ConcurrentLongLinkedOpenHashSet.java new file mode 100644 index 0000000000000000000000000000000000000000..586b3c87dcf010e2401933c5ec2338f59b9edad3 --- /dev/null +++ b/src/main/java/net/himeki/mcmtfabric/parallelised/fastutil/ConcurrentLongLinkedOpenHashSet.java @@ -0,0 +1,230 @@ +package net.himeki.mcmtfabric.parallelised.fastutil; + +import it.unimi.dsi.fastutil.longs.*; + +import java.util.Collection; +import java.util.Iterator; +import java.util.concurrent.ConcurrentSkipListSet; + +public class ConcurrentLongLinkedOpenHashSet extends LongLinkedOpenHashSet { + + private static final long serialVersionUID = -5532128240738069111L; + + private final ConcurrentSkipListSet backing; + + public ConcurrentLongLinkedOpenHashSet() { + //backing = new ConcurrentLinkedDeque(); + backing = new ConcurrentSkipListSet(); + } + + public ConcurrentLongLinkedOpenHashSet(final int initial) { + //backing = new ConcurrentLinkedDeque(); + backing = new ConcurrentSkipListSet(); + } + + public ConcurrentLongLinkedOpenHashSet(final int initial, final float dnc) { + this(initial); + } + + public ConcurrentLongLinkedOpenHashSet(final LongCollection c) { + this(c.size()); + addAll(c); + } + + public ConcurrentLongLinkedOpenHashSet(final LongCollection c, final float f) { + this(c.size(), f); + addAll(c); + } + + public ConcurrentLongLinkedOpenHashSet(final LongIterator i, final float f) { + this(16, f); + while (i.hasNext()) + add(i.nextLong()); + } + + public ConcurrentLongLinkedOpenHashSet(final LongIterator i) { + this(i, -1); + } + + public ConcurrentLongLinkedOpenHashSet(final Iterator i, final float f) { + this(LongIterators.asLongIterator(i), f); + } + + public ConcurrentLongLinkedOpenHashSet(final Iterator i) { + this(LongIterators.asLongIterator(i)); + } + + public ConcurrentLongLinkedOpenHashSet(final long[] a, final int offset, final int length, final float f) { + this(length < 0 ? 0 : length, f); + LongArrays.ensureOffsetLength(a, offset, length); + for (int i = 0; i < length; i++) + add(a[offset + i]); + } + + public ConcurrentLongLinkedOpenHashSet(final long[] a, final int offset, final int length) { + this(a, offset, length, DEFAULT_LOAD_FACTOR); + } + + public ConcurrentLongLinkedOpenHashSet(final long[] a, final float f) { + this(a, 0, a.length, f); + } + + public ConcurrentLongLinkedOpenHashSet(final long[] a) { + this(a, -1); + } + + @Override + public boolean add(final long k) { + boolean out = backing.add(k); + /* + if (!firstDef) { + first = k; + firstDef = true; + } + last = k; + */ + return out; + } + + @Override + public boolean addAll(LongCollection c) { + return addAll((Collection) c); + } + + @Override + public boolean addAll(Collection c) { + return backing.addAll(c); + } + + @Override + public boolean addAndMoveToFirst(final long k) { + boolean out = backing.add(k); + //first = k; + return out; + } + + @Override + public boolean addAndMoveToLast(final long k) { + boolean out = backing.add(k); + //last = k; + return out; + } + + @Override + public void clear() { + backing.clear(); + } + + @Override + public LongLinkedOpenHashSet clone() { + return new ConcurrentLongLinkedOpenHashSet(backing.iterator()); + } + + @Override + public LongComparator comparator() { + return null; + } + + @Override + public boolean contains(final long k) { + return backing.contains(k); + } + + @Override + public long firstLong() { + /* + if (backing.size() == 0) throw new NoSuchElementException(); + return first; + */ + return backing.first(); + } + + @Override + public int hashCode() { + return backing.hashCode(); + } + + @Override + public LongSortedSet headSet(long to) { + throw new UnsupportedOperationException(); + } + + @Override + public boolean isEmpty() { + return backing.isEmpty(); + } + + @Override + public LongListIterator iterator() { + return FastUtilHackUtil.wrap(backing.iterator()); + } + + @Override + public LongListIterator iterator(long from) { + throw new IllegalStateException(); + //return FastUtilHackUtil.wrap(backing.iterator()); + } + + @Override + public long lastLong() { + /* + if (backing.size() == 0) throw new NoSuchElementException(); + return last; + */ + return backing.last(); + } + + @Override + public boolean remove(final long k) { + /* + if (k == first) { + first = backing.iterator().next(); + } + if (k == last) { + last = backing.iterator().next(); + } + */ + return backing.remove(k); + } + + @Override + public long removeFirstLong() { + long fl = this.firstLong(); + this.remove(fl); + //first = backing.iterator().next(); + return fl; + } + + @Override + public long removeLastLong() { + long fl = this.lastLong(); + this.remove(fl); + //last = backing.iterator().next(); + return fl; + } + + @Override + public int size() { + return backing.size(); + } + + @Override + public LongSortedSet subSet(long from, long to) { + throw new UnsupportedOperationException(); + } + + @Override + public LongSortedSet tailSet(long from) { + throw new UnsupportedOperationException(); + } + + @Override + public boolean trim() { + return true; + } + + @Override + public boolean trim(final int n) { + return true; + } +} diff --git a/src/main/java/net/himeki/mcmtfabric/parallelised/fastutil/ConcurrentLongSortedSet.java b/src/main/java/net/himeki/mcmtfabric/parallelised/fastutil/ConcurrentLongSortedSet.java new file mode 100644 index 0000000000000000000000000000000000000000..93bd066ec2013e42a85fcf21344fe41f3ad69598 --- /dev/null +++ b/src/main/java/net/himeki/mcmtfabric/parallelised/fastutil/ConcurrentLongSortedSet.java @@ -0,0 +1,144 @@ +package net.himeki.mcmtfabric.parallelised.fastutil; + +import it.unimi.dsi.fastutil.longs.*; +import org.jetbrains.annotations.NotNull; + +import java.util.Collection; +import java.util.concurrent.ConcurrentSkipListSet; + +public class ConcurrentLongSortedSet implements LongSortedSet { + + ConcurrentSkipListSet back = new ConcurrentSkipListSet<>(); + + @Override + public LongBidirectionalIterator iterator(long fromElement) { + return null; + } + + @Override + public int size() { + return back.size(); + } + + @Override + public boolean isEmpty() { + return back.isEmpty(); + } + + @Override + public LongBidirectionalIterator iterator() { + return null; + } + + @NotNull + @Override + public Object[] toArray() { + return back.toArray(); + } + + @NotNull + @Override + public T[] toArray(@NotNull T[] ts) { + return null; + } + + @Override + public boolean containsAll(@NotNull Collection collection) { + return back.containsAll(collection); + } + + @Override + public boolean addAll(@NotNull Collection collection) { + return back.addAll(collection); + } + + @Override + public boolean removeAll(@NotNull Collection collection) { + return back.removeAll(collection); + } + + @Override + public boolean retainAll(@NotNull Collection collection) { + return back.retainAll(collection); + } + + @Override + public void clear() { + back.clear(); + } + + @Override + public boolean add(long key) { + return back.add(key); + } + + @Override + public boolean contains(long key) { + return back.contains(key); + } + + @Override + public long[] toLongArray() { + return new long[0]; + } + + @Override + public long[] toArray(long[] a) { + return new long[0]; + } + + @Override + public boolean addAll(LongCollection c) { + return back.addAll(c); + } + + @Override + public boolean containsAll(LongCollection c) { + return back.containsAll(c); + } + + @Override + public boolean removeAll(LongCollection c) { + return back.removeAll(c); + } + + @Override + public boolean retainAll(LongCollection c) { + return back.retainAll(c); + } + + @Override + public boolean remove(long k) { + return back.remove(k); + } + + @Override + public LongSortedSet subSet(long fromElement, long toElement) { + return new LongAVLTreeSet(back.subSet(fromElement,toElement)); + } + + @Override + public LongSortedSet headSet(long toElement) { + return new LongAVLTreeSet(back.headSet(toElement)); + } + + @Override + public LongSortedSet tailSet(long fromElement) { + return new LongAVLTreeSet(back.tailSet(fromElement)); + } + + @Override + public LongComparator comparator() { + return null; + } + + @Override + public long firstLong() { + return back.first(); + } + + @Override + public long lastLong() { + return back.last(); + } +} diff --git a/src/main/java/net/himeki/mcmtfabric/parallelised/fastutil/ConcurrentShortHashSet.java b/src/main/java/net/himeki/mcmtfabric/parallelised/fastutil/ConcurrentShortHashSet.java new file mode 100644 index 0000000000000000000000000000000000000000..ff1a4f87356459d3bc990a77c3081932046da5b1 --- /dev/null +++ b/src/main/java/net/himeki/mcmtfabric/parallelised/fastutil/ConcurrentShortHashSet.java @@ -0,0 +1,112 @@ +package net.himeki.mcmtfabric.parallelised.fastutil; + +import it.unimi.dsi.fastutil.shorts.ShortCollection; +import it.unimi.dsi.fastutil.shorts.ShortIterator; +import it.unimi.dsi.fastutil.shorts.ShortSet; +import org.jetbrains.annotations.NotNull; + +import java.util.Collection; +import java.util.concurrent.ConcurrentHashMap; + +public class ConcurrentShortHashSet implements ShortSet { + + ConcurrentHashMap.KeySetView backing = ConcurrentHashMap.newKeySet(); + + @Override + public int size() { + return backing.size(); + } + + @Override + public boolean isEmpty() { + return backing.isEmpty(); + } + + @Override + public ShortIterator iterator() { + return new FastUtilHackUtil.WrappingShortIterator(backing.iterator()); + } + + @NotNull + @Override + public Object[] toArray() { + return backing.toArray(); + } + + @NotNull + @Override + public T[] toArray(@NotNull T[] ts) { + return (T[]) backing.toArray(); + } + + @Override + public boolean containsAll(@NotNull Collection collection) { + return backing.containsAll(collection); + } + + @Override + public boolean addAll(@NotNull Collection collection) { + return backing.addAll(collection); + } + + @Override + public boolean removeAll(@NotNull Collection collection) { + return backing.removeAll(collection); + } + + @Override + public boolean retainAll(@NotNull Collection collection) { + return backing.retainAll(collection); + } + + @Override + public void clear() { + backing.clear(); + + } + + @Override + public boolean add(short key) { + return backing.add(key); + } + + @Override + public boolean contains(short key) { + return backing.contains(key); + } + + @Override + public short[] toShortArray() { + return new short[0]; + } + + @Override + public short[] toArray(short[] a) { + return new short[0]; + } + + @Override + public boolean addAll(ShortCollection c) { + return backing.addAll(c); + } + + @Override + public boolean containsAll(ShortCollection c) { + return backing.containsAll(c); + } + + @Override + public boolean removeAll(ShortCollection c) { + return backing.removeAll(c); + } + + @Override + public boolean retainAll(ShortCollection c) { + return backing.retainAll(c); + } + + @Override + public boolean remove(short k) { + return backing.remove(k); + } +} diff --git a/src/main/java/net/himeki/mcmtfabric/parallelised/fastutil/FastUtilHackUtil.java b/src/main/java/net/himeki/mcmtfabric/parallelised/fastutil/FastUtilHackUtil.java new file mode 100644 index 0000000000000000000000000000000000000000..ca1fd9ca6f5c5d5d4a0f374440ccaf80347fb781 --- /dev/null +++ b/src/main/java/net/himeki/mcmtfabric/parallelised/fastutil/FastUtilHackUtil.java @@ -0,0 +1,1678 @@ +package net.himeki.mcmtfabric.parallelised.fastutil; + +import it.unimi.dsi.fastutil.bytes.ByteCollection; +import it.unimi.dsi.fastutil.bytes.ByteIterator; +import it.unimi.dsi.fastutil.ints.Int2ObjectMap.Entry; +import it.unimi.dsi.fastutil.ints.IntCollection; +import it.unimi.dsi.fastutil.ints.IntIterator; +import it.unimi.dsi.fastutil.ints.IntSet; +import it.unimi.dsi.fastutil.longs.*; +import it.unimi.dsi.fastutil.objects.ObjectCollection; +import it.unimi.dsi.fastutil.objects.ObjectIterator; +import it.unimi.dsi.fastutil.objects.ObjectSet; +import it.unimi.dsi.fastutil.shorts.ShortIterator; +import org.apache.commons.lang3.ArrayUtils; + +import java.util.*; +import java.util.function.Function; +import java.util.stream.Collectors; + +public class FastUtilHackUtil { + + public static class ConvertingObjectSet implements ObjectSet { + + Set backing; + Function forward; + Function back; + + public ConvertingObjectSet(Set backing, Function forward, Function back) { + this.backing = backing; + this.forward = forward; + this.back = back; + } + + @Override + public int size() { + return backing.size(); + } + + @Override + public boolean isEmpty() { + return backing.isEmpty(); + } + + @SuppressWarnings("unchecked") + @Override + public boolean contains(Object o) { + try { + return backing.contains(back.apply((T) o)); + } catch (ClassCastException cce) { + return false; + } + } + + @Override + public Object[] toArray() { + return backing.stream().map(forward).toArray(); + } + + @Override + public R[] toArray(R[] a) { + return backing.stream().map(forward).collect(Collectors.toSet()).toArray(a); + } + + @Override + public boolean add(T e) { + return backing.add(back.apply(e)); + } + + @SuppressWarnings("unchecked") + @Override + public boolean remove(Object o) { + try { + return backing.remove(back.apply((T) o)); + } catch (ClassCastException cce) { + return false; + } + } + + @SuppressWarnings("unchecked") + @Override + public boolean containsAll(Collection c) { + try { + return backing.containsAll(c.stream().map(i -> back.apply((T) i)).collect(Collectors.toSet())); + } catch (ClassCastException cce) { + return false; + } + + } + + @Override + public boolean addAll(Collection c) { + return backing.addAll(c.stream().map(i -> back.apply(i)).collect(Collectors.toSet())); + } + + @SuppressWarnings("unchecked") + @Override + public boolean removeAll(Collection c) { + try { + return backing.removeAll(c.stream().map(i -> back.apply((T) i)).collect(Collectors.toSet())); + } catch (ClassCastException cce) { + return false; + } + } + + @SuppressWarnings("unchecked") + @Override + public boolean retainAll(Collection c) { + try { + return backing.retainAll(c.stream().map(i -> back.apply((T) i)).collect(Collectors.toSet())); + } catch (ClassCastException cce) { + return false; + } + } + + @Override + public void clear() { + backing.clear(); + + } + + @Override + public ObjectIterator iterator() { + final Iterator backg = backing.iterator(); + return new ObjectIterator() { + + @Override + public boolean hasNext() { + return backg.hasNext(); + } + + @Override + public T next() { + return forward.apply(backg.next()); + } + + @Override + public void remove() { + backg.remove(); + } + }; + } + + + } + + public static class ConvertingObjectSetFast implements Long2ObjectMap.FastEntrySet { + + Set backing; + Function> forward; + Function, E> back; + + public ConvertingObjectSetFast(Set backing, + Function> forward, + Function, E> back) { + this.backing = backing; + this.forward = forward; + this.back = back; + } + + @Override + public int size() { + return backing.size(); + } + + @Override + public boolean isEmpty() { + return backing.isEmpty(); + } + + @SuppressWarnings("unchecked") + @Override + public boolean contains(Object o) { + try { + return backing.contains(back.apply((Long2ObjectMap.Entry)o)); + } catch (ClassCastException cce) { + return false; + } + } + + @Override + public Object[] toArray() { + return backing.stream().map(forward).toArray(); + } + + @Override + public R[] toArray(R[] a) { + return backing.stream().map(forward).collect(Collectors.toSet()).toArray(a); + } + + @SuppressWarnings("unchecked") + @Override + public boolean remove(Object o) { + try { + return backing.remove(back.apply((Long2ObjectMap.Entry)o)); + } catch (ClassCastException cce) { + return false; + } + } + + @SuppressWarnings("unchecked") + @Override + public boolean containsAll(Collection c) { + try { + return backing.containsAll(c.stream() + .map(i -> back.apply((Long2ObjectMap.Entry) i)) + .collect(Collectors.toSet())); + } catch (ClassCastException cce) { + return false; + } + + } + + @SuppressWarnings("unchecked") + @Override + public boolean removeAll(Collection c) { + try { + return backing.removeAll(c.stream().map(i -> back + .apply((Long2ObjectMap.Entry) i)) + .collect(Collectors.toSet())); + } catch (ClassCastException cce) { + return false; + } + } + + @SuppressWarnings("unchecked") + @Override + public boolean retainAll(Collection c) { + try { + return backing.retainAll(c.stream() + .map(i -> back.apply((Long2ObjectMap.Entry) i)) + .collect(Collectors.toSet())); + } catch (ClassCastException cce) { + return false; + } + } + + @Override + public void clear() { + backing.clear(); + + } + + @Override + public ObjectIterator> iterator() { + final Iterator backg = backing.iterator(); + return new ObjectIterator>() { + + @Override + public boolean hasNext() { + return backg.hasNext(); + } + + @Override + public Long2ObjectMap.Entry next() { + return forward.apply(backg.next()); + } + + @Override + public void remove() { + backg.remove(); + } + }; + } + + @Override + public boolean add(Long2ObjectMap.Entry e) { + return backing.add(back.apply(e)); + } + + @Override + public boolean addAll(Collection> c) { + return backing.addAll(c.stream().map(back).collect(Collectors.toList())); + } + + @Override + public ObjectIterator> fastIterator() { + return iterator(); + } + + + } + + private static Entry intEntryForwards(Map.Entry entry) { + return new Entry() { + + @Override + public T getValue() { + return entry.getValue(); + } + + @Override + public T setValue(T value) { + return entry.setValue(value); + } + + @Override + public int getIntKey() { + return entry.getKey(); + } + + @Override + public boolean equals(Object obj) { + if (obj == entry) { + return true; + } + return super.equals(obj); + } + + @Override + public int hashCode() { + return entry.hashCode(); + } + }; + } + + private static Map.Entry intEntryBackwards(Entry entry) { + return entry; + } + + private static Long2ObjectMap.Entry longEntryForwards(Map.Entry entry) { + return new Long2ObjectMap.Entry() { + + @Override + public T getValue() { + return entry.getValue(); + } + + @Override + public T setValue(T value) { + return entry.setValue(value); + } + + @Override + public long getLongKey() { + return entry.getKey(); + } + + @Override + public boolean equals(Object obj) { + if (obj == entry) { + return true; + } + return super.equals(obj); + } + + @Override + public int hashCode() { + return entry.hashCode(); + } + }; + } + + private static Map.Entry longEntryBackwards(Long2ObjectMap.Entry entry) { + return entry; + } + + private static Long2ByteMap.Entry longByteEntryForwards(Map.Entry entry) { + return new Long2ByteMap.Entry() { + + @Override + public Byte getValue() { + return entry.getValue(); + } + + @Override + public byte setValue(byte value) { + return entry.setValue(value); + } + + @Override + public byte getByteValue() { + return entry.getValue(); + } + + @Override + public long getLongKey() { + return entry.getKey(); + } + + @Override + public boolean equals(Object obj) { + if (obj == entry) { + return true; + } + return super.equals(obj); + } + + @Override + public int hashCode() { + return entry.hashCode(); + } + + }; + } + + private static Map.Entry longByteEntryBackwards(Long2ByteMap.Entry entry) { + return entry; + } + + private static Long2LongMap.Entry longLongEntryForwards(Map.Entry entry) { + return new Long2LongMap.Entry() { + + @Override + public Long getValue() { + return entry.getValue(); + } + + @Override + public long setValue(long value) { + return entry.setValue(value); + } + + @Override + public long getLongValue() { + return entry.getValue(); + } + + @Override + public long getLongKey() { + return entry.getKey(); + } + + @Override + public boolean equals(Object obj) { + if (obj == entry) { + return true; + } + return super.equals(obj); + } + + @Override + public int hashCode() { + return entry.hashCode(); + } + + }; + } + + private static Map.Entry longLongEntryBackwards(Long2LongMap.Entry entry) { + return entry; + } + + public static ObjectSet> entrySetIntWrap(Map map) { + return new ConvertingObjectSet, Entry>(map.entrySet(), FastUtilHackUtil::intEntryForwards, FastUtilHackUtil::intEntryBackwards); + } + + public static ObjectSet> entrySetLongWrap(Map map) { + return new ConvertingObjectSet, Long2ObjectMap.Entry>(map.entrySet(), FastUtilHackUtil::longEntryForwards, FastUtilHackUtil::longEntryBackwards); + } + + public static Long2ObjectMap.FastEntrySet entrySetLongWrapFast(Map map) { + return new ConvertingObjectSetFast, T>(map.entrySet(), FastUtilHackUtil::longEntryForwards, FastUtilHackUtil::longEntryBackwards); + } + + public static ObjectSet entrySetLongByteWrap(Map map) { + return new ConvertingObjectSet, Long2ByteMap.Entry>(map.entrySet(), FastUtilHackUtil::longByteEntryForwards, FastUtilHackUtil::longByteEntryBackwards); + } + + public static ObjectSet entrySetLongLongWrap(Map map) { + return new ConvertingObjectSet, Long2LongMap.Entry>(map.entrySet(), FastUtilHackUtil::longLongEntryForwards, FastUtilHackUtil::longLongEntryBackwards); + } + + + static class WrappingIntIterator implements IntIterator { + + Iterator backing; + + public WrappingIntIterator(Iterator backing) { + this.backing = backing; + } + + @Override + public boolean hasNext() { + return backing.hasNext(); + } + + @Override + public int nextInt() { + return backing.next(); + } + + @Override + public Integer next() { + return backing.next(); + } + + @Override + public void remove() { + backing.remove(); + } + + } + + static class WrappingLongIterator implements LongIterator { + + Iterator backing; + + public WrappingLongIterator(Iterator backing) { + this.backing = backing; + } + + @Override + public boolean hasNext() { + return backing.hasNext(); + } + + @Override + public long nextLong() { + return backing.next(); + } + + @Override + public Long next() { + return backing.next(); + } + + @Override + public void remove() { + backing.remove(); + } + + } + + static class WrappingShortIterator implements ShortIterator { + + Iterator backing; + + public WrappingShortIterator(Iterator backing) { + this.backing = backing; + } + + @Override + public boolean hasNext() { + return backing.hasNext(); + } + + @Override + public short nextShort() { + return backing.next(); + } + + @Override + public Short next() { + return backing.next(); + } + + @Override + public void remove() { + backing.remove(); + } + + } + + public static class WrappingIntSet implements IntSet { + + Set backing; + + public WrappingIntSet(Set backing) { + this.backing = backing; + } + + @Override + public boolean add(int key) { + return backing.add(key); + } + + @Override + public boolean contains(int key) { + return backing.contains(key); + } + + @Override + public int[] toIntArray() { + return backing.stream().mapToInt(i -> i).toArray(); + } + + @Override + public int[] toIntArray(int[] a) { + if (a.length >= size()) { + return null; + } else { + return toIntArray(); + } + } + + @Override + public int[] toArray(int[] a) { + return toIntArray(a); + } + + @Override + public boolean addAll(IntCollection c) { + return backing.addAll(c); + } + + @Override + public boolean containsAll(IntCollection c) { + return backing.containsAll(c); + } + + @Override + public boolean removeAll(IntCollection c) { + return backing.removeAll(c); + } + + @Override + public boolean retainAll(IntCollection c) { + return backing.retainAll(c); + } + + @Override + public int size() { + return backing.size(); + } + + @Override + public boolean isEmpty() { + return backing.isEmpty(); + } + + @Override + public Object[] toArray() { + return backing.toArray(); + } + + @Override + public T[] toArray(T[] a) { + return backing.toArray(a); + } + + @Override + public boolean containsAll(Collection c) { + return backing.containsAll(c); + } + + @Override + public boolean addAll(Collection c) { + return backing.addAll(c); + } + + @Override + public boolean removeAll(Collection c) { + return backing.removeAll(c); + } + + @Override + public boolean retainAll(Collection c) { + return backing.retainAll(c); + } + + @Override + public void clear() { + backing.clear(); + } + + @Override + public IntIterator iterator() { + return new WrappingIntIterator(backing.iterator()); + } + + @Override + public boolean remove(int k) { + return backing.remove(k); + } + + } + + public static LongSet wrapLongSet(Set longset) { + return new WrappingLongSet(longset); + } + + public static class WrappingLongSet implements LongSet { + + Set backing; + + public WrappingLongSet(Set backing) { + this.backing = backing; + } + + @Override + public boolean add(long key) { + return backing.add(key); + } + + @Override + public boolean contains(long key) { + return backing.contains(key); + } + + @Override + public long[] toLongArray() { + return backing.stream().mapToLong(i -> i).toArray(); + } + + @Override + public long[] toLongArray(long[] a) { + if (a.length >= size()) { + return null; + } else { + return toLongArray(); + } + } + + @Override + public long[] toArray(long[] a) { + return toLongArray(a); + } + + @Override + public boolean addAll(LongCollection c) { + return backing.addAll(c); + } + + @Override + public boolean containsAll(LongCollection c) { + return backing.containsAll(c); + } + + @Override + public boolean removeAll(LongCollection c) { + return backing.removeAll(c); + } + + @Override + public boolean retainAll(LongCollection c) { + return backing.retainAll(c); + } + + @Override + public int size() { + return backing.size(); + } + + @Override + public boolean isEmpty() { + return backing.isEmpty(); + } + + @Override + public Object[] toArray() { + return backing.toArray(); + } + + @Override + public T[] toArray(T[] a) { + return backing.toArray(a); + } + + @Override + public boolean containsAll(Collection c) { + return backing.containsAll(c); + } + + @Override + public boolean addAll(Collection c) { + return backing.addAll(c); + } + + @Override + public boolean removeAll(Collection c) { + return backing.removeAll(c); + } + + @Override + public boolean retainAll(Collection c) { + return backing.retainAll(c); + } + + @Override + public void clear() { + backing.clear(); + } + + @Override + public LongIterator iterator() { + return new WrappingLongIterator(backing.iterator()); + } + + @Override + public boolean remove(long k) { + return backing.remove(k); + } + + } + + public static LongSortedSet wrapLongSortedSet(Set longset) { + return new WrappingLongSortedSet(longset); + } + + public static class WrappingLongSortedSet implements LongSortedSet { + + Set backing; + + public WrappingLongSortedSet(Set backing) { + this.backing = backing; + } + + @Override + public boolean add(long key) { + return backing.add(key); + } + + @Override + public boolean contains(long key) { + return backing.contains(key); + } + + @Override + public long[] toLongArray() { + return backing.stream().mapToLong(i -> i).toArray(); + } + + @Override + public long[] toLongArray(long[] a) { + if (a.length >= size()) { + return null; + } else { + return toLongArray(); + } + } + + @Override + public long[] toArray(long[] a) { + return toLongArray(a); + } + + @Override + public boolean addAll(LongCollection c) { + return backing.addAll(c); + } + + @Override + public boolean containsAll(LongCollection c) { + return backing.containsAll(c); + } + + @Override + public boolean removeAll(LongCollection c) { + return backing.removeAll(c); + } + + @Override + public boolean retainAll(LongCollection c) { + return backing.retainAll(c); + } + + @Override + public int size() { + return backing.size(); + } + + @Override + public boolean isEmpty() { + return backing.isEmpty(); + } + + @Override + public Object[] toArray() { + return backing.toArray(); + } + + @Override + public T[] toArray(T[] a) { + return backing.toArray(a); + } + + @Override + public boolean containsAll(Collection c) { + return backing.containsAll(c); + } + + @Override + public boolean addAll(Collection c) { + return backing.addAll(c); + } + + @Override + public boolean removeAll(Collection c) { + return backing.removeAll(c); + } + + @Override + public boolean retainAll(Collection c) { + return backing.retainAll(c); + } + + @Override + public void clear() { + backing.clear(); + } + + @Override + public boolean remove(long k) { + return backing.remove(k); + } + + @Override + public LongBidirectionalIterator iterator(long fromElement) { + throw new UnsupportedOperationException(); + //return FastUtilHackUtil.wrap(new LinkedList(backing).iterator()); + } + + @Override + public LongBidirectionalIterator iterator() { + return FastUtilHackUtil.wrap(new LinkedList(backing).iterator()); + } + + @Override + public LongSortedSet subSet(long fromElement, long toElement) { + throw new UnsupportedOperationException(); + } + + @Override + public LongSortedSet headSet(long toElement) { + throw new UnsupportedOperationException(); + } + + @Override + public LongSortedSet tailSet(long fromElement) { + throw new UnsupportedOperationException(); + } + + @Override + public LongComparator comparator() { + return null; + } + + @Override + public long firstLong() { + return backing.stream().findAny().get(); + } + + @Override + public long lastLong() { + return backing.stream().findAny().get(); + } + + } + + public static IntSet wrapIntSet(Set intset) { + return new WrappingIntSet(intset); + } + + public static class WrappingObjectCollection implements ObjectCollection { + + Collection backing; + + public WrappingObjectCollection(Collection backing) { + this.backing = backing; + } + + @Override + public int size() { + return backing.size(); + } + + @Override + public boolean isEmpty() { + return backing.isEmpty(); + } + + @Override + public boolean contains(Object o) { + return backing.contains(o); + } + + @Override + public Object[] toArray() { + return backing.toArray(); + } + + @Override + public T[] toArray(T[] a) { + return backing.toArray(a); + } + + @Override + public boolean add(V e) { + return backing.add(e); + } + + @Override + public boolean remove(Object o) { + return backing.remove(o); + } + + @Override + public boolean containsAll(Collection c) { + return backing.containsAll(c); + } + + @Override + public boolean addAll(Collection c) { + return backing.addAll(c); + } + + @Override + public boolean removeAll(Collection c) { + return backing.removeAll(c); + } + + @Override + public boolean retainAll(Collection c) { + return backing.retainAll(c); + } + + @Override + public void clear() { + backing.clear(); + } + + @Override + public ObjectIterator iterator() { + return FastUtilHackUtil.itrWrap(backing); + } + + } + + public static ObjectCollection wrap(Collection c) { + return new WrappingObjectCollection(c); + } + + public static class WrappingByteCollection implements ByteCollection { + + Collection backing; + + public WrappingByteCollection(Collection backing) { + this.backing = backing; + } + + @Override + public int size() { + return backing.size(); + } + + @Override + public boolean isEmpty() { + return backing.isEmpty(); + } + + @Override + public boolean contains(byte o) { + return backing.contains(o); + } + + @Override + public Object[] toArray() { + return backing.toArray(); + } + + @Override + public T[] toArray(T[] a) { + return backing.toArray(a); + } + + @Override + public boolean add(byte e) { + return backing.add(e); + } + + @Override + public boolean remove(Object o) { + return backing.remove(o); + } + + @Override + public boolean containsAll(Collection c) { + return backing.containsAll(c); + } + + @Override + public boolean addAll(Collection c) { + return backing.addAll(c); + } + + @Override + public boolean removeAll(Collection c) { + return backing.removeAll(c); + } + + @Override + public boolean retainAll(Collection c) { + return backing.retainAll(c); + } + + @Override + public void clear() { + backing.clear(); + } + + @Override + public ByteIterator iterator() { + return FastUtilHackUtil.itrByteWrap(backing); + } + + @Override + public boolean rem(byte key) { + return this.remove(key); + } + + @Override + public byte[] toByteArray() { + return null; + } + + @Override + public byte[] toByteArray(byte[] a) { + return toArray(a); + } + + @Override + public byte[] toArray(byte[] a) { + return ArrayUtils.toPrimitive(backing.toArray(new Byte[0])); + } + + @Override + public boolean addAll(ByteCollection c) { + return addAll((Collection) c); + } + + @Override + public boolean containsAll(ByteCollection c) { + return containsAll((Collection) c); + } + + @Override + public boolean removeAll(ByteCollection c) { + return removeAll((Collection) c); + } + + @Override + public boolean retainAll(ByteCollection c) { + return retainAll((Collection) c); + } + + } + + public static ByteCollection wrapBytes(Collection c) { + return new WrappingByteCollection(c); + } + + public static class WrappingIntCollection implements IntCollection { + + Collection backing; + + public WrappingIntCollection(Collection backing) { + this.backing = backing; + } + + @Override + public int size() { + return backing.size(); + } + + @Override + public boolean isEmpty() { + return backing.isEmpty(); + } + + @Override + public boolean contains(int o) { + return backing.contains(o); + } + + @Override + public Object[] toArray() { + return backing.toArray(); + } + + @Override + public T[] toArray(T[] a) { + return backing.toArray(a); + } + + @Override + public boolean add(int e) { + return backing.add(e); + } + + @Override + public boolean remove(Object o) { + return backing.remove(o); + } + + @Override + public boolean containsAll(Collection c) { + return backing.containsAll(c); + } + + @Override + public boolean addAll(Collection c) { + return backing.addAll(c); + } + + @Override + public boolean removeAll(Collection c) { + return backing.removeAll(c); + } + + @Override + public boolean retainAll(Collection c) { + return backing.retainAll(c); + } + + @Override + public void clear() { + backing.clear(); + } + + @Override + public IntIterator iterator() { + return FastUtilHackUtil.itrIntWrap(backing); + } + + @Override + public boolean rem(int key) { + return this.remove(key); + } + + @Override + public int[] toIntArray() { + return null; + } + + @Override + public int[] toIntArray(int[] a) { + return toArray(a); + } + + @Override + public int[] toArray(int[] a) { + return ArrayUtils.toPrimitive(backing.toArray(new Integer[0])); + } + + @Override + public boolean addAll(IntCollection c) { + return addAll((Collection) c); + } + + @Override + public boolean containsAll(IntCollection c) { + return containsAll((Collection) c); + } + + @Override + public boolean removeAll(IntCollection c) { + return removeAll((Collection) c); + } + + @Override + public boolean retainAll(IntCollection c) { + return retainAll((Collection) c); + } + + } + + public static IntCollection wrapInts(Collection c) { + return new WrappingIntCollection(c); + } + + public static class WrappingLongCollection implements LongCollection { + + Collection backing; + + public WrappingLongCollection(Collection backing) { + this.backing = backing; + } + + @Override + public int size() { + return backing.size(); + } + + @Override + public boolean isEmpty() { + return backing.isEmpty(); + } + + @Override + public boolean contains(long o) { + return backing.contains(o); + } + + @Override + public Object[] toArray() { + return backing.toArray(); + } + + @Override + public T[] toArray(T[] a) { + return backing.toArray(a); + } + + @Override + public boolean add(long e) { + return backing.add(e); + } + + @Override + public boolean remove(Object o) { + return backing.remove(o); + } + + @Override + public boolean containsAll(Collection c) { + return backing.containsAll(c); + } + + @Override + public boolean addAll(Collection c) { + return backing.addAll(c); + } + + @Override + public boolean removeAll(Collection c) { + return backing.removeAll(c); + } + + @Override + public boolean retainAll(Collection c) { + return backing.retainAll(c); + } + + @Override + public void clear() { + backing.clear(); + } + + @Override + public LongIterator iterator() { + return FastUtilHackUtil.itrLongWrap(backing); + } + + @Override + public boolean rem(long key) { + return this.remove(key); + } + + @Override + public long[] toLongArray() { + return null; + } + + @Override + public long[] toLongArray(long[] a) { + return toArray(a); + } + + @Override + public long[] toArray(long[] a) { + return ArrayUtils.toPrimitive(backing.toArray(new Long[0])); + } + + @Override + public boolean addAll(LongCollection c) { + return addAll((Collection) c); + } + + @Override + public boolean containsAll(LongCollection c) { + return containsAll((Collection) c); + } + + @Override + public boolean removeAll(LongCollection c) { + return removeAll((Collection) c); + } + + @Override + public boolean retainAll(LongCollection c) { + return retainAll((Collection) c); + } + + } + + public static LongCollection wrapLongs(Collection c) { + return new WrappingLongCollection(c); + } + + + public static class WrappingLongListIterator implements LongListIterator { + + ListIterator backing; + + public WrappingLongListIterator(ListIterator backing) { + this.backing = backing; + } + + @Override + public long previousLong() { + return backing.previous(); + } + + @Override + public long nextLong() { + return backing.next(); + } + + @Override + public boolean hasNext() { + return backing.hasNext(); + } + + @Override + public boolean hasPrevious() { + return backing.hasPrevious(); + } + + @Override + public int nextIndex() { + return backing.nextIndex(); + } + + @Override + public int previousIndex() { + return backing.previousIndex(); + } + + @Override + public void add(long k) { + backing.add(k); + } + + @Override + public void remove() { + backing.remove(); + } + + @Override + public void set(long k) { + backing.set(k); + } + } + + public static class SlimWrappingLongListIterator implements LongListIterator { + + Iterator backing; + + public SlimWrappingLongListIterator(Iterator backing) { + this.backing = backing; + } + + @Override + public long previousLong() { + throw new IllegalStateException(); + } + + @Override + public long nextLong() { + return backing.next(); + } + + @Override + public boolean hasNext() { + return backing.hasNext(); + } + + @Override + public boolean hasPrevious() { + throw new IllegalStateException(); + } + + @Override + public int nextIndex() { + throw new IllegalStateException(); + } + + @Override + public int previousIndex() { + throw new IllegalStateException(); + } + + @Override + public void add(long k) { + throw new IllegalStateException(); + } + + @Override + public void remove() { + backing.remove(); + } + + @Override + public void set(long k) { + throw new IllegalStateException(); + } + } + + public static LongListIterator wrap(ListIterator c) { + return new WrappingLongListIterator(c); + } + + public static LongListIterator wrap(Iterator c) { + return new SlimWrappingLongListIterator(c); + } + + public static class WrappingByteIterator implements ByteIterator { + + Iterator parent; + + public WrappingByteIterator(Iterator parent) { + this.parent = parent; + } + + @Override + public boolean hasNext() { + return parent.hasNext(); + } + + @Override + public Byte next() { + return parent.next(); + } + + @Override + public void remove() { + parent.remove(); + } + + @Override + public byte nextByte() { + return next(); + } + + } + + public static ByteIterator itrByteWrap(Iterator backing) { + return new WrappingByteIterator(backing); + } + + public static ByteIterator itrByteWrap(Iterable backing) { + return new WrappingByteIterator(backing.iterator()); + } + + public static IntIterator itrIntWrap(Iterator backing) { + return new WrappingIntIterator(backing); + } + + public static IntIterator itrIntWrap(Iterable backing) { + return new WrappingIntIterator(backing.iterator()); + } + + public static LongIterator itrLongWrap(Iterator backing) { + return new WrappingLongIterator(backing); + } + + public static LongIterator itrLongWrap(Iterable backing) { + return new WrappingLongIterator(backing.iterator()); + } + + public static ShortIterator itrShortWrap(Iterator backing) { + return new WrappingShortIterator(backing); + } + + public static ShortIterator itrShortWrap(Iterable backing) { + return new WrappingShortIterator(backing.iterator()); + } + + public static class WrapperObjectIterator implements ObjectIterator { + + Iterator parent; + + public WrapperObjectIterator(Iterator parent) { + this.parent = parent; + } + + @Override + public boolean hasNext() { + return parent.hasNext(); + } + + @Override + public T next() { + return parent.next(); + } + + @Override + public void remove() { + parent.remove(); + } + + } + + public static class IntWrapperEntry implements Entry { + + Map.Entry parent; + + public IntWrapperEntry(Map.Entry parent) { + this.parent = parent; + } + + @Override + public T getValue() { + return parent.getValue(); + } + + @Override + public T setValue(T value) { + return parent.setValue(value); + } + + @Override + public int getIntKey() { + return parent.getKey(); + } + + @Override + public Integer getKey() { + return parent.getKey(); + } + + } + + public static class Long2IntWrapperEntry implements Long2IntMap.Entry { + + Map.Entry parent; + + public Long2IntWrapperEntry(Map.Entry parent) { + this.parent = parent; + } + + @Override + public long getLongKey() { + return parent.getKey(); + } + + @Override + public int getIntValue() { + return parent.getValue(); + } + + @Override + public int setValue(int value) { + return parent.setValue(value); + } + + + } + + public static class WrapperIntEntryObjectIterator implements ObjectIterator> { + + Iterator> parent; + + public WrapperIntEntryObjectIterator(Iterator> parent) { + this.parent = parent; + } + + @Override + public boolean hasNext() { + return parent.hasNext(); + } + + @Override + public Entry next() { + Map.Entry val = parent.next(); + if (val == null) return null; + return new IntWrapperEntry(val); + } + + @Override + public void remove() { + parent.remove(); + } + + } + + public static ObjectIterator> intMapItrFake(Map in) { + return new WrapperIntEntryObjectIterator(in.entrySet().iterator()); + } + + public static ObjectIterator itrWrap(Iterator in) { + return new WrapperObjectIterator(in); + } + + public static ObjectIterator itrWrap(Iterable in) { + return new WrapperObjectIterator(in.iterator()); + } +} \ No newline at end of file diff --git a/src/main/java/net/himeki/mcmtfabric/parallelised/fastutil/Int2ObjectConcurrentHashMap.java b/src/main/java/net/himeki/mcmtfabric/parallelised/fastutil/Int2ObjectConcurrentHashMap.java new file mode 100644 index 0000000000000000000000000000000000000000..bb6c592fd34423fdd910feae83a058d288da537a --- /dev/null +++ b/src/main/java/net/himeki/mcmtfabric/parallelised/fastutil/Int2ObjectConcurrentHashMap.java @@ -0,0 +1,93 @@ +package net.himeki.mcmtfabric.parallelised.fastutil; + +import it.unimi.dsi.fastutil.ints.Int2ObjectMap; +import it.unimi.dsi.fastutil.ints.IntSet; +import it.unimi.dsi.fastutil.objects.ObjectCollection; +import it.unimi.dsi.fastutil.objects.ObjectSet; +import org.apache.commons.lang3.NotImplementedException; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +public class Int2ObjectConcurrentHashMap implements Int2ObjectMap { + + Map backing; + + public Int2ObjectConcurrentHashMap() { + backing = new ConcurrentHashMap(); + } + + @Override + public V get(int key) { + return backing.get(key); + } + + @Override + public boolean isEmpty() { + return backing.isEmpty(); + } + + @Override + public boolean containsValue(Object value) { + return backing.containsValue(value); + } + + @Override + public void putAll(Map m) { + backing.putAll(m); + } + + @Override + public int size() { + return backing.size(); + } + + @Override + public void defaultReturnValue(V rv) { + throw new NotImplementedException("MCMT - Not implemented"); + } + + @Override + public V defaultReturnValue() { + return null; + } + + @Override + public ObjectSet> int2ObjectEntrySet() { + return FastUtilHackUtil.entrySetIntWrap(backing); + } + + + @Override + public IntSet keySet() { + return FastUtilHackUtil.wrapIntSet(backing.keySet()); + } + + @Override + public ObjectCollection values() { + return FastUtilHackUtil.wrap(backing.values()); + } + + @Override + public boolean containsKey(int key) { + return backing.containsKey(key); + } + + @Override + public V put(int key, V value) { + return backing.put(key, value); + } + + @Override + public V put(Integer key, V value) { + return backing.put(key, value); + } + + @Override + public V remove(int key) { + return backing.remove(key); + } + + @Override + public void clear() { backing.clear(); } +} diff --git a/src/main/java/net/himeki/mcmtfabric/parallelised/fastutil/Long2ByteConcurrentHashMap.java b/src/main/java/net/himeki/mcmtfabric/parallelised/fastutil/Long2ByteConcurrentHashMap.java new file mode 100644 index 0000000000000000000000000000000000000000..e0fab16860e1be817fd10dbec684f295f2e291dd --- /dev/null +++ b/src/main/java/net/himeki/mcmtfabric/parallelised/fastutil/Long2ByteConcurrentHashMap.java @@ -0,0 +1,99 @@ +package net.himeki.mcmtfabric.parallelised.fastutil; + +import it.unimi.dsi.fastutil.bytes.ByteCollection; +import it.unimi.dsi.fastutil.longs.Long2ByteMap; +import it.unimi.dsi.fastutil.longs.LongSet; +import it.unimi.dsi.fastutil.objects.ObjectSet; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +public class Long2ByteConcurrentHashMap implements Long2ByteMap { + + Map backing; + byte defaultReturn = 0; + byte nullKey = 0; + + public Long2ByteConcurrentHashMap() { + backing = new ConcurrentHashMap<>(); + } + + public Long2ByteConcurrentHashMap(int initialCapacity, float loadFactor) { + backing = new ConcurrentHashMap<>(initialCapacity, loadFactor); + } + + @Override + public byte get(long key) { + Byte out = backing.get(key); + return out == null ? defaultReturn : out; + } + + @Override + public boolean isEmpty() { + return backing.isEmpty(); + } + + @Override + public boolean containsValue(byte value) { + return backing.containsValue(value); + } + + @Override + public void putAll(Map m) { + backing.putAll(m); + } + + @Override + public int size() { + return backing.size(); + } + + @Override + public void defaultReturnValue(byte rv) { + defaultReturn = rv; + } + + @Override + public byte defaultReturnValue() { + return defaultReturn; + } + + @Override + public ObjectSet long2ByteEntrySet() { + return FastUtilHackUtil.entrySetLongByteWrap(backing); + } + + @Override + public LongSet keySet() { + return FastUtilHackUtil.wrapLongSet(backing.keySet()); + } + + @Override + public ByteCollection values() { + return FastUtilHackUtil.wrapBytes(backing.values()); + } + + @Override + public boolean containsKey(long key) { + return backing.containsKey(key); + } + + @Override + public byte put(long key, byte value) { + return put((Long) key, (Byte) value); + } + + @Override + public Byte put(Long key, Byte value) { + Byte out = backing.put(key, value); + return out == null ? Byte.valueOf(defaultReturn) : out; + } + + @Override + public byte remove(long key) { + Byte out = backing.remove(key); + return out == null ? defaultReturn : out; + } + + +} diff --git a/src/main/java/net/himeki/mcmtfabric/parallelised/fastutil/Long2IntConcurrentHashMap.java b/src/main/java/net/himeki/mcmtfabric/parallelised/fastutil/Long2IntConcurrentHashMap.java new file mode 100644 index 0000000000000000000000000000000000000000..261f06a88021a95b6a0500444665547aeb4ae2c1 --- /dev/null +++ b/src/main/java/net/himeki/mcmtfabric/parallelised/fastutil/Long2IntConcurrentHashMap.java @@ -0,0 +1,74 @@ +package net.himeki.mcmtfabric.parallelised.fastutil; + +import it.unimi.dsi.fastutil.ints.IntCollection; +import it.unimi.dsi.fastutil.longs.Long2IntMap; +import it.unimi.dsi.fastutil.longs.LongSet; +import it.unimi.dsi.fastutil.objects.ObjectSet; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +public class Long2IntConcurrentHashMap implements Long2IntMap { + + public Map backing = new ConcurrentHashMap(); + int defaultRV = 0; + + @Override + public int get(long key) { + if (backing.containsKey(key)) { + return backing.get(key); + } else return defaultRV; + } + + @Override + public boolean isEmpty() { + return backing.isEmpty(); + } + + @Override + public void putAll(Map m) { + backing.putAll(m); + } + + @Override + public int size() { + return backing.size(); + } + + @Override + public void defaultReturnValue(int rv) { + defaultRV = rv; + } + + @Override + public int defaultReturnValue() { + return defaultRV; + } + + @Override + public ObjectSet long2IntEntrySet() { + return null; + } + + @Override + public LongSet keySet() { + return FastUtilHackUtil.wrapLongSet(backing.keySet()); + } + + @Override + public IntCollection values() { + return FastUtilHackUtil.wrapInts(backing.values()); + } + + @Override + public boolean containsKey(long key) { + return backing.containsKey(key); + } + + @Override + public boolean containsValue(int value) { + return backing.containsValue(value); + } + + +} diff --git a/src/main/java/net/himeki/mcmtfabric/parallelised/fastutil/Long2IntConcurrentNonLinkedOpenMap.java b/src/main/java/net/himeki/mcmtfabric/parallelised/fastutil/Long2IntConcurrentNonLinkedOpenMap.java new file mode 100644 index 0000000000000000000000000000000000000000..dc2342486318721d399c7c60a0a859befb4d1c9f --- /dev/null +++ b/src/main/java/net/himeki/mcmtfabric/parallelised/fastutil/Long2IntConcurrentNonLinkedOpenMap.java @@ -0,0 +1,375 @@ +package net.himeki.mcmtfabric.parallelised.fastutil; + +import it.unimi.dsi.fastutil.Hash; +import it.unimi.dsi.fastutil.ints.IntCollection; +import it.unimi.dsi.fastutil.longs.*; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +@SuppressWarnings("deprecation") +public class Long2IntConcurrentNonLinkedOpenMap extends Long2IntLinkedOpenHashMap { + + /** + * + */ + private static final long serialVersionUID = -2082212127278131631L; + + public Map backing = new ConcurrentHashMap(); + + public Long2IntConcurrentNonLinkedOpenMap(final int expected, final float f) { + + } + + /** + * Creates a new hash map with {@link Hash#DEFAULT_LOAD_FACTOR} as load factor. + * + * @param expected the expected number of elements in the hash map. + */ + public Long2IntConcurrentNonLinkedOpenMap(final int expected) { + } + + /** + * Creates a new hash map with initial expected + * {@link Hash#DEFAULT_INITIAL_SIZE} entries and + * {@link Hash#DEFAULT_LOAD_FACTOR} as load factor. + */ + public Long2IntConcurrentNonLinkedOpenMap() { + } + + /** + * Creates a new hash map copying a given one. + * + * @param m a {@link Map} to be copied into the new hash map. + * @param f the load factor. + */ + public Long2IntConcurrentNonLinkedOpenMap(final Map m, final float f) { + putAll(m); + } + + /** + * Creates a new hash map with {@link Hash#DEFAULT_LOAD_FACTOR} as load factor + * copying a given one. + * + * @param m a {@link Map} to be copied into the new hash map. + */ + public Long2IntConcurrentNonLinkedOpenMap(final Map m) { + this(m, DEFAULT_LOAD_FACTOR); + } + + /** + * Creates a new hash map copying a given type-specific one. + * + * @param m a type-specific map to be copied into the new hash map. + * @param f the load factor. + */ + public Long2IntConcurrentNonLinkedOpenMap(final Long2IntMap m, final float f) { + this(m.size(), f); + putAll(m); + } + + /** + * Creates a new hash map with {@link Hash#DEFAULT_LOAD_FACTOR} as load factor + * copying a given type-specific one. + * + * @param m a type-specific map to be copied into the new hash map. + */ + public Long2IntConcurrentNonLinkedOpenMap(final Long2IntMap m) { + this(m, DEFAULT_LOAD_FACTOR); + } + + /** + * Creates a new hash map using the elements of two parallel arrays. + * + * @param k the array of keys of the new hash map. + * @param v the array of corresponding values in the new hash map. + * @param f the load factor. + * @throws IllegalArgumentException if {@code k} and {@code v} have different + * lengths. + */ + public Long2IntConcurrentNonLinkedOpenMap(final long[] k, final int[] v, final float f) { + if (k.length != v.length) + throw new IllegalArgumentException( + "The key array and the value array have different lengths (" + k.length + " and " + v.length + ")"); + for (int i = 0; i < k.length; i++) + this.put(k[i], v[i]); + } + + /** + * Creates a new hash map with {@link Hash#DEFAULT_LOAD_FACTOR} as load factor + * using the elements of two parallel arrays. + * + * @param k the array of keys of the new hash map. + * @param v the array of corresponding values in the new hash map. + * @throws IllegalArgumentException if {@code k} and {@code v} have different + * lengths. + */ + public Long2IntConcurrentNonLinkedOpenMap(final long[] k, final int[] v) { + this(k, v, DEFAULT_LOAD_FACTOR); + } + + public void putAll(Map m) { + backing.putAll(m); + } + + public int put(final long k, final int v) { + Integer out = backing.put(k, v); + if (out == null) { + return defRetValue; + } + return out; + } + + public int addTo(final long k, final int incr) { + Integer out = backing.put(k, this.get(k)+incr); + if (out == null) { + return defRetValue; + } + return out; + } + + public int remove(final long k) { + Integer out = backing.remove(k); + if (out == null) { + return defRetValue; + } + return out; + } + + public int removeFirstInt() { + Integer out = this.remove(backing.keySet().stream().findAny().get()); + if (out == null) { + return defRetValue; + } + return out; + } + + public int removeLastInt() { + Integer out = this.remove(backing.keySet().stream().findAny().get()); + if (out == null) { + return defRetValue; + } + return out; + } + + + public int getAndMoveToFirst(final long k) { + Integer out = backing.get(k); + if (out == null) { + return defRetValue; + } + return out; + } + + public int getAndMoveToLast(final long k) { + Integer out = backing.get(k); + if (out == null) { + return defRetValue; + } + return out; + } + + public int putAndMoveToFirst(final long k, final int v) { + Integer out = backing.put(k, v); + if (out == null) { + return defRetValue; + } + return out; + } + + public int putAndMoveToLast(final long k, final int v) { + Integer out = backing.put(k, v); + if (out == null) { + return defRetValue; + } + return out; + } + + public int get(final long k) { + Integer out = backing.get(k); + if (out == null) { + return defRetValue; + } + return out; + } + + public boolean containsKey(final long k) { + return backing.containsKey(k); + } + + public boolean containsValue(final int v) { + return backing.containsValue(v); + } + + public int getOrDefault(final long k, final int defaultValue) { + Integer out = backing.getOrDefault(k, defaultValue); + if (out == null) { + return defRetValue; + } + return out; + } + + public int putIfAbsent(final long k, final int v) { + Integer out = backing.putIfAbsent(k, v); + if (out == null) { + return defRetValue; + } + return out; + } + + + public boolean remove(final long k, final int v) { + return backing.remove(k, v); + } + + + public boolean replace(final long k, final int oldValue, final int v) { + return backing.replace(k, oldValue, v); + } + + + public int replace(final long k, final int v) { + Integer out = backing.replace(k, v); + if (out == null) { + return defRetValue; + } + return out; + } + + + public int computeIfAbsent(final long k, final java.util.function.LongToIntFunction mappingFunction) { + Integer out = backing.computeIfAbsent(k, (l) -> mappingFunction.applyAsInt(l)); + if (out == null) { + return defRetValue; + } + return out; + } + + + public int computeIfAbsentNullable(final long k, + final java.util.function.LongFunction mappingFunction) { + Integer out = backing.computeIfAbsent(k, (l) -> mappingFunction.apply(l)); + if (out == null) { + return defRetValue; + } + return out; + } + + + public int computeIfPresent(final long k, + final java.util.function.BiFunction remappingFunction) { + if (this.containsKey(k)) { + Integer out = backing.put(k, remappingFunction.apply(k, backing.get(k))); + if (out == null) { + return defRetValue; + } + return out; + } + return defaultReturnValue(); + + } + + @Override + public int compute(final long k, + final java.util.function.BiFunction remappingFunction) { + Integer out = backing.compute(k, remappingFunction); + if (out == null) { + return defRetValue; + } + return out; + } + + @Override + public int merge(final long k, final int v, + final java.util.function.BiFunction remappingFunction) { + Integer out = backing.merge(k, v, remappingFunction); + if (out == null) { + return defRetValue; + } + return out; + } + + @Override + public void clear() { + backing.clear(); + } + + @Override + public int size() { + return backing.size(); + } + + @Override + public boolean isEmpty() { + return backing.isEmpty(); + } + + @Override + public long firstLongKey() { + return backing.keySet().stream().findAny().get(); + } + + @Override + public long lastLongKey() { + return backing.keySet().stream().findAny().get(); + } + + @Override + public Long2IntSortedMap tailMap(long from) { + throw new UnsupportedOperationException(); + } + + @Override + public Long2IntSortedMap headMap(long to) { + throw new UnsupportedOperationException(); + } + + @Override + public Long2IntSortedMap subMap(long from, long to) { + throw new UnsupportedOperationException(); + } + + @Override + public LongComparator comparator() { + return null; + } + + + @Override + public FastSortedEntrySet long2IntEntrySet() { + //TODO implement + throw new UnsupportedOperationException(); + } + + @Override + public LongSortedSet keySet() { + return FastUtilHackUtil.wrapLongSortedSet(backing.keySet()); + } + + + @Override + public IntCollection values() { + return FastUtilHackUtil.wrapInts(backing.values()); + } + + public boolean trim() { + return true; + } + + public boolean trim(final int n) { + return true; + } + + + @Override + public Long2IntConcurrentNonLinkedOpenMap clone() { + return new Long2IntConcurrentNonLinkedOpenMap(backing); + } + + @Override + public int hashCode() { + return backing.hashCode(); + } + + +} diff --git a/src/main/java/net/himeki/mcmtfabric/parallelised/fastutil/Long2LongConcurrentHashMap.java b/src/main/java/net/himeki/mcmtfabric/parallelised/fastutil/Long2LongConcurrentHashMap.java new file mode 100644 index 0000000000000000000000000000000000000000..3205d30a03f99caf7dfa05237b2bc31182b2db20 --- /dev/null +++ b/src/main/java/net/himeki/mcmtfabric/parallelised/fastutil/Long2LongConcurrentHashMap.java @@ -0,0 +1,97 @@ +package net.himeki.mcmtfabric.parallelised.fastutil; + +import it.unimi.dsi.fastutil.longs.Long2LongMap; +import it.unimi.dsi.fastutil.longs.LongCollection; +import it.unimi.dsi.fastutil.longs.LongSet; +import it.unimi.dsi.fastutil.objects.ObjectSet; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + + +public class Long2LongConcurrentHashMap implements Long2LongMap { + + public Map backing = new ConcurrentHashMap(); + long defaultRV = 0; + + public Long2LongConcurrentHashMap(long defaultRV) { + this.defaultRV = defaultRV; + } + + @Override + public long get(long key) { + if (backing.containsKey(key)) { + return backing.get(key); + } else return defaultRV; + } + + @Override + public boolean isEmpty() { + return backing.isEmpty(); + } + + @Override + public long put(final long key, final long val) { + backing.put(key,val); + return val; + } + + @Override + public Long put(final Long key, final Long val) { + backing.put(key,val); + return val; + } + + @Override + public long remove(final long key) { + return backing.remove(key); + } + + @Override + public void putAll(Map m) { + backing.putAll(m); + } + + @Override + public int size() { + return backing.size(); + } + + @Override + public void defaultReturnValue(long rv) { + defaultRV = rv; + } + + @Override + public long defaultReturnValue() { + return defaultRV; + } + + @Override + public ObjectSet long2LongEntrySet() { + return FastUtilHackUtil.entrySetLongLongWrap(backing); + } + + + @Override + public LongSet keySet() { + return FastUtilHackUtil.wrapLongSet(backing.keySet()); + } + + @Override + public LongCollection values() { + return FastUtilHackUtil.wrapLongs(backing.values()); + } + + @Override + public boolean containsKey(long key) { + return backing.containsKey(key); + } + + @Override + public boolean containsValue(long value) { + return backing.containsValue(value); + } + + +} \ No newline at end of file diff --git a/src/main/java/net/himeki/mcmtfabric/parallelised/fastutil/Long2ObjectConcurrentHashMap.java b/src/main/java/net/himeki/mcmtfabric/parallelised/fastutil/Long2ObjectConcurrentHashMap.java new file mode 100644 index 0000000000000000000000000000000000000000..a5ed71564d4c9a986f77cbc0397130aa38f97a91 --- /dev/null +++ b/src/main/java/net/himeki/mcmtfabric/parallelised/fastutil/Long2ObjectConcurrentHashMap.java @@ -0,0 +1,93 @@ +package net.himeki.mcmtfabric.parallelised.fastutil; + +import it.unimi.dsi.fastutil.longs.Long2ObjectMap; +import it.unimi.dsi.fastutil.longs.LongSet; +import it.unimi.dsi.fastutil.objects.ObjectCollection; +import it.unimi.dsi.fastutil.objects.ObjectSet; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +public class Long2ObjectConcurrentHashMap implements Long2ObjectMap { + + Map backing; + V defaultReturn = null; + + public Long2ObjectConcurrentHashMap() { + backing = new ConcurrentHashMap(); + } + + @Override + public V get(long key) { + V out = backing.get(key); + return (out == null && !backing.containsKey(key)) ? defaultReturn : out; + } + + @Override + public boolean isEmpty() { + return backing.isEmpty(); + } + + @Override + public boolean containsValue(Object value) { + return backing.containsValue(value); + } + + @Override + public void putAll(Map m) { + backing.putAll(m); + } + + @Override + public int size() { + return backing.size(); + } + + @Override + public void defaultReturnValue(V rv) { + defaultReturn = rv; + } + + @Override + public V defaultReturnValue() { + return defaultReturn; + } + + @Override + public ObjectSet> long2ObjectEntrySet() { + return FastUtilHackUtil.entrySetLongWrap(backing); + } + + + @Override + public LongSet keySet() { + return FastUtilHackUtil.wrapLongSet(backing.keySet()); + } + + @Override + public ObjectCollection values() { + return FastUtilHackUtil.wrap(backing.values()); + } + + @Override + public boolean containsKey(long key) { + return backing.containsKey(key); + } + + @Override + public V put(long key, V value) { + return put((Long)key, value); + } + + @Override + public V put(Long key, V value) { + V out = backing.put(key, value); + return (out == null && !backing.containsKey(key)) ? defaultReturn : backing.put(key, value); + } + + @Override + public V remove(long key) { + V out = backing.remove(key); + return (out == null && !backing.containsKey(key)) ? defaultReturn : out; + } +} diff --git a/src/main/java/net/himeki/mcmtfabric/parallelised/fastutil/Long2ObjectOpenConcurrentHashMap.java b/src/main/java/net/himeki/mcmtfabric/parallelised/fastutil/Long2ObjectOpenConcurrentHashMap.java new file mode 100644 index 0000000000000000000000000000000000000000..a7d6be048ab3b8bd38231fce16eca0ac78e24690 --- /dev/null +++ b/src/main/java/net/himeki/mcmtfabric/parallelised/fastutil/Long2ObjectOpenConcurrentHashMap.java @@ -0,0 +1,233 @@ +package net.himeki.mcmtfabric.parallelised.fastutil; + +import it.unimi.dsi.fastutil.longs.Long2ObjectFunction; +import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; +import it.unimi.dsi.fastutil.longs.LongSet; +import it.unimi.dsi.fastutil.objects.ObjectCollection; +import it.unimi.dsi.fastutil.objects.ObjectSet; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.function.Function; + +public class Long2ObjectOpenConcurrentHashMap extends Long2ObjectOpenHashMap { + + /** + * + */ + private static final long serialVersionUID = -121514116954680057L; + + Map backing; + V defaultReturn = null; + + public Long2ObjectOpenConcurrentHashMap() { + backing = new ConcurrentHashMap(); + } + + @Override + public V get(long key) { + V out = backing.get(key); + return (out == null && !backing.containsKey(key)) ? defaultReturn : out; + } + + @Override + public V get(Object key) { + V out = backing.get(key); + return (out == null && !backing.containsKey(key)) ? defaultReturn : out; + } + + @Override + public boolean isEmpty() { + return backing.isEmpty(); + } + + @Override + public boolean containsValue(Object value) { + return backing.containsValue(value); + } + + @Override + public void putAll(Map m) { + backing.putAll(m); + } + + @Override + public int size() { + return backing.size(); + } + + @Override + public void defaultReturnValue(V rv) { + defaultReturn = rv; + } + + @Override + public V defaultReturnValue() { + return defaultReturn; + } + + @Override + public FastEntrySet long2ObjectEntrySet() { + return FastUtilHackUtil.entrySetLongWrapFast(backing); + } + + + @Override + public LongSet keySet() { + return FastUtilHackUtil.wrapLongSet(backing.keySet()); + } + + @Override + public ObjectCollection values() { + return FastUtilHackUtil.wrap(backing.values()); + } + + @Override + public boolean containsKey(long key) { + return backing.containsKey(key); + } + + @Override + public V put(long key, V value) { + return put((Long)key, value); + } + + @Override + public V put(Long key, V value) { + V out = backing.put(key, value); + return (out == null && !backing.containsKey(key)) ? defaultReturn : backing.put(key, value); + } + + @Override + public V remove(long key) { + V out = backing.remove(key); + return (out == null && !backing.containsKey(key)) ? defaultReturn : out; + } + + @Override + public boolean trim() { return true; } + + @Override + public boolean trim(final int n) { return true; } + + @Override + public boolean replace(final long k, final V oldValue, final V v) { + return backing.replace(k, oldValue, v); + } + + @Override + public V replace(final long k, final V v) { + return backing.replace(k, v); + } + + @Override + public boolean replace(final Long k, final V oldValue, final V v) { + return backing.replace(k, oldValue, v); + } + + @Override + public V replace(final Long k, final V v) { + return backing.replace(k, v); + } + + @Override + public boolean remove(final long k, final Object v) { + return backing.remove(k, v); + } + + @Override + public V putIfAbsent(final long k, final V v) { + return backing.putIfAbsent(k, v); + } + + @Override + public V putIfAbsent(final Long k, final V v) { + return backing.putIfAbsent(k, v); + } + + @Override + public V merge(final long k, final V v, final java.util.function.BiFunction remappingFunction) { + return backing.merge(k, v, remappingFunction); + } + + @Override + public V merge(Long k, final V v, final java.util.function.BiFunction remappingFunction) { + return backing.merge(k, v, remappingFunction); + } + + @Override + public int hashCode() { + return backing.hashCode(); + } + + @Override + public V getOrDefault(final long k, final V defaultValue) { + return backing.getOrDefault(k, defaultValue); + } + + @Override + public V getOrDefault(Object k, final V defaultValue) { + return backing.getOrDefault(k, defaultValue); + } + + @Override + public V computeIfPresent(final long k, final java.util.function.BiFunction remappingFunction) { + return backing.computeIfPresent(k, remappingFunction); + } + + @Override + public V computeIfPresent(final Long k, final java.util.function.BiFunction remappingFunction) { + return backing.computeIfPresent(k, remappingFunction); + } + + @Override + public V computeIfAbsent(final long k, final java.util.function.LongFunction mappingFunction) { + return backing.computeIfAbsent(k, (llong) -> mappingFunction.apply(llong)); + } + + public V computeIfAbsent(final Long k, final java.util.function.LongFunction mappingFunction) { + return backing.computeIfAbsent(k, (llong) -> mappingFunction.apply(llong)); + } + + @Override + public V computeIfAbsentPartial(final long key, final Long2ObjectFunction mappingFunction) { + if (!mappingFunction.containsKey(key)) + return defaultReturn; + return backing.computeIfAbsent(key, (llong) -> mappingFunction.apply(llong)); + } + + @Override + public V compute(final long k, final java.util.function.BiFunction remappingFunction) { + return backing.compute(k, remappingFunction); + } + + @Override + public V compute(final Long k, final java.util.function.BiFunction remappingFunction) { + return backing.compute(k, remappingFunction); + } + + @Override + public Long2ObjectOpenHashMap clone() { + throw new IllegalArgumentException(); + } + + public void clear() { + backing.clear(); + } + + @Override + public ObjectSet> entrySet() { + return new FastUtilHackUtil.ConvertingObjectSet, Map.Entry>(backing.entrySet(), Function.identity(), Function.identity()); + } + + @Override + public V remove(Object key) { + return backing.remove(key); + } + + @Override + public boolean remove(Object key, Object value) { + return backing.remove(key, value); + } + +} \ No newline at end of file diff --git a/src/main/java/net/himeki/mcmtfabric/parallelised/fastutil/sync/SyncLongLinkedOpenHashSet.java b/src/main/java/net/himeki/mcmtfabric/parallelised/fastutil/sync/SyncLongLinkedOpenHashSet.java new file mode 100644 index 0000000000000000000000000000000000000000..1d65e9575389a170e8b8465b1221a6e319749eb1 --- /dev/null +++ b/src/main/java/net/himeki/mcmtfabric/parallelised/fastutil/sync/SyncLongLinkedOpenHashSet.java @@ -0,0 +1,190 @@ +package net.himeki.mcmtfabric.parallelised.fastutil.sync; + +import it.unimi.dsi.fastutil.longs.*; + +import java.util.Collection; +import java.util.Iterator; + +public class SyncLongLinkedOpenHashSet extends LongLinkedOpenHashSet { + + private static final long serialVersionUID = -5532128240738069111L; + + public SyncLongLinkedOpenHashSet() { + super(); + } + + public SyncLongLinkedOpenHashSet(final int initial) { + super(initial); + } + + public SyncLongLinkedOpenHashSet(final int initial, final float dnc) { + this(initial); + } + + public SyncLongLinkedOpenHashSet(final LongCollection c) { + this(c.size()); + addAll(c); + } + + public SyncLongLinkedOpenHashSet(final LongCollection c, final float f) { + this(c.size(), f); + addAll(c); + } + + public SyncLongLinkedOpenHashSet(final LongIterator i, final float f) { + this(16, f); + while (i.hasNext()) + add(i.nextLong()); + } + + public SyncLongLinkedOpenHashSet(final LongIterator i) { + this(i, -1); + } + + public SyncLongLinkedOpenHashSet(final Iterator i, final float f) { + this(LongIterators.asLongIterator(i), f); + } + + public SyncLongLinkedOpenHashSet(final Iterator i) { + this(LongIterators.asLongIterator(i)); + } + + public SyncLongLinkedOpenHashSet(final long[] a, final int offset, final int length, final float f) { + this(length < 0 ? 0 : length, f); + LongArrays.ensureOffsetLength(a, offset, length); + for (int i = 0; i < length; i++) + add(a[offset + i]); + } + + public SyncLongLinkedOpenHashSet(final long[] a, final int offset, final int length) { + this(a, offset, length, DEFAULT_LOAD_FACTOR); + } + + public SyncLongLinkedOpenHashSet(final long[] a, final float f) { + this(a, 0, a.length, f); + } + + public SyncLongLinkedOpenHashSet(final long[] a) { + this(a, -1); + } + + @Override + public synchronized boolean add(final long k) { + return super.add(k); + } + + @Override + public synchronized boolean addAll(LongCollection c) { + return super.addAll(c); + } + + @Override + public synchronized boolean addAll(Collection c) { + return super.addAll(c); + } + + @Override + public synchronized boolean addAndMoveToFirst(final long k) { + return super.addAndMoveToFirst(k); + } + + @Override + public synchronized boolean addAndMoveToLast(final long k) { + return super.addAndMoveToFirst(k); + } + + @Override + public synchronized void clear() { + super.clear(); + } + + @Override + public synchronized LongLinkedOpenHashSet clone() { + return new SyncLongLinkedOpenHashSet(this); + } + + @Override + public synchronized LongComparator comparator() { + return super.comparator(); + } + + @Override + public synchronized boolean contains(final long k) { + return super.contains(k); + } + + @Override + public synchronized long firstLong() { + return super.firstLong(); + } + + @Override + public synchronized int hashCode() { + return super.hashCode(); + } + + @Override + public synchronized LongSortedSet headSet(long to) { + return super.headSet(to); + } + + @Override + public synchronized boolean isEmpty() { + return super.isEmpty(); + } + + @Override + public synchronized LongListIterator iterator() { + return super.iterator(); + } + + @Override + public synchronized LongListIterator iterator(long from) { + return super.iterator(from); + } + + @Override + public synchronized long lastLong() { + return super.lastLong(); + } + + @Override + public synchronized boolean remove(final long k) { + return super.remove(k); + } + + @Override + public synchronized long removeFirstLong() { + return super.removeFirstLong(); + } + + @Override + public synchronized long removeLastLong() { + return super.removeLastLong(); + } + + @Override + public synchronized int size() { + return super.size(); + } + + @Override + public synchronized LongSortedSet subSet(long from, long to) { + return super.subSet(from, to); + } + + @Override + public synchronized LongSortedSet tailSet(long from) { + return super.tailSet(from); + } + + @Override + public synchronized boolean trim() { + return super.trim(); + } + + @Override + public synchronized boolean trim(final int n) { + return super.trim(n); + } +}