foolio 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (261) hide show
  1. data/.gitignore +22 -0
  2. data/Gemfile +4 -0
  3. data/LICENSE +22 -0
  4. data/README.md +29 -0
  5. data/Rakefile +21 -0
  6. data/examples/timer.rb +20 -0
  7. data/ext/foolio/extconf.rb +34 -0
  8. data/ext/foolio/foolio_ext.c +921 -0
  9. data/ext/foolio/gen.rb +50 -0
  10. data/ext/foolio/make_table.rb +12 -0
  11. data/ext/foolio/templ +243 -0
  12. data/ext/libuv/.gitignore +33 -0
  13. data/ext/libuv/.mailmap +13 -0
  14. data/ext/libuv/.travis.yml +9 -0
  15. data/ext/libuv/AUTHORS +61 -0
  16. data/ext/libuv/LICENSE +44 -0
  17. data/ext/libuv/Makefile +71 -0
  18. data/ext/libuv/README.md +90 -0
  19. data/ext/libuv/common.gypi +178 -0
  20. data/ext/libuv/gyp_uv +73 -0
  21. data/ext/libuv/include/uv-private/eio.h +403 -0
  22. data/ext/libuv/include/uv-private/ev.h +838 -0
  23. data/ext/libuv/include/uv-private/ngx-queue.h +108 -0
  24. data/ext/libuv/include/uv-private/tree.h +768 -0
  25. data/ext/libuv/include/uv-private/uv-unix.h +324 -0
  26. data/ext/libuv/include/uv-private/uv-win.h +517 -0
  27. data/ext/libuv/include/uv.h +1838 -0
  28. data/ext/libuv/src/fs-poll.c +235 -0
  29. data/ext/libuv/src/inet.c +293 -0
  30. data/ext/libuv/src/unix/async.c +148 -0
  31. data/ext/libuv/src/unix/core.c +696 -0
  32. data/ext/libuv/src/unix/cygwin.c +83 -0
  33. data/ext/libuv/src/unix/darwin.c +342 -0
  34. data/ext/libuv/src/unix/dl.c +83 -0
  35. data/ext/libuv/src/unix/eio/Changes +63 -0
  36. data/ext/libuv/src/unix/eio/LICENSE +36 -0
  37. data/ext/libuv/src/unix/eio/Makefile.am +15 -0
  38. data/ext/libuv/src/unix/eio/aclocal.m4 +8957 -0
  39. data/ext/libuv/src/unix/eio/autogen.sh +3 -0
  40. data/ext/libuv/src/unix/eio/config.h.in +86 -0
  41. data/ext/libuv/src/unix/eio/config_cygwin.h +80 -0
  42. data/ext/libuv/src/unix/eio/config_darwin.h +141 -0
  43. data/ext/libuv/src/unix/eio/config_freebsd.h +81 -0
  44. data/ext/libuv/src/unix/eio/config_linux.h +94 -0
  45. data/ext/libuv/src/unix/eio/config_netbsd.h +81 -0
  46. data/ext/libuv/src/unix/eio/config_openbsd.h +137 -0
  47. data/ext/libuv/src/unix/eio/config_sunos.h +84 -0
  48. data/ext/libuv/src/unix/eio/configure.ac +22 -0
  49. data/ext/libuv/src/unix/eio/demo.c +194 -0
  50. data/ext/libuv/src/unix/eio/ecb.h +370 -0
  51. data/ext/libuv/src/unix/eio/eio.3 +3428 -0
  52. data/ext/libuv/src/unix/eio/eio.c +2593 -0
  53. data/ext/libuv/src/unix/eio/eio.pod +969 -0
  54. data/ext/libuv/src/unix/eio/libeio.m4 +195 -0
  55. data/ext/libuv/src/unix/eio/xthread.h +164 -0
  56. data/ext/libuv/src/unix/error.c +105 -0
  57. data/ext/libuv/src/unix/ev/Changes +388 -0
  58. data/ext/libuv/src/unix/ev/LICENSE +36 -0
  59. data/ext/libuv/src/unix/ev/Makefile.am +18 -0
  60. data/ext/libuv/src/unix/ev/Makefile.in +771 -0
  61. data/ext/libuv/src/unix/ev/README +58 -0
  62. data/ext/libuv/src/unix/ev/aclocal.m4 +8957 -0
  63. data/ext/libuv/src/unix/ev/autogen.sh +6 -0
  64. data/ext/libuv/src/unix/ev/config.guess +1526 -0
  65. data/ext/libuv/src/unix/ev/config.h.in +125 -0
  66. data/ext/libuv/src/unix/ev/config.sub +1658 -0
  67. data/ext/libuv/src/unix/ev/config_cygwin.h +123 -0
  68. data/ext/libuv/src/unix/ev/config_darwin.h +122 -0
  69. data/ext/libuv/src/unix/ev/config_freebsd.h +120 -0
  70. data/ext/libuv/src/unix/ev/config_linux.h +141 -0
  71. data/ext/libuv/src/unix/ev/config_netbsd.h +120 -0
  72. data/ext/libuv/src/unix/ev/config_openbsd.h +126 -0
  73. data/ext/libuv/src/unix/ev/config_sunos.h +122 -0
  74. data/ext/libuv/src/unix/ev/configure +13037 -0
  75. data/ext/libuv/src/unix/ev/configure.ac +18 -0
  76. data/ext/libuv/src/unix/ev/depcomp +630 -0
  77. data/ext/libuv/src/unix/ev/ev++.h +816 -0
  78. data/ext/libuv/src/unix/ev/ev.3 +5311 -0
  79. data/ext/libuv/src/unix/ev/ev.c +3925 -0
  80. data/ext/libuv/src/unix/ev/ev.pod +5243 -0
  81. data/ext/libuv/src/unix/ev/ev_epoll.c +266 -0
  82. data/ext/libuv/src/unix/ev/ev_kqueue.c +235 -0
  83. data/ext/libuv/src/unix/ev/ev_poll.c +148 -0
  84. data/ext/libuv/src/unix/ev/ev_port.c +179 -0
  85. data/ext/libuv/src/unix/ev/ev_select.c +310 -0
  86. data/ext/libuv/src/unix/ev/ev_vars.h +203 -0
  87. data/ext/libuv/src/unix/ev/ev_win32.c +153 -0
  88. data/ext/libuv/src/unix/ev/ev_wrap.h +196 -0
  89. data/ext/libuv/src/unix/ev/event.c +402 -0
  90. data/ext/libuv/src/unix/ev/event.h +170 -0
  91. data/ext/libuv/src/unix/ev/install-sh +294 -0
  92. data/ext/libuv/src/unix/ev/libev.m4 +39 -0
  93. data/ext/libuv/src/unix/ev/ltmain.sh +8413 -0
  94. data/ext/libuv/src/unix/ev/missing +336 -0
  95. data/ext/libuv/src/unix/ev/mkinstalldirs +111 -0
  96. data/ext/libuv/src/unix/freebsd.c +326 -0
  97. data/ext/libuv/src/unix/fs.c +739 -0
  98. data/ext/libuv/src/unix/internal.h +188 -0
  99. data/ext/libuv/src/unix/kqueue.c +120 -0
  100. data/ext/libuv/src/unix/linux/inotify.c +239 -0
  101. data/ext/libuv/src/unix/linux/linux-core.c +557 -0
  102. data/ext/libuv/src/unix/linux/syscalls.c +388 -0
  103. data/ext/libuv/src/unix/linux/syscalls.h +124 -0
  104. data/ext/libuv/src/unix/loop-watcher.c +62 -0
  105. data/ext/libuv/src/unix/loop.c +94 -0
  106. data/ext/libuv/src/unix/netbsd.c +108 -0
  107. data/ext/libuv/src/unix/openbsd.c +295 -0
  108. data/ext/libuv/src/unix/pipe.c +259 -0
  109. data/ext/libuv/src/unix/poll.c +114 -0
  110. data/ext/libuv/src/unix/process.c +495 -0
  111. data/ext/libuv/src/unix/signal.c +269 -0
  112. data/ext/libuv/src/unix/stream.c +990 -0
  113. data/ext/libuv/src/unix/sunos.c +481 -0
  114. data/ext/libuv/src/unix/tcp.c +393 -0
  115. data/ext/libuv/src/unix/thread.c +251 -0
  116. data/ext/libuv/src/unix/timer.c +136 -0
  117. data/ext/libuv/src/unix/tty.c +145 -0
  118. data/ext/libuv/src/unix/udp.c +659 -0
  119. data/ext/libuv/src/unix/uv-eio.c +107 -0
  120. data/ext/libuv/src/unix/uv-eio.h +13 -0
  121. data/ext/libuv/src/uv-common.c +380 -0
  122. data/ext/libuv/src/uv-common.h +170 -0
  123. data/ext/libuv/src/win/async.c +100 -0
  124. data/ext/libuv/src/win/atomicops-inl.h +56 -0
  125. data/ext/libuv/src/win/core.c +278 -0
  126. data/ext/libuv/src/win/dl.c +86 -0
  127. data/ext/libuv/src/win/error.c +155 -0
  128. data/ext/libuv/src/win/fs-event.c +510 -0
  129. data/ext/libuv/src/win/fs.c +1948 -0
  130. data/ext/libuv/src/win/getaddrinfo.c +365 -0
  131. data/ext/libuv/src/win/handle-inl.h +149 -0
  132. data/ext/libuv/src/win/handle.c +154 -0
  133. data/ext/libuv/src/win/internal.h +343 -0
  134. data/ext/libuv/src/win/loop-watcher.c +122 -0
  135. data/ext/libuv/src/win/pipe.c +1672 -0
  136. data/ext/libuv/src/win/poll.c +616 -0
  137. data/ext/libuv/src/win/process-stdio.c +500 -0
  138. data/ext/libuv/src/win/process.c +1013 -0
  139. data/ext/libuv/src/win/req-inl.h +220 -0
  140. data/ext/libuv/src/win/req.c +25 -0
  141. data/ext/libuv/src/win/signal.c +57 -0
  142. data/ext/libuv/src/win/stream-inl.h +67 -0
  143. data/ext/libuv/src/win/stream.c +167 -0
  144. data/ext/libuv/src/win/tcp.c +1394 -0
  145. data/ext/libuv/src/win/thread.c +372 -0
  146. data/ext/libuv/src/win/threadpool.c +74 -0
  147. data/ext/libuv/src/win/timer.c +224 -0
  148. data/ext/libuv/src/win/tty.c +1799 -0
  149. data/ext/libuv/src/win/udp.c +716 -0
  150. data/ext/libuv/src/win/util.c +864 -0
  151. data/ext/libuv/src/win/winapi.c +132 -0
  152. data/ext/libuv/src/win/winapi.h +4452 -0
  153. data/ext/libuv/src/win/winsock.c +557 -0
  154. data/ext/libuv/src/win/winsock.h +171 -0
  155. data/ext/libuv/test/benchmark-async-pummel.c +97 -0
  156. data/ext/libuv/test/benchmark-async.c +137 -0
  157. data/ext/libuv/test/benchmark-fs-stat.c +135 -0
  158. data/ext/libuv/test/benchmark-getaddrinfo.c +94 -0
  159. data/ext/libuv/test/benchmark-list.h +127 -0
  160. data/ext/libuv/test/benchmark-loop-count.c +88 -0
  161. data/ext/libuv/test/benchmark-million-timers.c +65 -0
  162. data/ext/libuv/test/benchmark-ping-pongs.c +213 -0
  163. data/ext/libuv/test/benchmark-pound.c +324 -0
  164. data/ext/libuv/test/benchmark-pump.c +462 -0
  165. data/ext/libuv/test/benchmark-sizes.c +44 -0
  166. data/ext/libuv/test/benchmark-spawn.c +162 -0
  167. data/ext/libuv/test/benchmark-tcp-write-batch.c +140 -0
  168. data/ext/libuv/test/benchmark-thread.c +64 -0
  169. data/ext/libuv/test/benchmark-udp-packet-storm.c +247 -0
  170. data/ext/libuv/test/blackhole-server.c +118 -0
  171. data/ext/libuv/test/dns-server.c +321 -0
  172. data/ext/libuv/test/echo-server.c +378 -0
  173. data/ext/libuv/test/fixtures/empty_file +0 -0
  174. data/ext/libuv/test/fixtures/load_error.node +1 -0
  175. data/ext/libuv/test/run-benchmarks.c +64 -0
  176. data/ext/libuv/test/run-tests.c +138 -0
  177. data/ext/libuv/test/runner-unix.c +295 -0
  178. data/ext/libuv/test/runner-unix.h +36 -0
  179. data/ext/libuv/test/runner-win.c +285 -0
  180. data/ext/libuv/test/runner-win.h +42 -0
  181. data/ext/libuv/test/runner.c +355 -0
  182. data/ext/libuv/test/runner.h +159 -0
  183. data/ext/libuv/test/task.h +112 -0
  184. data/ext/libuv/test/test-async.c +118 -0
  185. data/ext/libuv/test/test-callback-order.c +76 -0
  186. data/ext/libuv/test/test-callback-stack.c +203 -0
  187. data/ext/libuv/test/test-connection-fail.c +148 -0
  188. data/ext/libuv/test/test-cwd-and-chdir.c +64 -0
  189. data/ext/libuv/test/test-delayed-accept.c +188 -0
  190. data/ext/libuv/test/test-dlerror.c +58 -0
  191. data/ext/libuv/test/test-error.c +59 -0
  192. data/ext/libuv/test/test-fail-always.c +29 -0
  193. data/ext/libuv/test/test-fs-event.c +474 -0
  194. data/ext/libuv/test/test-fs-poll.c +146 -0
  195. data/ext/libuv/test/test-fs.c +1843 -0
  196. data/ext/libuv/test/test-get-currentexe.c +63 -0
  197. data/ext/libuv/test/test-get-loadavg.c +36 -0
  198. data/ext/libuv/test/test-get-memory.c +38 -0
  199. data/ext/libuv/test/test-getaddrinfo.c +122 -0
  200. data/ext/libuv/test/test-getsockname.c +342 -0
  201. data/ext/libuv/test/test-hrtime.c +54 -0
  202. data/ext/libuv/test/test-idle.c +81 -0
  203. data/ext/libuv/test/test-ipc-send-recv.c +209 -0
  204. data/ext/libuv/test/test-ipc.c +620 -0
  205. data/ext/libuv/test/test-list.h +427 -0
  206. data/ext/libuv/test/test-loop-handles.c +336 -0
  207. data/ext/libuv/test/test-multiple-listen.c +102 -0
  208. data/ext/libuv/test/test-mutexes.c +63 -0
  209. data/ext/libuv/test/test-pass-always.c +28 -0
  210. data/ext/libuv/test/test-ping-pong.c +253 -0
  211. data/ext/libuv/test/test-pipe-bind-error.c +140 -0
  212. data/ext/libuv/test/test-pipe-connect-error.c +96 -0
  213. data/ext/libuv/test/test-platform-output.c +87 -0
  214. data/ext/libuv/test/test-poll-close.c +72 -0
  215. data/ext/libuv/test/test-poll.c +573 -0
  216. data/ext/libuv/test/test-process-title.c +49 -0
  217. data/ext/libuv/test/test-ref.c +338 -0
  218. data/ext/libuv/test/test-run-once.c +48 -0
  219. data/ext/libuv/test/test-semaphore.c +111 -0
  220. data/ext/libuv/test/test-shutdown-close.c +103 -0
  221. data/ext/libuv/test/test-shutdown-eof.c +183 -0
  222. data/ext/libuv/test/test-signal.c +162 -0
  223. data/ext/libuv/test/test-spawn.c +863 -0
  224. data/ext/libuv/test/test-stdio-over-pipes.c +246 -0
  225. data/ext/libuv/test/test-tcp-bind-error.c +191 -0
  226. data/ext/libuv/test/test-tcp-bind6-error.c +154 -0
  227. data/ext/libuv/test/test-tcp-close-while-connecting.c +80 -0
  228. data/ext/libuv/test/test-tcp-close.c +129 -0
  229. data/ext/libuv/test/test-tcp-connect-error-after-write.c +95 -0
  230. data/ext/libuv/test/test-tcp-connect-error.c +70 -0
  231. data/ext/libuv/test/test-tcp-connect-timeout.c +85 -0
  232. data/ext/libuv/test/test-tcp-connect6-error.c +68 -0
  233. data/ext/libuv/test/test-tcp-flags.c +51 -0
  234. data/ext/libuv/test/test-tcp-shutdown-after-write.c +131 -0
  235. data/ext/libuv/test/test-tcp-unexpected-read.c +113 -0
  236. data/ext/libuv/test/test-tcp-write-error.c +168 -0
  237. data/ext/libuv/test/test-tcp-write-to-half-open-connection.c +135 -0
  238. data/ext/libuv/test/test-tcp-writealot.c +170 -0
  239. data/ext/libuv/test/test-thread.c +183 -0
  240. data/ext/libuv/test/test-threadpool.c +57 -0
  241. data/ext/libuv/test/test-timer-again.c +141 -0
  242. data/ext/libuv/test/test-timer.c +152 -0
  243. data/ext/libuv/test/test-tty.c +110 -0
  244. data/ext/libuv/test/test-udp-dgram-too-big.c +86 -0
  245. data/ext/libuv/test/test-udp-ipv6.c +156 -0
  246. data/ext/libuv/test/test-udp-multicast-join.c +139 -0
  247. data/ext/libuv/test/test-udp-multicast-ttl.c +86 -0
  248. data/ext/libuv/test/test-udp-options.c +86 -0
  249. data/ext/libuv/test/test-udp-send-and-recv.c +208 -0
  250. data/ext/libuv/test/test-util.c +97 -0
  251. data/ext/libuv/test/test-walk-handles.c +77 -0
  252. data/ext/libuv/uv.gyp +375 -0
  253. data/ext/libuv/vcbuild.bat +105 -0
  254. data/foolio.gemspec +18 -0
  255. data/lib/foolio.rb +9 -0
  256. data/lib/foolio/handle.rb +27 -0
  257. data/lib/foolio/listener.rb +26 -0
  258. data/lib/foolio/loop.rb +79 -0
  259. data/lib/foolio/stream.rb +109 -0
  260. data/lib/foolio/version.rb +3 -0
  261. metadata +309 -0
@@ -0,0 +1,108 @@
1
+
2
+ /*
3
+ * Copyright (C) Igor Sysoev
4
+ */
5
+
6
+
7
+ #ifndef NGX_QUEUE_H_INCLUDED_
8
+ #define NGX_QUEUE_H_INCLUDED_
9
+
10
+
11
+ typedef struct ngx_queue_s ngx_queue_t;
12
+
13
+ struct ngx_queue_s {
14
+ ngx_queue_t *prev;
15
+ ngx_queue_t *next;
16
+ };
17
+
18
+
19
+ #define ngx_queue_init(q) \
20
+ (q)->prev = q; \
21
+ (q)->next = q
22
+
23
+
24
+ #define ngx_queue_empty(h) \
25
+ (h == (h)->prev)
26
+
27
+
28
+ #define ngx_queue_insert_head(h, x) \
29
+ (x)->next = (h)->next; \
30
+ (x)->next->prev = x; \
31
+ (x)->prev = h; \
32
+ (h)->next = x
33
+
34
+
35
+ #define ngx_queue_insert_after ngx_queue_insert_head
36
+
37
+
38
+ #define ngx_queue_insert_tail(h, x) \
39
+ (x)->prev = (h)->prev; \
40
+ (x)->prev->next = x; \
41
+ (x)->next = h; \
42
+ (h)->prev = x
43
+
44
+
45
+ #define ngx_queue_head(h) \
46
+ (h)->next
47
+
48
+
49
+ #define ngx_queue_last(h) \
50
+ (h)->prev
51
+
52
+
53
+ #define ngx_queue_sentinel(h) \
54
+ (h)
55
+
56
+
57
+ #define ngx_queue_next(q) \
58
+ (q)->next
59
+
60
+
61
+ #define ngx_queue_prev(q) \
62
+ (q)->prev
63
+
64
+
65
+ #if defined(NGX_DEBUG)
66
+
67
+ #define ngx_queue_remove(x) \
68
+ (x)->next->prev = (x)->prev; \
69
+ (x)->prev->next = (x)->next; \
70
+ (x)->prev = NULL; \
71
+ (x)->next = NULL
72
+
73
+ #else
74
+
75
+ #define ngx_queue_remove(x) \
76
+ (x)->next->prev = (x)->prev; \
77
+ (x)->prev->next = (x)->next
78
+
79
+ #endif
80
+
81
+
82
+ #define ngx_queue_split(h, q, n) \
83
+ (n)->prev = (h)->prev; \
84
+ (n)->prev->next = n; \
85
+ (n)->next = q; \
86
+ (h)->prev = (q)->prev; \
87
+ (h)->prev->next = h; \
88
+ (q)->prev = n;
89
+
90
+
91
+ #define ngx_queue_add(h, n) \
92
+ (h)->prev->next = (n)->next; \
93
+ (n)->next->prev = (h)->prev; \
94
+ (h)->prev = (n)->prev; \
95
+ (h)->prev->next = h;
96
+
97
+
98
+ #define ngx_queue_data(q, type, link) \
99
+ (type *) ((unsigned char *) q - offsetof(type, link))
100
+
101
+
102
+ #define ngx_queue_foreach(q, h) \
103
+ for ((q) = ngx_queue_head(h); \
104
+ (q) != ngx_queue_sentinel(h); \
105
+ (q) = ngx_queue_next(q))
106
+
107
+
108
+ #endif /* NGX_QUEUE_H_INCLUDED_ */
@@ -0,0 +1,768 @@
1
+ /*-
2
+ * Copyright 2002 Niels Provos <provos@citi.umich.edu>
3
+ * All rights reserved.
4
+ *
5
+ * Redistribution and use in source and binary forms, with or without
6
+ * modification, are permitted provided that the following conditions
7
+ * are met:
8
+ * 1. Redistributions of source code must retain the above copyright
9
+ * notice, this list of conditions and the following disclaimer.
10
+ * 2. Redistributions in binary form must reproduce the above copyright
11
+ * notice, this list of conditions and the following disclaimer in the
12
+ * documentation and/or other materials provided with the distribution.
13
+ *
14
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
15
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
18
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
19
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
20
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
21
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24
+ */
25
+
26
+ #ifndef UV_TREE_H_
27
+ #define UV_TREE_H_
28
+
29
+ #ifndef UV__UNUSED
30
+ # if __GNUC__
31
+ # define UV__UNUSED __attribute__((unused))
32
+ # else
33
+ # define UV__UNUSED
34
+ # endif
35
+ #endif
36
+
37
+ /*
38
+ * This file defines data structures for different types of trees:
39
+ * splay trees and red-black trees.
40
+ *
41
+ * A splay tree is a self-organizing data structure. Every operation
42
+ * on the tree causes a splay to happen. The splay moves the requested
43
+ * node to the root of the tree and partly rebalances it.
44
+ *
45
+ * This has the benefit that request locality causes faster lookups as
46
+ * the requested nodes move to the top of the tree. On the other hand,
47
+ * every lookup causes memory writes.
48
+ *
49
+ * The Balance Theorem bounds the total access time for m operations
50
+ * and n inserts on an initially empty tree as O((m + n)lg n). The
51
+ * amortized cost for a sequence of m accesses to a splay tree is O(lg n);
52
+ *
53
+ * A red-black tree is a binary search tree with the node color as an
54
+ * extra attribute. It fulfills a set of conditions:
55
+ * - every search path from the root to a leaf consists of the
56
+ * same number of black nodes,
57
+ * - each red node (except for the root) has a black parent,
58
+ * - each leaf node is black.
59
+ *
60
+ * Every operation on a red-black tree is bounded as O(lg n).
61
+ * The maximum height of a red-black tree is 2lg (n+1).
62
+ */
63
+
64
+ #define SPLAY_HEAD(name, type) \
65
+ struct name { \
66
+ struct type *sph_root; /* root of the tree */ \
67
+ }
68
+
69
+ #define SPLAY_INITIALIZER(root) \
70
+ { NULL }
71
+
72
+ #define SPLAY_INIT(root) do { \
73
+ (root)->sph_root = NULL; \
74
+ } while (/*CONSTCOND*/ 0)
75
+
76
+ #define SPLAY_ENTRY(type) \
77
+ struct { \
78
+ struct type *spe_left; /* left element */ \
79
+ struct type *spe_right; /* right element */ \
80
+ }
81
+
82
+ #define SPLAY_LEFT(elm, field) (elm)->field.spe_left
83
+ #define SPLAY_RIGHT(elm, field) (elm)->field.spe_right
84
+ #define SPLAY_ROOT(head) (head)->sph_root
85
+ #define SPLAY_EMPTY(head) (SPLAY_ROOT(head) == NULL)
86
+
87
+ /* SPLAY_ROTATE_{LEFT,RIGHT} expect that tmp hold SPLAY_{RIGHT,LEFT} */
88
+ #define SPLAY_ROTATE_RIGHT(head, tmp, field) do { \
89
+ SPLAY_LEFT((head)->sph_root, field) = SPLAY_RIGHT(tmp, field); \
90
+ SPLAY_RIGHT(tmp, field) = (head)->sph_root; \
91
+ (head)->sph_root = tmp; \
92
+ } while (/*CONSTCOND*/ 0)
93
+
94
+ #define SPLAY_ROTATE_LEFT(head, tmp, field) do { \
95
+ SPLAY_RIGHT((head)->sph_root, field) = SPLAY_LEFT(tmp, field); \
96
+ SPLAY_LEFT(tmp, field) = (head)->sph_root; \
97
+ (head)->sph_root = tmp; \
98
+ } while (/*CONSTCOND*/ 0)
99
+
100
+ #define SPLAY_LINKLEFT(head, tmp, field) do { \
101
+ SPLAY_LEFT(tmp, field) = (head)->sph_root; \
102
+ tmp = (head)->sph_root; \
103
+ (head)->sph_root = SPLAY_LEFT((head)->sph_root, field); \
104
+ } while (/*CONSTCOND*/ 0)
105
+
106
+ #define SPLAY_LINKRIGHT(head, tmp, field) do { \
107
+ SPLAY_RIGHT(tmp, field) = (head)->sph_root; \
108
+ tmp = (head)->sph_root; \
109
+ (head)->sph_root = SPLAY_RIGHT((head)->sph_root, field); \
110
+ } while (/*CONSTCOND*/ 0)
111
+
112
+ #define SPLAY_ASSEMBLE(head, node, left, right, field) do { \
113
+ SPLAY_RIGHT(left, field) = SPLAY_LEFT((head)->sph_root, field); \
114
+ SPLAY_LEFT(right, field) = SPLAY_RIGHT((head)->sph_root, field); \
115
+ SPLAY_LEFT((head)->sph_root, field) = SPLAY_RIGHT(node, field); \
116
+ SPLAY_RIGHT((head)->sph_root, field) = SPLAY_LEFT(node, field); \
117
+ } while (/*CONSTCOND*/ 0)
118
+
119
+ /* Generates prototypes and inline functions */
120
+
121
+ #define SPLAY_PROTOTYPE(name, type, field, cmp) \
122
+ void name##_SPLAY(struct name *, struct type *); \
123
+ void name##_SPLAY_MINMAX(struct name *, int); \
124
+ struct type *name##_SPLAY_INSERT(struct name *, struct type *); \
125
+ struct type *name##_SPLAY_REMOVE(struct name *, struct type *); \
126
+ \
127
+ /* Finds the node with the same key as elm */ \
128
+ static __inline struct type * \
129
+ name##_SPLAY_FIND(struct name *head, struct type *elm) \
130
+ { \
131
+ if (SPLAY_EMPTY(head)) \
132
+ return(NULL); \
133
+ name##_SPLAY(head, elm); \
134
+ if ((cmp)(elm, (head)->sph_root) == 0) \
135
+ return (head->sph_root); \
136
+ return (NULL); \
137
+ } \
138
+ \
139
+ static __inline struct type * \
140
+ name##_SPLAY_NEXT(struct name *head, struct type *elm) \
141
+ { \
142
+ name##_SPLAY(head, elm); \
143
+ if (SPLAY_RIGHT(elm, field) != NULL) { \
144
+ elm = SPLAY_RIGHT(elm, field); \
145
+ while (SPLAY_LEFT(elm, field) != NULL) { \
146
+ elm = SPLAY_LEFT(elm, field); \
147
+ } \
148
+ } else \
149
+ elm = NULL; \
150
+ return (elm); \
151
+ } \
152
+ \
153
+ static __inline struct type * \
154
+ name##_SPLAY_MIN_MAX(struct name *head, int val) \
155
+ { \
156
+ name##_SPLAY_MINMAX(head, val); \
157
+ return (SPLAY_ROOT(head)); \
158
+ }
159
+
160
+ /* Main splay operation.
161
+ * Moves node close to the key of elm to top
162
+ */
163
+ #define SPLAY_GENERATE(name, type, field, cmp) \
164
+ struct type * \
165
+ name##_SPLAY_INSERT(struct name *head, struct type *elm) \
166
+ { \
167
+ if (SPLAY_EMPTY(head)) { \
168
+ SPLAY_LEFT(elm, field) = SPLAY_RIGHT(elm, field) = NULL; \
169
+ } else { \
170
+ int __comp; \
171
+ name##_SPLAY(head, elm); \
172
+ __comp = (cmp)(elm, (head)->sph_root); \
173
+ if(__comp < 0) { \
174
+ SPLAY_LEFT(elm, field) = SPLAY_LEFT((head)->sph_root, field); \
175
+ SPLAY_RIGHT(elm, field) = (head)->sph_root; \
176
+ SPLAY_LEFT((head)->sph_root, field) = NULL; \
177
+ } else if (__comp > 0) { \
178
+ SPLAY_RIGHT(elm, field) = SPLAY_RIGHT((head)->sph_root, field); \
179
+ SPLAY_LEFT(elm, field) = (head)->sph_root; \
180
+ SPLAY_RIGHT((head)->sph_root, field) = NULL; \
181
+ } else \
182
+ return ((head)->sph_root); \
183
+ } \
184
+ (head)->sph_root = (elm); \
185
+ return (NULL); \
186
+ } \
187
+ \
188
+ struct type * \
189
+ name##_SPLAY_REMOVE(struct name *head, struct type *elm) \
190
+ { \
191
+ struct type *__tmp; \
192
+ if (SPLAY_EMPTY(head)) \
193
+ return (NULL); \
194
+ name##_SPLAY(head, elm); \
195
+ if ((cmp)(elm, (head)->sph_root) == 0) { \
196
+ if (SPLAY_LEFT((head)->sph_root, field) == NULL) { \
197
+ (head)->sph_root = SPLAY_RIGHT((head)->sph_root, field); \
198
+ } else { \
199
+ __tmp = SPLAY_RIGHT((head)->sph_root, field); \
200
+ (head)->sph_root = SPLAY_LEFT((head)->sph_root, field); \
201
+ name##_SPLAY(head, elm); \
202
+ SPLAY_RIGHT((head)->sph_root, field) = __tmp; \
203
+ } \
204
+ return (elm); \
205
+ } \
206
+ return (NULL); \
207
+ } \
208
+ \
209
+ void \
210
+ name##_SPLAY(struct name *head, struct type *elm) \
211
+ { \
212
+ struct type __node, *__left, *__right, *__tmp; \
213
+ int __comp; \
214
+ \
215
+ SPLAY_LEFT(&__node, field) = SPLAY_RIGHT(&__node, field) = NULL; \
216
+ __left = __right = &__node; \
217
+ \
218
+ while ((__comp = (cmp)(elm, (head)->sph_root)) != 0) { \
219
+ if (__comp < 0) { \
220
+ __tmp = SPLAY_LEFT((head)->sph_root, field); \
221
+ if (__tmp == NULL) \
222
+ break; \
223
+ if ((cmp)(elm, __tmp) < 0){ \
224
+ SPLAY_ROTATE_RIGHT(head, __tmp, field); \
225
+ if (SPLAY_LEFT((head)->sph_root, field) == NULL) \
226
+ break; \
227
+ } \
228
+ SPLAY_LINKLEFT(head, __right, field); \
229
+ } else if (__comp > 0) { \
230
+ __tmp = SPLAY_RIGHT((head)->sph_root, field); \
231
+ if (__tmp == NULL) \
232
+ break; \
233
+ if ((cmp)(elm, __tmp) > 0){ \
234
+ SPLAY_ROTATE_LEFT(head, __tmp, field); \
235
+ if (SPLAY_RIGHT((head)->sph_root, field) == NULL) \
236
+ break; \
237
+ } \
238
+ SPLAY_LINKRIGHT(head, __left, field); \
239
+ } \
240
+ } \
241
+ SPLAY_ASSEMBLE(head, &__node, __left, __right, field); \
242
+ } \
243
+ \
244
+ /* Splay with either the minimum or the maximum element \
245
+ * Used to find minimum or maximum element in tree. \
246
+ */ \
247
+ void name##_SPLAY_MINMAX(struct name *head, int __comp) \
248
+ { \
249
+ struct type __node, *__left, *__right, *__tmp; \
250
+ \
251
+ SPLAY_LEFT(&__node, field) = SPLAY_RIGHT(&__node, field) = NULL; \
252
+ __left = __right = &__node; \
253
+ \
254
+ while (1) { \
255
+ if (__comp < 0) { \
256
+ __tmp = SPLAY_LEFT((head)->sph_root, field); \
257
+ if (__tmp == NULL) \
258
+ break; \
259
+ if (__comp < 0){ \
260
+ SPLAY_ROTATE_RIGHT(head, __tmp, field); \
261
+ if (SPLAY_LEFT((head)->sph_root, field) == NULL) \
262
+ break; \
263
+ } \
264
+ SPLAY_LINKLEFT(head, __right, field); \
265
+ } else if (__comp > 0) { \
266
+ __tmp = SPLAY_RIGHT((head)->sph_root, field); \
267
+ if (__tmp == NULL) \
268
+ break; \
269
+ if (__comp > 0) { \
270
+ SPLAY_ROTATE_LEFT(head, __tmp, field); \
271
+ if (SPLAY_RIGHT((head)->sph_root, field) == NULL) \
272
+ break; \
273
+ } \
274
+ SPLAY_LINKRIGHT(head, __left, field); \
275
+ } \
276
+ } \
277
+ SPLAY_ASSEMBLE(head, &__node, __left, __right, field); \
278
+ }
279
+
280
+ #define SPLAY_NEGINF -1
281
+ #define SPLAY_INF 1
282
+
283
+ #define SPLAY_INSERT(name, x, y) name##_SPLAY_INSERT(x, y)
284
+ #define SPLAY_REMOVE(name, x, y) name##_SPLAY_REMOVE(x, y)
285
+ #define SPLAY_FIND(name, x, y) name##_SPLAY_FIND(x, y)
286
+ #define SPLAY_NEXT(name, x, y) name##_SPLAY_NEXT(x, y)
287
+ #define SPLAY_MIN(name, x) (SPLAY_EMPTY(x) ? NULL \
288
+ : name##_SPLAY_MIN_MAX(x, SPLAY_NEGINF))
289
+ #define SPLAY_MAX(name, x) (SPLAY_EMPTY(x) ? NULL \
290
+ : name##_SPLAY_MIN_MAX(x, SPLAY_INF))
291
+
292
+ #define SPLAY_FOREACH(x, name, head) \
293
+ for ((x) = SPLAY_MIN(name, head); \
294
+ (x) != NULL; \
295
+ (x) = SPLAY_NEXT(name, head, x))
296
+
297
+ /* Macros that define a red-black tree */
298
+ #define RB_HEAD(name, type) \
299
+ struct name { \
300
+ struct type *rbh_root; /* root of the tree */ \
301
+ }
302
+
303
+ #define RB_INITIALIZER(root) \
304
+ { NULL }
305
+
306
+ #define RB_INIT(root) do { \
307
+ (root)->rbh_root = NULL; \
308
+ } while (/*CONSTCOND*/ 0)
309
+
310
+ #define RB_BLACK 0
311
+ #define RB_RED 1
312
+ #define RB_ENTRY(type) \
313
+ struct { \
314
+ struct type *rbe_left; /* left element */ \
315
+ struct type *rbe_right; /* right element */ \
316
+ struct type *rbe_parent; /* parent element */ \
317
+ int rbe_color; /* node color */ \
318
+ }
319
+
320
+ #define RB_LEFT(elm, field) (elm)->field.rbe_left
321
+ #define RB_RIGHT(elm, field) (elm)->field.rbe_right
322
+ #define RB_PARENT(elm, field) (elm)->field.rbe_parent
323
+ #define RB_COLOR(elm, field) (elm)->field.rbe_color
324
+ #define RB_ROOT(head) (head)->rbh_root
325
+ #define RB_EMPTY(head) (RB_ROOT(head) == NULL)
326
+
327
+ #define RB_SET(elm, parent, field) do { \
328
+ RB_PARENT(elm, field) = parent; \
329
+ RB_LEFT(elm, field) = RB_RIGHT(elm, field) = NULL; \
330
+ RB_COLOR(elm, field) = RB_RED; \
331
+ } while (/*CONSTCOND*/ 0)
332
+
333
+ #define RB_SET_BLACKRED(black, red, field) do { \
334
+ RB_COLOR(black, field) = RB_BLACK; \
335
+ RB_COLOR(red, field) = RB_RED; \
336
+ } while (/*CONSTCOND*/ 0)
337
+
338
+ #ifndef RB_AUGMENT
339
+ #define RB_AUGMENT(x) do {} while (0)
340
+ #endif
341
+
342
+ #define RB_ROTATE_LEFT(head, elm, tmp, field) do { \
343
+ (tmp) = RB_RIGHT(elm, field); \
344
+ if ((RB_RIGHT(elm, field) = RB_LEFT(tmp, field)) != NULL) { \
345
+ RB_PARENT(RB_LEFT(tmp, field), field) = (elm); \
346
+ } \
347
+ RB_AUGMENT(elm); \
348
+ if ((RB_PARENT(tmp, field) = RB_PARENT(elm, field)) != NULL) { \
349
+ if ((elm) == RB_LEFT(RB_PARENT(elm, field), field)) \
350
+ RB_LEFT(RB_PARENT(elm, field), field) = (tmp); \
351
+ else \
352
+ RB_RIGHT(RB_PARENT(elm, field), field) = (tmp); \
353
+ } else \
354
+ (head)->rbh_root = (tmp); \
355
+ RB_LEFT(tmp, field) = (elm); \
356
+ RB_PARENT(elm, field) = (tmp); \
357
+ RB_AUGMENT(tmp); \
358
+ if ((RB_PARENT(tmp, field))) \
359
+ RB_AUGMENT(RB_PARENT(tmp, field)); \
360
+ } while (/*CONSTCOND*/ 0)
361
+
362
+ #define RB_ROTATE_RIGHT(head, elm, tmp, field) do { \
363
+ (tmp) = RB_LEFT(elm, field); \
364
+ if ((RB_LEFT(elm, field) = RB_RIGHT(tmp, field)) != NULL) { \
365
+ RB_PARENT(RB_RIGHT(tmp, field), field) = (elm); \
366
+ } \
367
+ RB_AUGMENT(elm); \
368
+ if ((RB_PARENT(tmp, field) = RB_PARENT(elm, field)) != NULL) { \
369
+ if ((elm) == RB_LEFT(RB_PARENT(elm, field), field)) \
370
+ RB_LEFT(RB_PARENT(elm, field), field) = (tmp); \
371
+ else \
372
+ RB_RIGHT(RB_PARENT(elm, field), field) = (tmp); \
373
+ } else \
374
+ (head)->rbh_root = (tmp); \
375
+ RB_RIGHT(tmp, field) = (elm); \
376
+ RB_PARENT(elm, field) = (tmp); \
377
+ RB_AUGMENT(tmp); \
378
+ if ((RB_PARENT(tmp, field))) \
379
+ RB_AUGMENT(RB_PARENT(tmp, field)); \
380
+ } while (/*CONSTCOND*/ 0)
381
+
382
+ /* Generates prototypes and inline functions */
383
+ #define RB_PROTOTYPE(name, type, field, cmp) \
384
+ RB_PROTOTYPE_INTERNAL(name, type, field, cmp,)
385
+ #define RB_PROTOTYPE_STATIC(name, type, field, cmp) \
386
+ RB_PROTOTYPE_INTERNAL(name, type, field, cmp, UV__UNUSED static)
387
+ #define RB_PROTOTYPE_INTERNAL(name, type, field, cmp, attr) \
388
+ attr void name##_RB_INSERT_COLOR(struct name *, struct type *); \
389
+ attr void name##_RB_REMOVE_COLOR(struct name *, struct type *, struct type *);\
390
+ attr struct type *name##_RB_REMOVE(struct name *, struct type *); \
391
+ attr struct type *name##_RB_INSERT(struct name *, struct type *); \
392
+ attr struct type *name##_RB_FIND(struct name *, struct type *); \
393
+ attr struct type *name##_RB_NFIND(struct name *, struct type *); \
394
+ attr struct type *name##_RB_NEXT(struct type *); \
395
+ attr struct type *name##_RB_PREV(struct type *); \
396
+ attr struct type *name##_RB_MINMAX(struct name *, int); \
397
+ \
398
+
399
+ /* Main rb operation.
400
+ * Moves node close to the key of elm to top
401
+ */
402
+ #define RB_GENERATE(name, type, field, cmp) \
403
+ RB_GENERATE_INTERNAL(name, type, field, cmp,)
404
+ #define RB_GENERATE_STATIC(name, type, field, cmp) \
405
+ RB_GENERATE_INTERNAL(name, type, field, cmp, UV__UNUSED static)
406
+ #define RB_GENERATE_INTERNAL(name, type, field, cmp, attr) \
407
+ attr void \
408
+ name##_RB_INSERT_COLOR(struct name *head, struct type *elm) \
409
+ { \
410
+ struct type *parent, *gparent, *tmp; \
411
+ while ((parent = RB_PARENT(elm, field)) != NULL && \
412
+ RB_COLOR(parent, field) == RB_RED) { \
413
+ gparent = RB_PARENT(parent, field); \
414
+ if (parent == RB_LEFT(gparent, field)) { \
415
+ tmp = RB_RIGHT(gparent, field); \
416
+ if (tmp && RB_COLOR(tmp, field) == RB_RED) { \
417
+ RB_COLOR(tmp, field) = RB_BLACK; \
418
+ RB_SET_BLACKRED(parent, gparent, field); \
419
+ elm = gparent; \
420
+ continue; \
421
+ } \
422
+ if (RB_RIGHT(parent, field) == elm) { \
423
+ RB_ROTATE_LEFT(head, parent, tmp, field); \
424
+ tmp = parent; \
425
+ parent = elm; \
426
+ elm = tmp; \
427
+ } \
428
+ RB_SET_BLACKRED(parent, gparent, field); \
429
+ RB_ROTATE_RIGHT(head, gparent, tmp, field); \
430
+ } else { \
431
+ tmp = RB_LEFT(gparent, field); \
432
+ if (tmp && RB_COLOR(tmp, field) == RB_RED) { \
433
+ RB_COLOR(tmp, field) = RB_BLACK; \
434
+ RB_SET_BLACKRED(parent, gparent, field); \
435
+ elm = gparent; \
436
+ continue; \
437
+ } \
438
+ if (RB_LEFT(parent, field) == elm) { \
439
+ RB_ROTATE_RIGHT(head, parent, tmp, field); \
440
+ tmp = parent; \
441
+ parent = elm; \
442
+ elm = tmp; \
443
+ } \
444
+ RB_SET_BLACKRED(parent, gparent, field); \
445
+ RB_ROTATE_LEFT(head, gparent, tmp, field); \
446
+ } \
447
+ } \
448
+ RB_COLOR(head->rbh_root, field) = RB_BLACK; \
449
+ } \
450
+ \
451
+ attr void \
452
+ name##_RB_REMOVE_COLOR(struct name *head, struct type *parent, \
453
+ struct type *elm) \
454
+ { \
455
+ struct type *tmp; \
456
+ while ((elm == NULL || RB_COLOR(elm, field) == RB_BLACK) && \
457
+ elm != RB_ROOT(head)) { \
458
+ if (RB_LEFT(parent, field) == elm) { \
459
+ tmp = RB_RIGHT(parent, field); \
460
+ if (RB_COLOR(tmp, field) == RB_RED) { \
461
+ RB_SET_BLACKRED(tmp, parent, field); \
462
+ RB_ROTATE_LEFT(head, parent, tmp, field); \
463
+ tmp = RB_RIGHT(parent, field); \
464
+ } \
465
+ if ((RB_LEFT(tmp, field) == NULL || \
466
+ RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) && \
467
+ (RB_RIGHT(tmp, field) == NULL || \
468
+ RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK)) { \
469
+ RB_COLOR(tmp, field) = RB_RED; \
470
+ elm = parent; \
471
+ parent = RB_PARENT(elm, field); \
472
+ } else { \
473
+ if (RB_RIGHT(tmp, field) == NULL || \
474
+ RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK) { \
475
+ struct type *oleft; \
476
+ if ((oleft = RB_LEFT(tmp, field)) \
477
+ != NULL) \
478
+ RB_COLOR(oleft, field) = RB_BLACK; \
479
+ RB_COLOR(tmp, field) = RB_RED; \
480
+ RB_ROTATE_RIGHT(head, tmp, oleft, field); \
481
+ tmp = RB_RIGHT(parent, field); \
482
+ } \
483
+ RB_COLOR(tmp, field) = RB_COLOR(parent, field); \
484
+ RB_COLOR(parent, field) = RB_BLACK; \
485
+ if (RB_RIGHT(tmp, field)) \
486
+ RB_COLOR(RB_RIGHT(tmp, field), field) = RB_BLACK; \
487
+ RB_ROTATE_LEFT(head, parent, tmp, field); \
488
+ elm = RB_ROOT(head); \
489
+ break; \
490
+ } \
491
+ } else { \
492
+ tmp = RB_LEFT(parent, field); \
493
+ if (RB_COLOR(tmp, field) == RB_RED) { \
494
+ RB_SET_BLACKRED(tmp, parent, field); \
495
+ RB_ROTATE_RIGHT(head, parent, tmp, field); \
496
+ tmp = RB_LEFT(parent, field); \
497
+ } \
498
+ if ((RB_LEFT(tmp, field) == NULL || \
499
+ RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) && \
500
+ (RB_RIGHT(tmp, field) == NULL || \
501
+ RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK)) { \
502
+ RB_COLOR(tmp, field) = RB_RED; \
503
+ elm = parent; \
504
+ parent = RB_PARENT(elm, field); \
505
+ } else { \
506
+ if (RB_LEFT(tmp, field) == NULL || \
507
+ RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) { \
508
+ struct type *oright; \
509
+ if ((oright = RB_RIGHT(tmp, field)) \
510
+ != NULL) \
511
+ RB_COLOR(oright, field) = RB_BLACK; \
512
+ RB_COLOR(tmp, field) = RB_RED; \
513
+ RB_ROTATE_LEFT(head, tmp, oright, field); \
514
+ tmp = RB_LEFT(parent, field); \
515
+ } \
516
+ RB_COLOR(tmp, field) = RB_COLOR(parent, field); \
517
+ RB_COLOR(parent, field) = RB_BLACK; \
518
+ if (RB_LEFT(tmp, field)) \
519
+ RB_COLOR(RB_LEFT(tmp, field), field) = RB_BLACK; \
520
+ RB_ROTATE_RIGHT(head, parent, tmp, field); \
521
+ elm = RB_ROOT(head); \
522
+ break; \
523
+ } \
524
+ } \
525
+ } \
526
+ if (elm) \
527
+ RB_COLOR(elm, field) = RB_BLACK; \
528
+ } \
529
+ \
530
+ attr struct type * \
531
+ name##_RB_REMOVE(struct name *head, struct type *elm) \
532
+ { \
533
+ struct type *child, *parent, *old = elm; \
534
+ int color; \
535
+ if (RB_LEFT(elm, field) == NULL) \
536
+ child = RB_RIGHT(elm, field); \
537
+ else if (RB_RIGHT(elm, field) == NULL) \
538
+ child = RB_LEFT(elm, field); \
539
+ else { \
540
+ struct type *left; \
541
+ elm = RB_RIGHT(elm, field); \
542
+ while ((left = RB_LEFT(elm, field)) != NULL) \
543
+ elm = left; \
544
+ child = RB_RIGHT(elm, field); \
545
+ parent = RB_PARENT(elm, field); \
546
+ color = RB_COLOR(elm, field); \
547
+ if (child) \
548
+ RB_PARENT(child, field) = parent; \
549
+ if (parent) { \
550
+ if (RB_LEFT(parent, field) == elm) \
551
+ RB_LEFT(parent, field) = child; \
552
+ else \
553
+ RB_RIGHT(parent, field) = child; \
554
+ RB_AUGMENT(parent); \
555
+ } else \
556
+ RB_ROOT(head) = child; \
557
+ if (RB_PARENT(elm, field) == old) \
558
+ parent = elm; \
559
+ (elm)->field = (old)->field; \
560
+ if (RB_PARENT(old, field)) { \
561
+ if (RB_LEFT(RB_PARENT(old, field), field) == old) \
562
+ RB_LEFT(RB_PARENT(old, field), field) = elm; \
563
+ else \
564
+ RB_RIGHT(RB_PARENT(old, field), field) = elm; \
565
+ RB_AUGMENT(RB_PARENT(old, field)); \
566
+ } else \
567
+ RB_ROOT(head) = elm; \
568
+ RB_PARENT(RB_LEFT(old, field), field) = elm; \
569
+ if (RB_RIGHT(old, field)) \
570
+ RB_PARENT(RB_RIGHT(old, field), field) = elm; \
571
+ if (parent) { \
572
+ left = parent; \
573
+ do { \
574
+ RB_AUGMENT(left); \
575
+ } while ((left = RB_PARENT(left, field)) != NULL); \
576
+ } \
577
+ goto color; \
578
+ } \
579
+ parent = RB_PARENT(elm, field); \
580
+ color = RB_COLOR(elm, field); \
581
+ if (child) \
582
+ RB_PARENT(child, field) = parent; \
583
+ if (parent) { \
584
+ if (RB_LEFT(parent, field) == elm) \
585
+ RB_LEFT(parent, field) = child; \
586
+ else \
587
+ RB_RIGHT(parent, field) = child; \
588
+ RB_AUGMENT(parent); \
589
+ } else \
590
+ RB_ROOT(head) = child; \
591
+ color: \
592
+ if (color == RB_BLACK) \
593
+ name##_RB_REMOVE_COLOR(head, parent, child); \
594
+ return (old); \
595
+ } \
596
+ \
597
+ /* Inserts a node into the RB tree */ \
598
+ attr struct type * \
599
+ name##_RB_INSERT(struct name *head, struct type *elm) \
600
+ { \
601
+ struct type *tmp; \
602
+ struct type *parent = NULL; \
603
+ int comp = 0; \
604
+ tmp = RB_ROOT(head); \
605
+ while (tmp) { \
606
+ parent = tmp; \
607
+ comp = (cmp)(elm, parent); \
608
+ if (comp < 0) \
609
+ tmp = RB_LEFT(tmp, field); \
610
+ else if (comp > 0) \
611
+ tmp = RB_RIGHT(tmp, field); \
612
+ else \
613
+ return (tmp); \
614
+ } \
615
+ RB_SET(elm, parent, field); \
616
+ if (parent != NULL) { \
617
+ if (comp < 0) \
618
+ RB_LEFT(parent, field) = elm; \
619
+ else \
620
+ RB_RIGHT(parent, field) = elm; \
621
+ RB_AUGMENT(parent); \
622
+ } else \
623
+ RB_ROOT(head) = elm; \
624
+ name##_RB_INSERT_COLOR(head, elm); \
625
+ return (NULL); \
626
+ } \
627
+ \
628
+ /* Finds the node with the same key as elm */ \
629
+ attr struct type * \
630
+ name##_RB_FIND(struct name *head, struct type *elm) \
631
+ { \
632
+ struct type *tmp = RB_ROOT(head); \
633
+ int comp; \
634
+ while (tmp) { \
635
+ comp = cmp(elm, tmp); \
636
+ if (comp < 0) \
637
+ tmp = RB_LEFT(tmp, field); \
638
+ else if (comp > 0) \
639
+ tmp = RB_RIGHT(tmp, field); \
640
+ else \
641
+ return (tmp); \
642
+ } \
643
+ return (NULL); \
644
+ } \
645
+ \
646
+ /* Finds the first node greater than or equal to the search key */ \
647
+ attr struct type * \
648
+ name##_RB_NFIND(struct name *head, struct type *elm) \
649
+ { \
650
+ struct type *tmp = RB_ROOT(head); \
651
+ struct type *res = NULL; \
652
+ int comp; \
653
+ while (tmp) { \
654
+ comp = cmp(elm, tmp); \
655
+ if (comp < 0) { \
656
+ res = tmp; \
657
+ tmp = RB_LEFT(tmp, field); \
658
+ } \
659
+ else if (comp > 0) \
660
+ tmp = RB_RIGHT(tmp, field); \
661
+ else \
662
+ return (tmp); \
663
+ } \
664
+ return (res); \
665
+ } \
666
+ \
667
+ /* ARGSUSED */ \
668
+ attr struct type * \
669
+ name##_RB_NEXT(struct type *elm) \
670
+ { \
671
+ if (RB_RIGHT(elm, field)) { \
672
+ elm = RB_RIGHT(elm, field); \
673
+ while (RB_LEFT(elm, field)) \
674
+ elm = RB_LEFT(elm, field); \
675
+ } else { \
676
+ if (RB_PARENT(elm, field) && \
677
+ (elm == RB_LEFT(RB_PARENT(elm, field), field))) \
678
+ elm = RB_PARENT(elm, field); \
679
+ else { \
680
+ while (RB_PARENT(elm, field) && \
681
+ (elm == RB_RIGHT(RB_PARENT(elm, field), field))) \
682
+ elm = RB_PARENT(elm, field); \
683
+ elm = RB_PARENT(elm, field); \
684
+ } \
685
+ } \
686
+ return (elm); \
687
+ } \
688
+ \
689
+ /* ARGSUSED */ \
690
+ attr struct type * \
691
+ name##_RB_PREV(struct type *elm) \
692
+ { \
693
+ if (RB_LEFT(elm, field)) { \
694
+ elm = RB_LEFT(elm, field); \
695
+ while (RB_RIGHT(elm, field)) \
696
+ elm = RB_RIGHT(elm, field); \
697
+ } else { \
698
+ if (RB_PARENT(elm, field) && \
699
+ (elm == RB_RIGHT(RB_PARENT(elm, field), field))) \
700
+ elm = RB_PARENT(elm, field); \
701
+ else { \
702
+ while (RB_PARENT(elm, field) && \
703
+ (elm == RB_LEFT(RB_PARENT(elm, field), field))) \
704
+ elm = RB_PARENT(elm, field); \
705
+ elm = RB_PARENT(elm, field); \
706
+ } \
707
+ } \
708
+ return (elm); \
709
+ } \
710
+ \
711
+ attr struct type * \
712
+ name##_RB_MINMAX(struct name *head, int val) \
713
+ { \
714
+ struct type *tmp = RB_ROOT(head); \
715
+ struct type *parent = NULL; \
716
+ while (tmp) { \
717
+ parent = tmp; \
718
+ if (val < 0) \
719
+ tmp = RB_LEFT(tmp, field); \
720
+ else \
721
+ tmp = RB_RIGHT(tmp, field); \
722
+ } \
723
+ return (parent); \
724
+ }
725
+
726
+ #define RB_NEGINF -1
727
+ #define RB_INF 1
728
+
729
+ #define RB_INSERT(name, x, y) name##_RB_INSERT(x, y)
730
+ #define RB_REMOVE(name, x, y) name##_RB_REMOVE(x, y)
731
+ #define RB_FIND(name, x, y) name##_RB_FIND(x, y)
732
+ #define RB_NFIND(name, x, y) name##_RB_NFIND(x, y)
733
+ #define RB_NEXT(name, x, y) name##_RB_NEXT(y)
734
+ #define RB_PREV(name, x, y) name##_RB_PREV(y)
735
+ #define RB_MIN(name, x) name##_RB_MINMAX(x, RB_NEGINF)
736
+ #define RB_MAX(name, x) name##_RB_MINMAX(x, RB_INF)
737
+
738
+ #define RB_FOREACH(x, name, head) \
739
+ for ((x) = RB_MIN(name, head); \
740
+ (x) != NULL; \
741
+ (x) = name##_RB_NEXT(x))
742
+
743
+ #define RB_FOREACH_FROM(x, name, y) \
744
+ for ((x) = (y); \
745
+ ((x) != NULL) && ((y) = name##_RB_NEXT(x), (x) != NULL); \
746
+ (x) = (y))
747
+
748
+ #define RB_FOREACH_SAFE(x, name, head, y) \
749
+ for ((x) = RB_MIN(name, head); \
750
+ ((x) != NULL) && ((y) = name##_RB_NEXT(x), (x) != NULL); \
751
+ (x) = (y))
752
+
753
+ #define RB_FOREACH_REVERSE(x, name, head) \
754
+ for ((x) = RB_MAX(name, head); \
755
+ (x) != NULL; \
756
+ (x) = name##_RB_PREV(x))
757
+
758
+ #define RB_FOREACH_REVERSE_FROM(x, name, y) \
759
+ for ((x) = (y); \
760
+ ((x) != NULL) && ((y) = name##_RB_PREV(x), (x) != NULL); \
761
+ (x) = (y))
762
+
763
+ #define RB_FOREACH_REVERSE_SAFE(x, name, head, y) \
764
+ for ((x) = RB_MAX(name, head); \
765
+ ((x) != NULL) && ((y) = name##_RB_PREV(x), (x) != NULL); \
766
+ (x) = (y))
767
+
768
+ #endif /* UV_TREE_H_ */