-
Notifications
You must be signed in to change notification settings - Fork 0
/
docs.json
306 lines (306 loc) · 14.2 KB
/
docs.json
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
[
{
"kind": "module",
"file": "source/timingwheels/timingwheels_impl.d",
"members": [
{
"line": 60,
"kind": "class",
"char": 1,
"base": "object.Exception",
"members": [
{
"parameters": [
{
"deco": "Aya",
"name": "msg"
},
{
"deco": "Aya",
"default": "__FILE__",
"name": "file"
},
{
"deco": "m",
"default": "cast(ulong)__LINE__",
"name": "line"
}
],
"line": 63,
"kind": "constructor",
"originalType": "@nogc @safe (string msg, string file = __FILE__, size_t line = __LINE__)",
"char": 5,
"name": "this",
"deco": "FNiNfAyaQdmZC12timingwheels17timingwheels_impl18ScheduleTimerError",
"endchar": 5,
"endline": 66,
"comment": "\n"
}
],
"name": "ScheduleTimerError",
"comment": "\nscheduling error occurs at schedule() when ticks == 0 or timer already scheduled.\n\n\n"
},
{
"line": 71,
"kind": "class",
"char": 1,
"base": "object.Exception",
"members": [
{
"parameters": [
{
"deco": "Aya",
"name": "msg"
},
{
"deco": "Aya",
"default": "__FILE__",
"name": "file"
},
{
"deco": "m",
"default": "cast(ulong)__LINE__",
"name": "line"
}
],
"line": 74,
"kind": "constructor",
"originalType": "@nogc @safe (string msg, string file = __FILE__, size_t line = __LINE__)",
"char": 5,
"name": "this",
"deco": "FNiNfAyaQdmZC12timingwheels17timingwheels_impl16CancelTimerError",
"endchar": 5,
"endline": 77,
"comment": "\n"
}
],
"name": "CancelTimerError",
"comment": "\nCancel timer error occurs if you try to cancel timer which is not scheduled.\n\n"
},
{
"line": 82,
"kind": "class",
"char": 1,
"base": "object.Exception",
"members": [
{
"parameters": [
{
"deco": "Aya",
"name": "msg"
},
{
"deco": "Aya",
"default": "__FILE__",
"name": "file"
},
{
"deco": "m",
"default": "cast(ulong)__LINE__",
"name": "line"
}
],
"line": 87,
"kind": "constructor",
"originalType": "@nogc @safe (string msg, string file = __FILE__, size_t line = __LINE__)",
"char": 5,
"name": "this",
"deco": "FNiNfAyaQdmZC12timingwheels17timingwheels_impl17AdvanceWheelError",
"endchar": 5,
"endline": 90,
"comment": "\n\n\n"
}
],
"name": "AdvanceWheelError",
"comment": "\nAdvancing error occurs if number of ticks for advance not in range 0<t<=256\n\n"
},
{
"parameters": [
{
"kind": "type",
"name": "T"
}
],
"line": 227,
"kind": "template",
"char": 1,
"members": [
{
"kind": "struct",
"char": 1,
"members": [
{
"storageClass": [
"auto"
],
"parameters": [
{
"type": "Duration",
"name": "tick"
}
],
"line": 385,
"kind": "function",
"char": 10,
"name": "currStdTime",
"type": "(Duration tick)",
"endchar": 5,
"endline": 388,
"comment": "\n Return internal view on current time - it is time at the call to $(B init)\n plus total number of steps multiplied by $(B tick) duration.\n Params:\n tick = tick duration\n"
},
{
"parameters": [
{
"kind": "type",
"name": "T"
}
],
"line": 401,
"kind": "template",
"char": 10,
"members": [
{
"parameters": [
{
"type": "T",
"name": "timer"
},
{
"deco": "m",
"storageClass": [
"const"
],
"name": "ticks"
}
],
"line": 401,
"kind": "function",
"char": 10,
"name": "schedule",
"type": "void(T timer, const ulong ticks)",
"endchar": 5,
"endline": 424
}
],
"name": "schedule",
"comment": "\nSchedule timer to $(B ticks) ticks forward from internal 'now'.\nParams:\ntimer = timer to schedule;\nticks = ticks in the future to schedule timer. (0 < ticks < ulong.max);\nReturns:\nvoid\nThrows:\nScheduleTimerError\nwhen thicks == 0\nor when timer already scheduled\n\n"
},
{
"parameters": [
{
"kind": "type",
"name": "T"
}
],
"line": 433,
"kind": "template",
"char": 10,
"members": [
{
"parameters": [
{
"type": "T",
"name": "timer"
}
],
"line": 433,
"kind": "function",
"char": 10,
"name": "cancel",
"type": "void(T timer)",
"endchar": 5,
"endline": 449
}
],
"name": "cancel",
"comment": "Cancel timer\nParams:\ntimer = timer to cancel\nReturns:\nvoid\nThrows:\nCancelTimerError\nif timer not in wheel\n"
},
{
"parameters": [
{
"type": "Duration",
"name": "tick"
},
{
"deco": "m",
"name": "realTime"
}
],
"line": 458,
"kind": "function",
"char": 9,
"name": "ticksToCatchUp",
"type": "int(Duration tick, ulong realTime)",
"endchar": 5,
"endline": 467,
"comment": "Number of ticks to rotate wheels until internal wheel 'now'\ncatch up with real world realTime.\nCalculation based on time when wheels were stared and total\nnumer of ticks pasded.\nParams:\ntick = your tick length (Duration)\nrealTime = current real world now (Clock.currStdTime)\nReturns: ticks to advance so that we catch up real world current time\n"
},
{
"parameters": [
{
"type": "Duration",
"storageClass": [
"const"
],
"name": "tick"
},
{
"deco": "m",
"name": "realNow"
}
],
"line": 477,
"kind": "function",
"char": 14,
"name": "timeUntilNextEvent",
"type": "Duration(const Duration tick, ulong realNow)",
"endchar": 5,
"endline": 485,
"comment": "Time until next scheduled timer event.\nYou provide tick size and current real world time.\nThis function find ticks until next event and use time of the start and\ntotal steps executed to calculate time delta from $(B realNow) to next event.\nParams:\ntick = your accepted tick duration.\nrealNow = real world now, result of Clock.currStdTime\nReturns: time until next event. Can be zero or negative in case you have already expired events.\n\n"
},
{
"parameters": [
{
"kind": "this",
"name": "W"
}
],
"line": 494,
"kind": "template",
"char": 10,
"members": [
{
"storageClass": [
"auto"
],
"parameters": [
{
"deco": "m",
"name": "ticks"
}
],
"line": 494,
"kind": "function",
"char": 10,
"name": "advance",
"type": "(ulong ticks)",
"endchar": 5,
"endline": 541
}
],
"name": "advance",
"comment": "\nAdnvance wheel and return all timers expired during wheel turn.\n\nParams:\nticks = how many ticks to advance. Must be in range 0 <= 256\nReturns: list of expired timers\n\n"
}
],
"line": 227,
"name": "TimingWheels"
}
],
"name": "TimingWheels",
"comment": "\nThis structure implements scheme 6.2 thom the\n$(LINK http://www.cs.columbia.edu/~nahum/w6998/papers/sosp87-timing-wheels.pdf)\nand supports several primitives:\n$(UL\n$(LI schedule timer in the future.)\n$(LI cancel timer.)\n$(LI time step (advance) - all timers expired at current time tick are extracted from wheels.)\n)\nEach operation take O(1) time.\n\nExample:\n$(DDOX_UNITTEST_HEADER __unittest_L742_C1)\n---\nimport std;\nglobalLogLevel = LogLevel.info;\nauto rnd = Random(142);\n\n/// track execution\nint counter;\nSysTime last;\n\n/// this is our Timer\nclass Timer\n{\n static ulong __id;\n private ulong _id;\n private string _name;\n this(string name)\n {\n _id = __id++;\n _name = name;\n }\n /// must provide id() method\n ulong id()\n {\n return _id;\n }\n}\n\nenum IOWakeUpInterval = 100; // to simulate random IO wakeups in interval 0 - 100.msecs\n\n// each tick span 5 msecs - this is our link with time in reality\nauto Tick = getValue!Duration();\nTimingWheels!Timer w;\nw.init();\nauto durationToTicks(Duration d)\n{\n // we have to adjust w.now and realtime 'now' before scheduling timer\n auto real_now = Clock.currStdTime;\n auto tw_now = w.currStdTime(Tick);\n auto delay = (real_now - tw_now).hnsecs;\n return (d + delay)/Tick;\n}\nvoid process_timer(Timer t)\n{\n switch(t._name)\n {\n case \"periodic\":\n if ( last.stdTime == 0)\n {\n // initialize tracking\n last = Clock.currTime - 50.msecs;\n }\n auto delta = Clock.currTime - last;\n shouldApproxEqual((1e0*delta.split!\"msecs\".msecs), 50e0,1e-1);\n writefln(\"@ %s - delta: %sms (should be 50ms)\", t._name, (Clock.currTime - last).split!\"msecs\".msecs);\n last = Clock.currTime;\n counter++;\n w.schedule(t, durationToTicks(50.msecs)); // rearm\n break;\n default:\n writefln(\"@ %s\", t._name);\n break;\n }\n}\n// some random initial delay\nauto randomInitialDelay = uniform(0, 500, rnd).msecs;\nThread.sleep(randomInitialDelay);\n//\n// start one arbitrary timer and one periodic timer\n//\nauto some_timer = new Timer(\"some\");\nauto periodic_timer = new Timer(\"periodic\");\nw.schedule(some_timer, durationToTicks(32.msecs));\nw.schedule(periodic_timer, durationToTicks(50.msecs));\n\nwhile(counter < 10)\n{\n auto realNow = Clock.currStdTime;\n auto randomIoInterval = uniform(0, IOWakeUpInterval, rnd).msecs;\n auto nextTimerEvent = max(w.timeUntilNextEvent(Tick, realNow), 0.msecs);\n // wait for what should happen earlier\n auto time_to_sleep = min(randomIoInterval, nextTimerEvent);\n writefln(\"* sleep until timer event or random I/O for %s\", time_to_sleep);\n Thread.sleep(time_to_sleep);\n // if we waked up early by the IO event then timeUntilNextEvent will be positive\n // otherwise it will be <= 0 and we have something to process.\n realNow = Clock.currStdTime;\n int ticks = w.ticksToCatchUp(Tick, realNow);\n if (ticks > 0)\n {\n auto wr = w.advance(ticks);\n foreach(t; wr.timers)\n {\n process_timer(t);\n }\n }\n // some random processing time\n Thread.sleep(uniform(0, 5, rnd).msecs);\n}\n\n---\n$(DDOX_UNITTEST_FOOTER __unittest_L742_C1)\nExample:\n$(DDOX_UNITTEST_HEADER __unittest_L742_C1)\n---\nimport std;\nglobalLogLevel = LogLevel.info;\nauto rnd = Random(142);\n\n/// track execution\nint counter;\nSysTime last;\n\n/// this is our Timer\nclass Timer\n{\n static ulong __id;\n private ulong _id;\n private string _name;\n this(string name)\n {\n _id = __id++;\n _name = name;\n }\n /// must provide id() method\n ulong id()\n {\n return _id;\n }\n}\n\nenum IOWakeUpInterval = 100; // to simulate random IO wakeups in interval 0 - 100.msecs\n\n// each tick span 5 msecs - this is our link with time in reality\nauto Tick = getValue!Duration();\nTimingWheels!Timer w;\nw.init();\nauto durationToTicks(Duration d)\n{\n // we have to adjust w.now and realtime 'now' before scheduling timer\n auto real_now = Clock.currStdTime;\n auto tw_now = w.currStdTime(Tick);\n auto delay = (real_now - tw_now).hnsecs;\n return (d + delay)/Tick;\n}\nvoid process_timer(Timer t)\n{\n switch(t._name)\n {\n case \"periodic\":\n if ( last.stdTime == 0)\n {\n // initialize tracking\n last = Clock.currTime - 50.msecs;\n }\n auto delta = Clock.currTime - last;\n shouldApproxEqual((1e0*delta.split!\"msecs\".msecs), 50e0,1e-1);\n writefln(\"@ %s - delta: %sms (should be 50ms)\", t._name, (Clock.currTime - last).split!\"msecs\".msecs);\n last = Clock.currTime;\n counter++;\n w.schedule(t, durationToTicks(50.msecs)); // rearm\n break;\n default:\n writefln(\"@ %s\", t._name);\n break;\n }\n}\n// some random initial delay\nauto randomInitialDelay = uniform(0, 500, rnd).msecs;\nThread.sleep(randomInitialDelay);\n//\n// start one arbitrary timer and one periodic timer\n//\nauto some_timer = new Timer(\"some\");\nauto periodic_timer = new Timer(\"periodic\");\nw.schedule(some_timer, durationToTicks(32.msecs));\nw.schedule(periodic_timer, durationToTicks(50.msecs));\n\nwhile(counter < 10)\n{\n auto realNow = Clock.currStdTime;\n auto randomIoInterval = uniform(0, IOWakeUpInterval, rnd).msecs;\n auto nextTimerEvent = max(w.timeUntilNextEvent(Tick, realNow), 0.msecs);\n // wait for what should happen earlier\n auto time_to_sleep = min(randomIoInterval, nextTimerEvent);\n writefln(\"* sleep until timer event or random I/O for %s\", time_to_sleep);\n Thread.sleep(time_to_sleep);\n // if we waked up early by the IO event then timeUntilNextEvent will be positive\n // otherwise it will be <= 0 and we have something to process.\n realNow = Clock.currStdTime;\n int ticks = w.ticksToCatchUp(Tick, realNow);\n if (ticks > 0)\n {\n auto wr = w.advance(ticks);\n foreach(t; wr.timers)\n {\n process_timer(t);\n }\n }\n // some random processing time\n Thread.sleep(uniform(0, 5, rnd).msecs);\n}\n\n---\n$(DDOX_UNITTEST_FOOTER __unittest_L742_C1)\n"
}
],
"comment": "\n",
"name": "timingwheels.timingwheels_impl"
}
]