Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- public class CombinedQueue<T> implements Queue<T> // WIP
- {
- final Collection<Queue<T>> memberQueues;
- final Lambda<T, Comparable> keyGetter;
- public T get(boolean remove)
- {
- // This algorithm works. That's not to say it's ideal. It's contrived, and an obvious workaround for maintaining
- // thread safety. If you happen to see this comment and know of a better algorithm for grabbing the next value
- // from a memberqueue in order decided by keyGetter while maintaining thread-safety, tell me <3
- // Uses a lambda to derive a comparable rather than a comparator as using a comparator removes the ability to
- // check whether the variable within the next value that's being measured is the same, which may happen where
- // the compared value is changed in a way that still results in the value being next in the queue it's in.
- // Work on a copy of memberQueues
- List<Queue<T>> memberQueuesCopy = getMemberQueuesCopyAsList();
- Queue<T> nextQueue = null;
- T nextValue = null;
- Comparable nextValueComparable = null;
- // Run through all member queues, filling those variables with the variables corresponding to the queue with the
- // lowest next comparable derived via keyGetter.
- // Establish a queue has the next value by iterating through the rest of the list before returning to it, and if
- // it still has the same values (that is, hasn't been modified in a way that affects its order in this queue)
- // after having compared the old values against the rest of the collection, return it as the next value.
- // null values always come last.
- for(int i = 0; i < 100; i++) // 100-loop threshhold
- {
- boolean populatedQueueFound = false;
- for(Queue<T> j : memberQueuesCopy)
- {
- if(j != null)
- {
- synchronized(j)
- {
- if(!j.isEmpty())
- {
- populatedQueueFound = true;
- T jValue = j.peek();
- if(jValue == null && nextQueue == null) // If there is no next queue, use this one.
- nextQueue = j;
- else if(jValue != null)
- {
- Comparable jValueComparable = keyGetter.getMember(jValue);
- if(j == nextQueue)
- {
- if(nextValue == jValue &&
- nextValueComparable == jValueComparable)
- {
- if(remove)
- return nextQueue.remove();
- else
- return jValue;
- }
- nextValue = jValue;
- nextValueComparable = jValueComparable;
- }
- else
- {
- if((jValueComparable == null && nextQueue == null) || // There is no next queue, use this one.
- (jValueComparable != null &&
- (nextValueComparable == null || // Currently stored next value is null (last) and this one should be used before.
- jValueComparable.compareTo(nextValueComparable) < 0))) // This one comes before the currently stored next value.
- {
- nextQueue = j;
- nextValue = jValue;
- nextValueComparable = jValueComparable;
- }
- }
- }
- }
- }
- }
- }
- if(!populatedQueueFound)
- throw new NoSuchElementException();
- }
- throw new RuntimeException("Loop threshhold reached for combined queue - either something is constantly " +
- "modifying one of the reference queues, or there is a problem with the " +
- "CombinedQueue.get method.");
- // replace with specific exception pertaining to the threshhold reached.
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment