diff --git a/tests/gold_tests/autest-site/ordered_set_queue.py b/tests/gold_tests/autest-site/ordered_set_queue.py new file mode 100644 index 00000000000..5001cf7ade1 --- /dev/null +++ b/tests/gold_tests/autest-site/ordered_set_queue.py @@ -0,0 +1,106 @@ +''' +Implement an OrderedSetQueue +''' +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +import collections +try: + import queue as Queue +except ImportError: + import Queue + + +# +# This is borrowed from the following (MIT licensed) recipe: +# https://code.activestate.com/recipes/576694/ +# + +class OrderedSet(collections.MutableSet): + + def __init__(self, iterable=None): + self.end = end = [] + end += [None, end, end] # sentinel node for doubly linked list + self.map = {} # key --> [key, prev, next] + if iterable is not None: + self |= iterable + + def __len__(self): + return len(self.map) + + def __contains__(self, key): + return key in self.map + + def add(self, key): + if key not in self.map: + end = self.end + curr = end[1] + curr[2] = end[1] = self.map[key] = [key, curr, end] + + def discard(self, key): + if key in self.map: + key, prev, next = self.map.pop(key) + prev[2] = next + next[1] = prev + + def __iter__(self): + end = self.end + curr = end[2] + while curr is not end: + yield curr[0] + curr = curr[2] + + def __reversed__(self): + end = self.end + curr = end[1] + while curr is not end: + yield curr[0] + curr = curr[1] + + # We set last=False so that FIFO is the default behavior. + def pop(self, last=False): + if not self: + raise KeyError('set is empty') + key = self.end[1][0] if last else self.end[2][0] + self.discard(key) + return key + + def __repr__(self): + if not self: + return '%s()' % (self.__class__.__name__,) + return '%s(%r)' % (self.__class__.__name__, list(self)) + + def __eq__(self, other): + if isinstance(other, OrderedSet): + return len(self) == len(other) and list(self) == list(other) + return set(self) == set(other) + + +class OrderedSetQueue(Queue.Queue): + """ + Make use of the OrderedSet to make a FIFO Queue.Queue that only has unique + elements in it. + """ + + def _init(self, maxsize): + self.queue = OrderedSet() + + def _put(self, item): + self.queue.add(item) + + def _get(self): + return self.queue.pop() diff --git a/tests/gold_tests/autest-site/ports.py b/tests/gold_tests/autest-site/ports.py index 7932be82e4f..f5efed6efbe 100644 --- a/tests/gold_tests/autest-site/ports.py +++ b/tests/gold_tests/autest-site/ports.py @@ -23,10 +23,8 @@ import hosts.output as host -try: - import queue as Queue -except ImportError: - import Queue +from ordered_set_queue import OrderedSetQueue + g_ports = None # ports we can use @@ -55,7 +53,7 @@ def PortOpen(port, address=None): def setup_port_queue(amount=1000): global g_ports if g_ports is None: - g_ports = Queue.LifoQueue() + g_ports = OrderedSetQueue() else: return try: