OLD | NEW |
(Empty) | |
| 1 # Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 # Use of this source code is governed by a BSD-style license that can be |
| 3 # found in the LICENSE file. |
| 4 |
| 5 import collections |
| 6 |
| 7 class OrderedSet(collections.MutableSet): |
| 8 # from http://code.activestate.com/recipes/576694/ |
| 9 def __init__(self, iterable=None): |
| 10 self.end = end = [] |
| 11 end += [None, end, end] # sentinel node for doubly linked list |
| 12 self.data = {} # key --> [key, prev, next] |
| 13 if iterable is not None: |
| 14 self |= iterable |
| 15 |
| 16 def __contains__(self, key): |
| 17 return key in self.data |
| 18 |
| 19 def __eq__(self, other): |
| 20 if isinstance(other, OrderedSet): |
| 21 return len(self) == len(other) and list(self) == list(other) |
| 22 return set(self) == set(other) |
| 23 |
| 24 def __ne__(self, other): |
| 25 if isinstance(other, OrderedSet): |
| 26 return len(self) != len(other) or list(self) != list(other) |
| 27 return set(self) != set(other) |
| 28 |
| 29 def __len__(self): |
| 30 return len(self.data) |
| 31 |
| 32 def __iter__(self): |
| 33 end = self.end |
| 34 curr = end[2] |
| 35 while curr is not end: |
| 36 yield curr[0] |
| 37 curr = curr[2] |
| 38 |
| 39 def __repr__(self): |
| 40 if not self: |
| 41 return '%s()' % (self.__class__.__name__,) |
| 42 return '%s(%r)' % (self.__class__.__name__, list(self)) |
| 43 |
| 44 def __reversed__(self): |
| 45 end = self.end |
| 46 curr = end[1] |
| 47 while curr is not end: |
| 48 yield curr[0] |
| 49 curr = curr[1] |
| 50 |
| 51 def add(self, key): |
| 52 if key not in self.data: |
| 53 end = self.end |
| 54 curr = end[1] |
| 55 curr[2] = end[1] = self.data[key] = [key, curr, end] |
| 56 |
| 57 def difference_update(self, *others): |
| 58 for other in others: |
| 59 for i in other: |
| 60 self.discard(i) |
| 61 |
| 62 def discard(self, key): |
| 63 if key in self.data: |
| 64 key, prev, nxt = self.data.pop(key) |
| 65 prev[2] = nxt |
| 66 nxt[1] = prev |
| 67 |
| 68 def pop(self, last=True): # pylint: disable=W0221 |
| 69 if not self: |
| 70 raise KeyError('set is empty') |
| 71 key = self.end[1][0] if last else self.end[2][0] |
| 72 self.discard(key) |
| 73 return key |
| 74 |
| 75 |
| 76 |
OLD | NEW |