Skip to content

Commit 045aece

Browse files
committed
Experimenting with different sorts, switching from heapq to list.sort()
Signed-off-by: Mike Stitt <[email protected]>
1 parent 3f3d25e commit 045aece

File tree

1 file changed

+84
-7
lines changed

1 file changed

+84
-7
lines changed

subprojects/robotpy-wpilib/wpilib/timedrobotpy.py

Lines changed: 84 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,82 @@ def __repr__(self) -> str:
9898
return f"{{func={self.func.__name__}, _periodUs={self._periodUs}, expirationUs={self.expirationUs}}}"
9999

100100

101-
class _OrderedList:
101+
class _OrderedListSort:
102+
103+
__slots__ = "_data"
104+
105+
def __init__(self) -> None:
106+
self._data: list[Any] = []
107+
108+
def add(self, item: Any) -> None:
109+
self._data.append(item)
110+
self._data.sort()
111+
112+
def pop(self) -> Any:
113+
return self._data.pop()
114+
115+
def peek(
116+
self,
117+
) -> Any: # todo change to Any | None when we don't build with python 3.9
118+
if self._data:
119+
return self._data[0]
120+
else:
121+
return None
122+
123+
def reorderListAfterAChangeInTheFirstElement(self):
124+
self._data.sort()
125+
126+
def __len__(self) -> int:
127+
return len(self._data)
128+
129+
def __iter__(self) -> Iterable[Any]:
130+
return iter(sorted(self._data))
131+
132+
def __contains__(self, item) -> bool:
133+
return item in self._data
134+
135+
def __repr__(self) -> str:
136+
return str(sorted(self._data))
137+
138+
139+
class _OrderedListMin:
140+
141+
__slots__ = "_data"
142+
143+
def __init__(self) -> None:
144+
self._data: list[Any] = []
145+
146+
def add(self, item: Any) -> None:
147+
self._data.append(item)
148+
149+
# def pop(self) -> Any:
150+
# return self._data.pop()
151+
152+
def peek(
153+
self,
154+
) -> Any: # todo change to Any | None when we don't build with python 3.9
155+
if self._data:
156+
return min(self._data)
157+
else:
158+
return None
159+
160+
def reorderListAfterAChangeInTheFirstElement(self):
161+
pass
162+
163+
def __len__(self) -> int:
164+
return len(self._data)
165+
166+
def __iter__(self) -> Iterable[Any]:
167+
return iter(sorted(self._data))
168+
169+
def __contains__(self, item) -> bool:
170+
return item in self._data
171+
172+
def __repr__(self) -> str:
173+
return str(sorted(self._data))
174+
175+
176+
class _OrderedListHeapq:
102177

103178
__slots__ = "_data"
104179

@@ -162,7 +237,7 @@ def __init__(self, period: wpimath.units.seconds = kDefaultPeriod) -> None:
162237
# All periodic functions created by addPeriodic are relative
163238
# to this self._startTimeUs
164239
self._startTimeUs = _getFPGATime()
165-
self._callbacks = _OrderedList()
240+
self._callbacks = _OrderedListSort()
166241
self._loopStartTimeUs = 0
167242
self.addPeriodic(self._loopFunc, period=self._periodS)
168243

@@ -236,19 +311,21 @@ def startCompetition(self) -> None:
236311

237312
# self._loopStartTimeUs = startTimeUs # Uncomment this line for legacy behavior.
238313

239-
self._runCallbackAtHeadOfListAndReschedule()
314+
self._runCallbackAtHeadOfListAndReschedule(callback)
240315

241316
# Process all other callbacks that are ready to run
242317
# Changing the comparison to be _getFPGATime() rather than
243318
# self._loopStartTimeUs would also be correct.
244-
while self._callbacks.peek().expirationUs <= self._loopStartTimeUs:
245-
self._runCallbackAtHeadOfListAndReschedule()
319+
while (
320+
callback := self._callbacks.peek()
321+
).expirationUs <= _getFPGATime():
322+
self._runCallbackAtHeadOfListAndReschedule(callback)
246323
finally:
247324
# pytests hang on PC when we don't force a call to self._stopNotifier()
248325
self._stopNotifier()
249326

250-
def _runCallbackAtHeadOfListAndReschedule(self) -> None:
251-
callback = self._callbacks.peek()
327+
def _runCallbackAtHeadOfListAndReschedule(self, callback) -> None:
328+
# callback = self._callbacks.peek()
252329
# The callback.func() may have added more callbacks to self._callbacks,
253330
# but each is sorted by the _getFPGATime() at the moment it is
254331
# created, which is greater than self.expirationUs of this callback,

0 commit comments

Comments
 (0)