aboutsummaryrefslogtreecommitdiff
path: root/discord/utils.py
diff options
context:
space:
mode:
Diffstat (limited to 'discord/utils.py')
-rw-r--r--discord/utils.py34
1 files changed, 33 insertions, 1 deletions
diff --git a/discord/utils.py b/discord/utils.py
index 6bdfc36e..f536200f 100644
--- a/discord/utils.py
+++ b/discord/utils.py
@@ -26,13 +26,16 @@ DEALINGS IN THE SOFTWARE.
from re import split as re_split
from .errors import InvalidArgument
-import datetime
from base64 import b64encode
from email.utils import parsedate_to_datetime
from inspect import isawaitable as _isawaitable
+from bisect import bisect_left
+
+import datetime
import asyncio
import json
import warnings, functools
+import array
DISCORD_EPOCH = 1420070400000
@@ -289,3 +292,32 @@ async def sane_wait_for(futures, *, timeout, loop):
def valid_icon_size(size):
"""Icons must be power of 2 within [16, 1024]."""
return ((size != 0) and not (size & (size - 1))) and size in range(16, 1025)
+
+class SnowflakeList(array.array):
+ """Internal data storage class to efficiently store a list of snowflakes.
+
+ This should have the following characteristics:
+
+ - Low memory usage
+ - O(n) iteration (obviously)
+ - O(n log n) initial creation if data is unsorted
+ - O(log n) search and indexing
+ - O(n) insertion
+ """
+
+ __slots__ = ()
+
+ def __new__(cls, data, *, is_sorted=False):
+ return array.array.__new__(cls, 'Q', data if is_sorted else sorted(data))
+
+ def add(self, element):
+ i = bisect_left(self, element)
+ self.insert(i, element)
+
+ def get(self, element):
+ i = bisect_left(self, element)
+ return self[i] if i != len(self) and self[i] == element else None
+
+ def has(self, element):
+ i = bisect_left(self, element)
+ return i != len(self) and self[i] == element