IOWA 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (502) hide show
  1. checksums.yaml +7 -0
  2. data/CONTRIBUTORS +14 -0
  3. data/README.md +23 -0
  4. data/RELEASE_NOTES +77 -0
  5. data/ToDo +21 -0
  6. data/components/CRUDList/CRUDList.html +13 -0
  7. data/components/CRUDList/CRUDList.iwa +136 -0
  8. data/components/Content/Content.html +0 -0
  9. data/components/Content/Content.iwa +143 -0
  10. data/components/Content/example/README +9 -0
  11. data/components/Content/example/cgi/iowa.cgi +10 -0
  12. data/components/Content/example/demo.rb +30 -0
  13. data/components/Content/example/doc/index.html +7 -0
  14. data/components/Content/example/iowa/Content.html +1 -0
  15. data/components/Content/example/iowa/Content.iwa +1 -0
  16. data/components/Content/example/iowa/Main.html +6 -0
  17. data/components/Content/example/iowa/Main.iwa +3 -0
  18. data/components/Content/example/iowa/_content/body +7 -0
  19. data/components/Content/example/iowa/_content/body2 +3 -0
  20. data/components/Content/example/iowa/_content/title +2 -0
  21. data/components/Content/example/iowa/app.cnf +8 -0
  22. data/components/Content/example/iowa/app.rb +8 -0
  23. data/components/Content/example/webrick.rb +38 -0
  24. data/components/Include/Include.html +1 -0
  25. data/components/Include/Include.iwa +30 -0
  26. data/components/Include/readme +5 -0
  27. data/components/JumpTo/JumpTo.html +8 -0
  28. data/components/JumpTo/JumpTo.iwa +8 -0
  29. data/components/JumpTo/readme +6 -0
  30. data/doc/Architecture.txt +6 -0
  31. data/doc/History.txt +33 -0
  32. data/doc/StandardDispatcher.txt +19 -0
  33. data/examples/blog/README +1 -0
  34. data/examples/hello_world/README +17 -0
  35. data/examples/hello_world/htdocs/hello_world_html.html +24 -0
  36. data/examples/hello_world/htdocs/hello_world_ruby.html +41 -0
  37. data/examples/hello_world/iowa/HelloWorld.html +14 -0
  38. data/examples/hello_world/iowa/HelloWorld.iwa +31 -0
  39. data/examples/hello_world/iowa/Index.html +16 -0
  40. data/examples/hello_world/iowa/Index.iwa +5 -0
  41. data/examples/hello_world/iowa/iowa_hello_world.cnf +19 -0
  42. data/examples/hello_world/iowa/iowa_hello_world.rb +5 -0
  43. data/examples/hello_world/iowa/mapfile.cnf +6 -0
  44. data/examples/hw1/iowa/Main.html +1 -0
  45. data/examples/hw1/iowa/README +9 -0
  46. data/examples/hw1/iowa/hw.rb +4 -0
  47. data/examples/hw2/iowa/Main.html +10 -0
  48. data/examples/hw2/iowa/Main.iwa +7 -0
  49. data/examples/hw2/iowa/README +16 -0
  50. data/examples/hw2/iowa/hw.rb +4 -0
  51. data/examples/hw3/iowa/Main.html +11 -0
  52. data/examples/hw3/iowa/Main.iwa +7 -0
  53. data/examples/hw3/iowa/README +22 -0
  54. data/examples/hw3/iowa/hw.rb +4 -0
  55. data/examples/hw4/iowa/Greetings.html +10 -0
  56. data/examples/hw4/iowa/Greetings.iwa +9 -0
  57. data/examples/hw4/iowa/Main.html +12 -0
  58. data/examples/hw4/iowa/Main.iwa +10 -0
  59. data/examples/hw4/iowa/README +28 -0
  60. data/examples/hw4/iowa/hw.rb +4 -0
  61. data/examples/hw5/iowa/Footer.html +2 -0
  62. data/examples/hw5/iowa/Greetings.html +4 -0
  63. data/examples/hw5/iowa/Greetings.iwa +12 -0
  64. data/examples/hw5/iowa/Header.html +6 -0
  65. data/examples/hw5/iowa/Main.html +12 -0
  66. data/examples/hw5/iowa/Main.iwa +13 -0
  67. data/examples/hw5/iowa/README +16 -0
  68. data/examples/hw5/iowa/hw.rb +4 -0
  69. data/examples/template_server/iowa/Content.iwa +121 -0
  70. data/examples/template_server/iowa/Content.view +0 -0
  71. data/examples/template_server/iowa/DBContentDispatcher.rb +112 -0
  72. data/examples/template_server/iowa/DBContentPage.html +3 -0
  73. data/examples/template_server/iowa/DBContentPage.iwa +85 -0
  74. data/examples/template_server/iowa/app.cnf +13 -0
  75. data/examples/template_server/iowa/app.rb +5 -0
  76. data/ext/Classifier/classifier.c +256 -0
  77. data/ext/Classifier/ext_help.h +14 -0
  78. data/ext/Classifier/extconf.rb +5 -0
  79. data/ext/Classifier/tst.h +40 -0
  80. data/ext/Classifier/tst_cleanup.c +24 -0
  81. data/ext/Classifier/tst_delete.c +146 -0
  82. data/ext/Classifier/tst_grow_node_free_list.c +38 -0
  83. data/ext/Classifier/tst_init.c +41 -0
  84. data/ext/Classifier/tst_insert.c +192 -0
  85. data/ext/Classifier/tst_search.c +68 -0
  86. data/ext/http11/README +11 -0
  87. data/ext/http11/ext_help.h +15 -0
  88. data/ext/http11/extconf.rb +5 -0
  89. data/ext/http11/http11.c +534 -0
  90. data/ext/http11/http11.c.dif +422 -0
  91. data/ext/http11/http11_parser.c +1243 -0
  92. data/ext/http11/http11_parser.c.dif +193 -0
  93. data/ext/http11/http11_parser.h +49 -0
  94. data/ext/http11/http11_parser.h.dif +20 -0
  95. data/ext/http11/http11_parser.rl +192 -0
  96. data/ext/httpmachine/Makefile +149 -0
  97. data/ext/httpmachine/extconf.rb +33 -0
  98. data/ext/httpmachine/http.cpp +430 -0
  99. data/ext/httpmachine/http.h +156 -0
  100. data/ext/httpmachine/rubyhttp.cpp +165 -0
  101. data/external/mime-types/LICENCE +18 -0
  102. data/external/mime-types/README +46 -0
  103. data/external/mime-types/doc/classes/MIME.html +120 -0
  104. data/external/mime-types/doc/classes/MIME/InvalidContentType.html +119 -0
  105. data/external/mime-types/doc/classes/MIME/Type.html +866 -0
  106. data/external/mime-types/doc/classes/MIME/Type.src/M000010.html +22 -0
  107. data/external/mime-types/doc/classes/MIME/Type.src/M000011.html +18 -0
  108. data/external/mime-types/doc/classes/MIME/Type.src/M000012.html +19 -0
  109. data/external/mime-types/doc/classes/MIME/Type.src/M000013.html +18 -0
  110. data/external/mime-types/doc/classes/MIME/Type.src/M000014.html +26 -0
  111. data/external/mime-types/doc/classes/MIME/Type.src/M000015.html +33 -0
  112. data/external/mime-types/doc/classes/MIME/Type.src/M000016.html +27 -0
  113. data/external/mime-types/doc/classes/MIME/Type.src/M000017.html +35 -0
  114. data/external/mime-types/doc/classes/MIME/Type.src/M000018.html +34 -0
  115. data/external/mime-types/doc/classes/MIME/Type.src/M000019.html +24 -0
  116. data/external/mime-types/doc/classes/MIME/Type.src/M000020.html +38 -0
  117. data/external/mime-types/doc/classes/MIME/Type.src/M000021.html +22 -0
  118. data/external/mime-types/doc/classes/MIME/Type.src/M000022.html +18 -0
  119. data/external/mime-types/doc/classes/MIME/Type.src/M000023.html +18 -0
  120. data/external/mime-types/doc/classes/MIME/Type.src/M000024.html +18 -0
  121. data/external/mime-types/doc/classes/MIME/Type.src/M000025.html +18 -0
  122. data/external/mime-types/doc/classes/MIME/Type.src/M000026.html +18 -0
  123. data/external/mime-types/doc/classes/MIME/Type.src/M000027.html +18 -0
  124. data/external/mime-types/doc/classes/MIME/Type.src/M000028.html +18 -0
  125. data/external/mime-types/doc/classes/MIME/Type.src/M000029.html +18 -0
  126. data/external/mime-types/doc/classes/MIME/Type.src/M000030.html +19 -0
  127. data/external/mime-types/doc/classes/MIME/Type.src/M000031.html +26 -0
  128. data/external/mime-types/doc/classes/MIME/Types.html +459 -0
  129. data/external/mime-types/doc/classes/MIME/Types.src/M000001.html +19 -0
  130. data/external/mime-types/doc/classes/MIME/Types.src/M000002.html +32 -0
  131. data/external/mime-types/doc/classes/MIME/Types.src/M000003.html +21 -0
  132. data/external/mime-types/doc/classes/MIME/Types.src/M000004.html +18 -0
  133. data/external/mime-types/doc/classes/MIME/Types.src/M000005.html +26 -0
  134. data/external/mime-types/doc/classes/MIME/Types.src/M000006.html +18 -0
  135. data/external/mime-types/doc/classes/MIME/Types.src/M000007.html +18 -0
  136. data/external/mime-types/doc/classes/MIME/Types.src/M000008.html +18 -0
  137. data/external/mime-types/doc/classes/MIME/Types.src/M000009.html +18 -0
  138. data/external/mime-types/doc/created.rid +1 -0
  139. data/external/mime-types/doc/files/ChangeLog.html +320 -0
  140. data/external/mime-types/doc/files/README.html +145 -0
  141. data/external/mime-types/doc/files/lib/mime/types_rb.html +101 -0
  142. data/external/mime-types/doc/fr_class_index.html +30 -0
  143. data/external/mime-types/doc/fr_file_index.html +29 -0
  144. data/external/mime-types/doc/fr_method_index.html +57 -0
  145. data/external/mime-types/doc/index.html +24 -0
  146. data/external/mime-types/doc/rdoc-style.css +208 -0
  147. data/external/mime-types/lib/mime/types.rb +1558 -0
  148. data/external/package.rb +672 -0
  149. data/external/test_support.rb +95 -0
  150. data/external/tmail/README +7 -0
  151. data/external/tmail/tmail.rb +4 -0
  152. data/external/tmail/tmail/address.rb +222 -0
  153. data/external/tmail/tmail/base64.rb +52 -0
  154. data/external/tmail/tmail/compat.rb +39 -0
  155. data/external/tmail/tmail/config.rb +50 -0
  156. data/external/tmail/tmail/encode.rb +447 -0
  157. data/external/tmail/tmail/header.rb +895 -0
  158. data/external/tmail/tmail/info.rb +14 -0
  159. data/external/tmail/tmail/loader.rb +1 -0
  160. data/external/tmail/tmail/mail.rb +869 -0
  161. data/external/tmail/tmail/mailbox.rb +386 -0
  162. data/external/tmail/tmail/mbox.rb +1 -0
  163. data/external/tmail/tmail/net.rb +260 -0
  164. data/external/tmail/tmail/obsolete.rb +123 -0
  165. data/external/tmail/tmail/parser.rb +1475 -0
  166. data/external/tmail/tmail/parser.y +372 -0
  167. data/external/tmail/tmail/port.rb +356 -0
  168. data/external/tmail/tmail/scanner.rb +17 -0
  169. data/external/tmail/tmail/scanner_r.rb +243 -0
  170. data/external/tmail/tmail/stringio.rb +256 -0
  171. data/external/tmail/tmail/textutils.rb +197 -0
  172. data/external/tmail/tmail/tmail.rb +1 -0
  173. data/external/tmail/tmail/utils.rb +23 -0
  174. data/external/win32-process/README +133 -0
  175. data/external/win32-process/lib/win32/process.rb +561 -0
  176. data/external/windows-pr/README +145 -0
  177. data/external/windows-pr/doc/conversion_guide.txt +25 -0
  178. data/external/windows-pr/lib/windows/clipboard.rb +72 -0
  179. data/external/windows-pr/lib/windows/console.rb +323 -0
  180. data/external/windows-pr/lib/windows/device_io.rb +88 -0
  181. data/external/windows-pr/lib/windows/directory.rb +80 -0
  182. data/external/windows-pr/lib/windows/error.rb +313 -0
  183. data/external/windows-pr/lib/windows/eventlog.rb +120 -0
  184. data/external/windows-pr/lib/windows/file.rb +349 -0
  185. data/external/windows-pr/lib/windows/filesystem.rb +16 -0
  186. data/external/windows-pr/lib/windows/handle.rb +31 -0
  187. data/external/windows-pr/lib/windows/library.rb +76 -0
  188. data/external/windows-pr/lib/windows/limits.rb +13 -0
  189. data/external/windows-pr/lib/windows/memory.rb +117 -0
  190. data/external/windows-pr/lib/windows/msvcrt/buffer.rb +48 -0
  191. data/external/windows-pr/lib/windows/msvcrt/file.rb +18 -0
  192. data/external/windows-pr/lib/windows/msvcrt/string.rb +46 -0
  193. data/external/windows-pr/lib/windows/national.rb +557 -0
  194. data/external/windows-pr/lib/windows/path.rb +296 -0
  195. data/external/windows-pr/lib/windows/pipe.rb +77 -0
  196. data/external/windows-pr/lib/windows/process.rb +171 -0
  197. data/external/windows-pr/lib/windows/registry.rb +238 -0
  198. data/external/windows-pr/lib/windows/security.rb +89 -0
  199. data/external/windows-pr/lib/windows/service.rb +183 -0
  200. data/external/windows-pr/lib/windows/shell.rb +88 -0
  201. data/external/windows-pr/lib/windows/sound.rb +52 -0
  202. data/external/windows-pr/lib/windows/synchronize.rb +161 -0
  203. data/external/windows-pr/lib/windows/system_info.rb +70 -0
  204. data/external/windows-pr/lib/windows/unicode.rb +138 -0
  205. data/external/windows-pr/lib/windows/window.rb +22 -0
  206. data/iowa.gemspec +45 -0
  207. data/microprojects/DiskCache/LICENSE +28 -0
  208. data/microprojects/DiskCache/README +17 -0
  209. data/microprojects/DiskCache/external/package.rb +608 -0
  210. data/microprojects/DiskCache/external/test_support.rb +8 -0
  211. data/microprojects/DiskCache/setup.rb +22 -0
  212. data/microprojects/DiskCache/src/iowa/Association.rb +67 -0
  213. data/microprojects/DiskCache/src/iowa/Constants.rb +159 -0
  214. data/microprojects/DiskCache/src/iowa/DiskStore.rb +377 -0
  215. data/microprojects/DiskCache/src/iowa/Hash.rb +63 -0
  216. data/microprojects/DiskCache/src/iowa/Lockfile.rb +575 -0
  217. data/microprojects/DiskCache/src/iowa/Mutex.rb +142 -0
  218. data/microprojects/DiskCache/src/iowa/caches/DiskCache.rb +605 -0
  219. data/microprojects/DiskCache/src/iowa/caches/LRUCache.rb +287 -0
  220. data/microprojects/DiskCache/test/TC_DiskCache.rb +218 -0
  221. data/microprojects/LRUCache/LICENSE +28 -0
  222. data/microprojects/LRUCache/README +13 -0
  223. data/microprojects/LRUCache/external/package.rb +608 -0
  224. data/microprojects/LRUCache/external/test_support.rb +8 -0
  225. data/microprojects/LRUCache/setup.rb +22 -0
  226. data/microprojects/LRUCache/src/iowa/Association.rb +57 -0
  227. data/microprojects/LRUCache/src/iowa/Constants.rb +159 -0
  228. data/microprojects/LRUCache/src/iowa/Hash.rb +63 -0
  229. data/microprojects/LRUCache/src/iowa/Mutex.rb +129 -0
  230. data/microprojects/LRUCache/src/iowa/caches/LRUCache.rb +287 -0
  231. data/microprojects/LRUCache/test/TC_LRUCache.rb +65 -0
  232. data/microprojects/LinkedList/LICENSE +28 -0
  233. data/microprojects/LinkedList/README +13 -0
  234. data/microprojects/LinkedList/external/package.rb +608 -0
  235. data/microprojects/LinkedList/external/test_support.rb +8 -0
  236. data/microprojects/LinkedList/setup.rb +22 -0
  237. data/microprojects/LinkedList/src/iowa/LinkedList.rb +165 -0
  238. data/microprojects/LinkedList/test/TC_LinkedList.rb +42 -0
  239. data/microprojects/README +8 -0
  240. data/setup.rb +116 -0
  241. data/share/iowa/app_skeleton/Main.html +8 -0
  242. data/share/iowa/app_skeleton/Main.iwa +15 -0
  243. data/share/iowa/app_skeleton/app.cnf +48 -0
  244. data/share/iowa/app_skeleton/app.rb +58 -0
  245. data/share/iowa/app_skeleton/models/model.rb +49 -0
  246. data/src/ihc.rb +223 -0
  247. data/src/iowa.cgi +29 -0
  248. data/src/iowa.rb +637 -0
  249. data/src/iowa/AbstractCache.rb +96 -0
  250. data/src/iowa/AcceptLanguage.rb +76 -0
  251. data/src/iowa/Application.rb +928 -0
  252. data/src/iowa/ApplicationStats.rb +72 -0
  253. data/src/iowa/Association.rb +67 -0
  254. data/src/iowa/BindingsParser.rb +62 -0
  255. data/src/iowa/Breakpoint.rb +273 -0
  256. data/src/iowa/CSS.rb +564 -0
  257. data/src/iowa/Client.rb +192 -0
  258. data/src/iowa/Component.rb +405 -0
  259. data/src/iowa/ComponentProxy.rb +26 -0
  260. data/src/iowa/Config.rb +21 -0
  261. data/src/iowa/Constants.rb +226 -0
  262. data/src/iowa/Context.rb +218 -0
  263. data/src/iowa/ContextLogger.rb +16 -0
  264. data/src/iowa/DbPool.rb +222 -0
  265. data/src/iowa/DetachedComponent.rb +18 -0
  266. data/src/iowa/Dispatcher.rb +27 -0
  267. data/src/iowa/DynamicElements.rb +471 -0
  268. data/src/iowa/Element.rb +100 -0
  269. data/src/iowa/Email.rb +287 -0
  270. data/src/iowa/Extensions/AllExtensions.rb +4 -0
  271. data/src/iowa/Extensions/Class.rb +94 -0
  272. data/src/iowa/Extensions/Date.rb +88 -0
  273. data/src/iowa/Extensions/DateTime.rb +88 -0
  274. data/src/iowa/Extensions/Hash.rb +22 -0
  275. data/src/iowa/Extensions/Kernel.rb +6 -0
  276. data/src/iowa/Extensions/Numeric.rb +47 -0
  277. data/src/iowa/Extensions/Object.rb +11 -0
  278. data/src/iowa/Extensions/String.rb +60 -0
  279. data/src/iowa/Extensions/Time.rb +89 -0
  280. data/src/iowa/Extensions/TimeExtensions.rb +6 -0
  281. data/src/iowa/Form.rb +368 -0
  282. data/src/iowa/Hash.rb +85 -0
  283. data/src/iowa/ISAAC.rb +175 -0
  284. data/src/iowa/ImageSize.rb +279 -0
  285. data/src/iowa/IowaComponentMixins.rb +7 -0
  286. data/src/iowa/JSON-lexer.rb +296 -0
  287. data/src/iowa/JSON-objects.rb +201 -0
  288. data/src/iowa/KeyValueCoding.rb +91 -0
  289. data/src/iowa/LinkedList.rb +175 -0
  290. data/src/iowa/Loader.rb +22 -0
  291. data/src/iowa/Lockfile.rb +575 -0
  292. data/src/iowa/Logger.rb +74 -0
  293. data/src/iowa/Monkey.rb +20 -0
  294. data/src/iowa/Mutex.rb +142 -0
  295. data/src/iowa/Policy.rb +70 -0
  296. data/src/iowa/Pool.rb +243 -0
  297. data/src/iowa/PrettyException.rb +1091 -0
  298. data/src/iowa/Request.rb +244 -0
  299. data/src/iowa/Response.rb +133 -0
  300. data/src/iowa/Session.rb +354 -0
  301. data/src/iowa/SessionStats.rb +78 -0
  302. data/src/iowa/String.rb +65 -0
  303. data/src/iowa/Tag.rb +101 -0
  304. data/src/iowa/TemplateParser.rb +236 -0
  305. data/src/iowa/Util.rb +314 -0
  306. data/src/iowa/Webcache.rb +122 -0
  307. data/src/iowa/caches/BiLevelCache.rb +65 -0
  308. data/src/iowa/caches/ClassLimitedCache.rb +67 -0
  309. data/src/iowa/caches/DiskCache.rb +609 -0
  310. data/src/iowa/caches/DiskStore.rb +380 -0
  311. data/src/iowa/caches/LRUCache-alternative.rb +155 -0
  312. data/src/iowa/caches/LRUCache.rb +290 -0
  313. data/src/iowa/caches/SimpleLRUCache.rb +112 -0
  314. data/src/iowa/dispatchers/StandardDispatcher.rb +396 -0
  315. data/src/iowa/dispatchers/StandardDispatcherWithClassifier.rb +93 -0
  316. data/src/iowa/js/iowa_jsonrpc.js +381 -0
  317. data/src/iowa/js/jsonrpc.js +187 -0
  318. data/src/iowa/js/jsonrpc_async.js +261 -0
  319. data/src/iowa/loaders/DiskLoader.rb +50 -0
  320. data/src/iowa/loggers/Analogger.rb +54 -0
  321. data/src/iowa/loggers/AsyncLogger.rb +54 -0
  322. data/src/iowa/loggers/BitBucket.rb +38 -0
  323. data/src/iowa/loggers/Log4R.rb +13 -0
  324. data/src/iowa/loggers/Log4rLogger.rb +48 -0
  325. data/src/iowa/loggers/Logger.rb +29 -0
  326. data/src/iowa/loggers/RubyLogger.rb +9 -0
  327. data/src/iowa/pools/DBConnectionPool.rb +53 -0
  328. data/src/iowa/request/Apache.rb +90 -0
  329. data/src/iowa/request/EMHybrid.rb +59 -0
  330. data/src/iowa/request/ENV.rb +80 -0
  331. data/src/iowa/request/FCGI.rb +68 -0
  332. data/src/iowa/request/HTTPMachine.rb +75 -0
  333. data/src/iowa/request/Mongrel.rb +68 -0
  334. data/src/iowa/request/WEBrick.rb +48 -0
  335. data/src/iowa/version.rb +3 -0
  336. data/src/iowa/webrick/HTTPServer.rb +43 -0
  337. data/src/iowa/webrick/WEBrickServlet.rb +28 -0
  338. data/src/iowa_fcgi_handler.rb +101 -0
  339. data/src/iowa_httpmachine.rb +141 -0
  340. data/src/iowa_hybrid.rb +193 -0
  341. data/src/iowa_hybrid_cluster.rb +231 -0
  342. data/src/iowa_mongrel.rb +136 -0
  343. data/src/iowa_webrick.rb +194 -0
  344. data/src/iowa_webrick_legacy.rb +104 -0
  345. data/src/mod_iowa.rb +104 -0
  346. data/tcss.rb +61 -0
  347. data/test/README.windows +12 -0
  348. data/test/TC_AcceptLanguage.rb +61 -0
  349. data/test/TC_AppConfig.rb +43 -0
  350. data/test/TC_AppConfig/cgi/iowa.cgi +7 -0
  351. data/test/TC_AppConfig/doc/index.html +1 -0
  352. data/test/TC_AppConfig/iowa/Main.html +4 -0
  353. data/test/TC_AppConfig/iowa/Main.iwa +17 -0
  354. data/test/TC_AppConfig/iowa/README +1 -0
  355. data/test/TC_AppConfig/iowa/app.cnf +19 -0
  356. data/test/TC_AppConfig/iowa/app.rb +8 -0
  357. data/test/TC_AppConfig/webrick.rb +38 -0
  358. data/test/TC_Association.rb +29 -0
  359. data/test/TC_BiLevelCache.rb +71 -0
  360. data/test/TC_CGI_Adaptor.rb +55 -0
  361. data/test/TC_CGI_Adaptor/cgi/iowa.cgi +7 -0
  362. data/test/TC_CGI_Adaptor/doc/index.html +1 -0
  363. data/test/TC_CGI_Adaptor/iowa/Main.html +8 -0
  364. data/test/TC_CGI_Adaptor/iowa/Main.iwa +14 -0
  365. data/test/TC_CGI_Adaptor/iowa/README +1 -0
  366. data/test/TC_CGI_Adaptor/iowa/app.cnf +8 -0
  367. data/test/TC_CGI_Adaptor/iowa/app.rb +8 -0
  368. data/test/TC_CGI_Adaptor/webrick.rb +38 -0
  369. data/test/TC_CSS.rb +660 -0
  370. data/test/TC_ClassLimitedCache.rb +89 -0
  371. data/test/TC_Classifier.rb +80 -0
  372. data/test/TC_DbPool.rb +127 -0
  373. data/test/TC_DiskCache.rb +218 -0
  374. data/test/TC_Hybrid.rb +58 -0
  375. data/test/TC_Hybrid/doc/thing.txt +1 -0
  376. data/test/TC_Hybrid/iowa/Main.html +3 -0
  377. data/test/TC_Hybrid/iowa/Main.iwa +7 -0
  378. data/test/TC_Hybrid/iowa/NewPage.html +1 -0
  379. data/test/TC_Hybrid/iowa/NewPage.iwa +5 -0
  380. data/test/TC_Hybrid/iowa/app.cnf +10 -0
  381. data/test/TC_Hybrid/iowa/app.rb +5 -0
  382. data/test/TC_IOWAFunctions/doc/Ajax1.html +1 -0
  383. data/test/TC_IOWAFunctions/doc/Ajax1.iwa +1 -0
  384. data/test/TC_IOWAFunctions/doc/index.html +1 -0
  385. data/test/TC_IOWAFunctions/doc/js/dojo.js +9686 -0
  386. data/test/TC_IOWAFunctions/iowa/Ajax1.html +40 -0
  387. data/test/TC_IOWAFunctions/iowa/Ajax1.iwa +23 -0
  388. data/test/TC_IOWAFunctions/iowa/AjaxWidget.iwa +19 -0
  389. data/test/TC_IOWAFunctions/iowa/AjaxWidget.view +22 -0
  390. data/test/TC_IOWAFunctions/iowa/DanielTest.html +9 -0
  391. data/test/TC_IOWAFunctions/iowa/DanielTest.iwa +10 -0
  392. data/test/TC_IOWAFunctions/iowa/IntervalWidget.html +1 -0
  393. data/test/TC_IOWAFunctions/iowa/IntervalWidget.iwa +14 -0
  394. data/test/TC_IOWAFunctions/iowa/Main.html +1 -0
  395. data/test/TC_IOWAFunctions/iowa/NestedRepeat1.html +12 -0
  396. data/test/TC_IOWAFunctions/iowa/NestedRepeat1.iwa +24 -0
  397. data/test/TC_IOWAFunctions/iowa/RPCResponse.iwa +7 -0
  398. data/test/TC_IOWAFunctions/iowa/RPCResponse.view +1 -0
  399. data/test/TC_IOWAFunctions/iowa/Repeat1.iwa +31 -0
  400. data/test/TC_IOWAFunctions/iowa/Repeat1.view +9 -0
  401. data/test/TC_IOWAFunctions/iowa/Repeat2.iwa +32 -0
  402. data/test/TC_IOWAFunctions/iowa/Repeat2.view +11 -0
  403. data/test/TC_IOWAFunctions/iowa/Repeat3.iwa +44 -0
  404. data/test/TC_IOWAFunctions/iowa/Repeat3.view +18 -0
  405. data/test/TC_IOWAFunctions/iowa/TesCon.html +1 -0
  406. data/test/TC_IOWAFunctions/iowa/TesCon.iwa +5 -0
  407. data/test/TC_IOWAFunctions/iowa/app.cnf +19 -0
  408. data/test/TC_IOWAFunctions/iowa/app.rb +9 -0
  409. data/test/TC_IOWAFunctions/iowa/mapfile.cnf +8 -0
  410. data/test/TC_ISAAC.rb +52 -0
  411. data/test/TC_ImageSize.rb +84 -0
  412. data/test/TC_ImageSize/img.bmp +0 -0
  413. data/test/TC_ImageSize/img.gif +0 -0
  414. data/test/TC_ImageSize/img.jpg +0 -0
  415. data/test/TC_ImageSize/img.pcx +0 -0
  416. data/test/TC_ImageSize/img.pgm +7144 -0
  417. data/test/TC_ImageSize/img.png +0 -0
  418. data/test/TC_ImageSize/img.ppm +0 -0
  419. data/test/TC_ImageSize/img.psd +0 -0
  420. data/test/TC_ImageSize/img.tiff +0 -0
  421. data/test/TC_ImageSize/img.xbm +22 -0
  422. data/test/TC_KeyValueCoding.rb +35 -0
  423. data/test/TC_LRUCache.rb +296 -0
  424. data/test/TC_LinkedList.rb +46 -0
  425. data/test/TC_Lockfile.rb +106 -0
  426. data/test/TC_Minimal.rb +45 -0
  427. data/test/TC_Minimal/app.cnf +8 -0
  428. data/test/TC_Minimal/cgi-bin/iowa.cgi +11 -0
  429. data/test/TC_Minimal/doc/index.html +1 -0
  430. data/test/TC_Minimal/iowa/Main.html +1 -0
  431. data/test/TC_Minimal/iowa/README +1 -0
  432. data/test/TC_Minimal/iowa/app.rb +3 -0
  433. data/test/TC_Minimal/webrick.rb +38 -0
  434. data/test/TC_Mongrel.rb +58 -0
  435. data/test/TC_Mongrel/doc/thing.txt +1 -0
  436. data/test/TC_Mongrel/iowa/Main.html +3 -0
  437. data/test/TC_Mongrel/iowa/Main.iwa +7 -0
  438. data/test/TC_Mongrel/iowa/NewPage.html +1 -0
  439. data/test/TC_Mongrel/iowa/NewPage.iwa +5 -0
  440. data/test/TC_Mongrel/iowa/app.cnf +10 -0
  441. data/test/TC_Mongrel/iowa/app.rb +5 -0
  442. data/test/TC_NoSubclass.rb +56 -0
  443. data/test/TC_NoSubclass/cgi/iowa.cgi +7 -0
  444. data/test/TC_NoSubclass/doc/index.html +1 -0
  445. data/test/TC_NoSubclass/iowa/Main.html +8 -0
  446. data/test/TC_NoSubclass/iowa/Main.iwa +14 -0
  447. data/test/TC_NoSubclass/iowa/README +1 -0
  448. data/test/TC_NoSubclass/iowa/app.cnf +8 -0
  449. data/test/TC_NoSubclass/iowa/app.rb +5 -0
  450. data/test/TC_NoSubclass/webrick.rb +38 -0
  451. data/test/TC_Pool.rb +139 -0
  452. data/test/TC_RenderedCache/doc/thing.txt +1 -0
  453. data/test/TC_RenderedCache/iowa/BigPage.html +1 -0
  454. data/test/TC_RenderedCache/iowa/BigPage.iwa +12 -0
  455. data/test/TC_RenderedCache/iowa/Main.html +3 -0
  456. data/test/TC_RenderedCache/iowa/Main.iwa +7 -0
  457. data/test/TC_RenderedCache/iowa/NewPage.html +1 -0
  458. data/test/TC_RenderedCache/iowa/NewPage.iwa +11 -0
  459. data/test/TC_RenderedCache/iowa/app.cnf +13 -0
  460. data/test/TC_RenderedCache/iowa/app.rb +5 -0
  461. data/test/TC_RenderedCache/iowa/mapfile.map +4 -0
  462. data/test/TC_ResourceURL.rb +73 -0
  463. data/test/TC_ResourceURL/iowa/Main.html +2 -0
  464. data/test/TC_ResourceURL/iowa/Main.iwa +10 -0
  465. data/test/TC_ResourceURL/iowa/app.cnf +10 -0
  466. data/test/TC_ResourceURL/iowa/app.rb +5 -0
  467. data/test/TC_SimpleDetached.rb +41 -0
  468. data/test/TC_StandardDispatcher.rb +362 -0
  469. data/test/TC_StandardDispatcherWithClassifier.rb +358 -0
  470. data/test/TC_String.rb +24 -0
  471. data/test/TC_Tag.rb +41 -0
  472. data/test/TC_Webrick.rb +56 -0
  473. data/test/TC_Webrick/doc/thing.txt +1 -0
  474. data/test/TC_Webrick/iowa/Main.html +3 -0
  475. data/test/TC_Webrick/iowa/Main.iwa +7 -0
  476. data/test/TC_Webrick/iowa/NewPage.html +1 -0
  477. data/test/TC_Webrick/iowa/NewPage.iwa +5 -0
  478. data/test/TC_Webrick/iowa/app.cnf +10 -0
  479. data/test/TC_Webrick/iowa/app.rb +5 -0
  480. data/test/tc_template.rb +15 -0
  481. data/test/tests.conf +19 -0
  482. data/utils/CVS/Entries +3 -0
  483. data/utils/CVS/Repository +1 -0
  484. data/utils/CVS/Root +1 -0
  485. data/utils/QuickCert-1.0.2.tar.gz +0 -0
  486. data/utils/QuickCert-1.0.2/InstalledFiles +7 -0
  487. data/utils/QuickCert-1.0.2/MANIFEST +10 -0
  488. data/utils/QuickCert-1.0.2/Makefile +15 -0
  489. data/utils/QuickCert-1.0.2/README +56 -0
  490. data/utils/QuickCert-1.0.2/bin/QuickCert +355 -0
  491. data/utils/QuickCert-1.0.2/config.save +12 -0
  492. data/utils/QuickCert-1.0.2/data/examples/ruby/QuickCert/README +60 -0
  493. data/utils/QuickCert-1.0.2/data/examples/ruby/QuickCert/drbssl_c.rb +26 -0
  494. data/utils/QuickCert-1.0.2/data/examples/ruby/QuickCert/drbssl_s.rb +35 -0
  495. data/utils/QuickCert-1.0.2/data/examples/ruby/QuickCert/qc_config +21 -0
  496. data/utils/QuickCert-1.0.2/lib/QuickCert/defaults.rb +28 -0
  497. data/utils/QuickCert-1.0.2/setup.rb +1312 -0
  498. data/utils/iowa_apps +422 -0
  499. data/utils/smtp_sink.rb +9 -0
  500. data/utils/startup_template.cnf +27 -0
  501. data/utils/startup_template.rb +73 -0
  502. metadata +551 -0
@@ -0,0 +1,8 @@
1
+ module IWATestSupport
2
+
3
+ def self.cd_to_test_dir(dir)
4
+ Dir.chdir(File.dirname(File.expand_path(dir)))
5
+ end
6
+
7
+ end
8
+
@@ -0,0 +1,22 @@
1
+ #!ruby
2
+
3
+ basedir = File.dirname(__FILE__)
4
+ $:.push(basedir)
5
+
6
+ require 'external/package'
7
+ require 'rbconfig'
8
+ begin
9
+ require 'rubygems'
10
+ rescue LoadError
11
+ end
12
+
13
+ Dir.chdir(basedir)
14
+ Package.setup("1.0") {
15
+ name "Iowa::Caches::LRUCache"
16
+
17
+ translate(:lib, 'src/' => '')
18
+ lib *Dir["src/iowa/**/*.rb"]
19
+ ri *Dir["src/iowa/**/*.rb"]
20
+
21
+ unit_test ["test/TC_LRUCache.rb"]
22
+ }
@@ -0,0 +1,57 @@
1
+ module Iowa
2
+ class Association
3
+
4
+ def initialize(association)
5
+ @association = association
6
+ end
7
+
8
+ def association
9
+ @association
10
+ end
11
+
12
+ def test(object)
13
+ true
14
+ end
15
+ end
16
+
17
+ class PathAssociation < Association
18
+ def get(object,cache = false)
19
+ myval = object.cached_associations[@association]
20
+ if cache
21
+ usecache = true
22
+ usecache = false unless myval
23
+ if myval.respond_to?(:empty?)
24
+ usecache = false if myval.empty?
25
+ end
26
+ end
27
+ if cache and usecache
28
+ myval
29
+ else
30
+ object.cached_associations[@association] = object.valueForKeyPath(@association)
31
+ end
32
+ end
33
+
34
+ def set(object, val)
35
+ object.takeValueForKeyPath(val, @association)
36
+ end
37
+
38
+ def test(object)
39
+ object.existsKeyPath?(@association)
40
+ end
41
+ end
42
+
43
+ class LiteralAssociation < Association
44
+
45
+ def get(object = nil, cache = false)
46
+ unless @association.is_a?(Proc)
47
+ @association
48
+ else
49
+ @association.call(object.send(:binding))
50
+ end
51
+ end
52
+
53
+ def set(object, val)
54
+ @association = val
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,159 @@
1
+ require 'iowa/Association'
2
+ require 'singleton'
3
+
4
+ module Iowa
5
+
6
+ class UnknownValue
7
+ include Singleton
8
+ def to_s
9
+ 'UNK'
10
+ end
11
+ end
12
+ alias :to_str :to_s
13
+
14
+ BindingKeywords = {'action' => [LiteralAssociation,true],
15
+ 'id' => [LiteralAssociation, false],
16
+ 'item' => [PathAssociation,true],
17
+ 'list' => [PathAssociation,true],
18
+ 'key' => [PathAssociation,true],
19
+ 'klass' => [LiteralAssociation,true], # not 'class' because of HTML conflict
20
+ 'tag' => [LiteralAssociation,true],
21
+ 'condition' => [PathAssociation,true],
22
+ 'value' => [PathAssociation,true]}
23
+
24
+ ClassSeparator = '::'.freeze
25
+ ContentClassesNamespace = 'Iowa::Application::ContentClasses'.freeze
26
+
27
+ C_empty = ''.freeze
28
+ C_ = ' '.freeze
29
+ C_anon_ = '_anon_'.freeze
30
+ C_at = '@'.freeze
31
+ C_atat = '@@'.freeze
32
+ C_bnd = '.bnd'.freeze
33
+ C_content = '_content'.freeze
34
+ C_default = '_default'.freeze
35
+ C_dot = '.'.freeze
36
+ C_dotdot = '..'.freeze
37
+ C_equal = '='.freeze
38
+ C_gt = '>'.freeze
39
+ C_item = '_item'.freeze
40
+ C_iwa = '.iwa'.freeze
41
+ C_list = '_list'.freeze
42
+ C_method = '_method'.freeze
43
+ C_semicolon = ';'.freeze
44
+ C_slash = '/'.freeze
45
+ C0 = '0'.freeze
46
+ C_0to7 = 0..7.freeze
47
+ C1 = '1'.freeze
48
+ Caction = 'action'.freeze
49
+ Caddresses = 'addresses'.freeze
50
+ Capplication = 'application'.freeze
51
+ Capplication_data = 'application/data'.freeze
52
+ Cbasedir = 'basedir'.freeze
53
+ Cbaselog = 'baselog'.freeze
54
+ Cbasename = 'basename'.freeze
55
+ Cbody = 'body'.freeze
56
+ CBodyContent = 'BodyContent'.freeze
57
+ Cbrowsers = 'browsers'.freeze
58
+ Cbutton = 'button'.freeze
59
+ Ccacheable = 'cacheable'.freeze
60
+ Ccheckbox = 'checkbox'.freeze
61
+ Cchecked = 'checked'.freeze
62
+ Cchecksum = 'checksum'.freeze
63
+ CClass = 'Class'.freeze
64
+ Cclass = 'class'.freeze
65
+ Ccondition = 'condition'.freeze
66
+ CContentClasses = 'ContentClasses'.freeze
67
+ CCookie = 'Cookie'.freeze
68
+ Ccookie = 'cookie'.freeze
69
+ Cdaemonize = 'daemonize'.freeze
70
+ Cdatabase = 'database'.freeze
71
+ Cdefault = 'default'.freeze
72
+ Cdepth = 'depth'.freeze
73
+ Cdirectory = 'directory'.freeze
74
+ Cdispatcher = 'dispatcher'.freeze
75
+ Cdoc_root = 'doc_root'.freeze
76
+ Cdocroot = 'docroot'.freeze
77
+ CdynamicString = 'dynamicString'.freeze
78
+ Celement = 'element'.freeze
79
+ Cexceptions = 'exceptions'.freeze
80
+ Cfalse = 'false'.freeze
81
+ CFALSE = 'false'.freeze
82
+ Cfilename = 'filename'.freeze
83
+ Cfiles = 'files'.freeze
84
+ Cforce = 'force'.freeze
85
+ CEIN = 'EIN'.freeze
86
+ CHash = 'Hash'.freeze
87
+ Cheight = 'height'.freeze
88
+ Chostname = 'hostname'.freeze
89
+ Chosts = 'hosts'.freeze
90
+ Chref = 'href'.freeze
91
+ Cid = 'id'.freeze
92
+ Cimage = 'image'.freeze
93
+ Cimage_path = 'image_path'.freeze
94
+ Cinterval = 'interval'.freeze
95
+ Ciowa_log = 'iowa_log'.freeze
96
+ Ciowa_root = 'iowa_root'.freeze
97
+ Cips = 'ips'.freeze
98
+ Citem = 'item'.freeze
99
+ Ckey = 'key'.freeze
100
+ Cklass = 'klass'.freeze
101
+ Clabel = 'label'.freeze
102
+ Clast_modification = 'last_modification'.freeze
103
+ Clibrary = 'library'.freeze
104
+ Clink = 'link'.freeze
105
+ Clist = 'list'.freeze
106
+ CLocation = 'Location'.freeze
107
+ Clog_root = 'log_root'.freeze
108
+ Clogging = 'logging'.freeze
109
+ Clonely_tag_terminator = ' />'.freeze
110
+ CMain = 'Main'.freeze
111
+ Cmapfile = 'mapfile'.freeze
112
+ Cmaxage = 'maxage'.freeze
113
+ Cmaxsize = 'maxsize'.freeze
114
+ Cmethod = 'method'.freeze
115
+ Cminlevel = 'minlevel'.freeze
116
+ Cmodel = 'model'.freeze
117
+ Cmultiple = 'multiple'.freeze
118
+ Cname = 'name'.freeze
119
+ COK = 'OK'.freeze
120
+ Cpage = 'page'.freeze
121
+ Cpagecache = 'pagecache'.freeze
122
+ Cparams = 'params'.freeze
123
+ Cpath = 'path'.freeze
124
+ Cpolicy = 'policy'.freeze
125
+ Cport = 'port'.freeze
126
+ Cplural = 'plural'.freeze
127
+ Cpost = 'post'.freeze
128
+ Cradio = 'radio'.freeze
129
+ Crefresh = 'refresh'.freeze
130
+ Crequest_cacheable = 'request_cacheable'.freeze
131
+ Croot_path = 'root_path'.freeze
132
+ Croot_url = 'root_url'.freeze
133
+ Cscreens = 'screens'.freeze
134
+ Cselected = 'selected'.freeze
135
+ Cserialize_templates = 'serialize_templates'.freeze
136
+ Csession = 'session'.freeze
137
+ Csessioncache = 'sessioncache'.freeze
138
+ Csingular = 'singular'.freeze
139
+ Csocket = 'socket'.freeze
140
+ Csrc = 'src'.freeze
141
+ Csubmit = 'submit'.freeze
142
+ Ctagclass = 'tagclass'.freeze
143
+ Ctag = 'tag'.freeze
144
+ CtemplateRoot = 'templateRoot'.freeze
145
+ Ctext_html = 'text/html'.freeze
146
+ Ctext_javascript = 'text/javascript'.freeze
147
+ Ctitle = 'title'.freeze
148
+ Ctrue = 'true'.freeze
149
+ CTRUE = 'TRUE'.freeze
150
+ Cttl = 'ttl'.freeze
151
+ Ctype = 'type'.freeze
152
+ Cuse_lockfile = 'use_lockfile'.freeze
153
+ CUserAgent = 'User-Agent'.freeze
154
+ Cvalue = 'value'.freeze
155
+ Cvariation = 'variation'.freeze
156
+ Cwebrick = 'webrick'.freeze
157
+ Cwidth = 'width'.freeze
158
+
159
+ end
@@ -0,0 +1,63 @@
1
+ module Iowa
2
+
3
+ # This is a subclass of Ruby's Hash that implements a few convenient
4
+ # methods used by IOWA.
5
+
6
+ class Hash < Hash
7
+
8
+ # A simple little routine to downcase any String used as a key
9
+ # in a hash or any hash nested as value somewhere within the hash.
10
+ # Thanks to Daniel Berger for this implementation.
11
+
12
+ def downcase_keys!
13
+ upper = /A-Z/
14
+ self.each do |k,v|
15
+ next unless k.kind_of? String
16
+ self[k.dup.downcase] = v
17
+ self.delete(k) if upper.match(k)
18
+ end
19
+ end
20
+
21
+ # Convert any symbolic keys to strings.
22
+
23
+ def stringify_keys!
24
+ self.each do |k,v|
25
+ next if k.kind_of? String
26
+ self[k.to_s] = v
27
+ self.delete k
28
+ end
29
+ end
30
+
31
+ def step_merge!(h)
32
+ h.each do |k,v|
33
+ if v.kind_of?(::Hash)
34
+ if self[k].kind_of?(::Hash)
35
+ unless self[k].respond_to?(:step_merge!)
36
+ if dp = self[k].default_proc
37
+ self[k] = Iowa::Hash.new {|h,k| dp.call(h,k)}.step_merge!(self[k])
38
+ else
39
+ osk = self[k]
40
+ self[k] = Iowa::Hash.new
41
+ self[k].step_merge!(osk)
42
+ end
43
+ end
44
+ self[k].step_merge!(v)
45
+ else
46
+ if self.default_proc
47
+ self.delete k
48
+ self[k]
49
+ end
50
+ unless self[k].kind_of?(::Hash)
51
+ self.delete k
52
+ self[k] = Iowa::Hash.new
53
+ end
54
+ self[k].step_merge!(v)
55
+ end
56
+ else
57
+ self[k] = v
58
+ end
59
+ end
60
+ end
61
+
62
+ end
63
+ end
@@ -0,0 +1,129 @@
1
+ module Iowa
2
+
3
+ # Iowa::Mutex is a slight modification of the standard Ruby Mutex class.
4
+ # This class changes the array operations used to manage the queue of
5
+ # threads waiting for a lock in order to get better memory management
6
+ # behavior from the array. This mutex will also not block if the thread
7
+ # holding a lock on a mutex calls lock on that mutex again. If nested
8
+ # locking occurs, the locks must be matched by an equal number of unlocks
9
+ # before the mutex will actually be unlocked.
10
+
11
+ class Mutex
12
+
13
+ # Creates a new Mutex.
14
+
15
+ def initialize
16
+ @waiting = []
17
+ @locked = false;
18
+ @nested_locks = 0
19
+ @waiting.taint # enable tainted comunication
20
+ self.taint
21
+ end
22
+
23
+
24
+ # Returns the thread that holds the lock or +false+ if the mutex is not locked.
25
+
26
+ def locked?
27
+ @locked
28
+ end
29
+
30
+
31
+ # Attempts to obtain the lock and returns immediately. Returns +true+ if the
32
+ # lock was granted.
33
+
34
+ def try_lock
35
+ @nested_locks += 1 and return true if @locked == Thread.current
36
+ result = false
37
+ Thread.critical = true
38
+ unless @locked
39
+ @locked = Thread.current
40
+ result = true
41
+ end
42
+ Thread.critical = false
43
+ result
44
+ end
45
+
46
+
47
+ # Attempts to obtain a lock on the mutex. Block if a lock can not be
48
+ # obtained immediately and waits until the lock can be obtained.
49
+ # If this thread already holds this lock, returns immediately.
50
+ # Returns the mutex.
51
+
52
+ def lock
53
+ if @locked == Thread.current
54
+ @nested_locks += 1
55
+ else
56
+ while (Thread.critical = true; @locked)
57
+ @waiting.unshift Thread.current
58
+ Thread.stop
59
+ end
60
+ @locked = Thread.current
61
+ Thread.critical = false
62
+ end
63
+ self
64
+ end
65
+
66
+
67
+ # Releases this thread's lock on the mutex and wakes the next thread
68
+ # waiting for the lock, if any.
69
+
70
+ def unlock
71
+ return unless @locked
72
+ if @nested_locks > 0
73
+ @nested_locks -= 1
74
+ else
75
+ Thread.critical = true
76
+ @locked = false
77
+ begin
78
+ t = @waiting.pop
79
+ t.wakeup if t
80
+ rescue ThreadError
81
+ retry
82
+ end
83
+ Thread.critical = false
84
+ begin
85
+ t.run if t
86
+ rescue ThreadError
87
+ end
88
+ end
89
+ self
90
+ end
91
+
92
+
93
+ # If the mutex is locked, unlocks the mutex, wakes one waiting thread, and
94
+ # yields in a critical section.
95
+
96
+ def exclusive_unlock
97
+ return unless @locked
98
+ if @nested_locks > 0
99
+ @nested_locks -= 1
100
+ else
101
+ Thread.exclusive do
102
+ @locked = false
103
+ begin
104
+ t = @waiting.pop
105
+ t.wakeup if t
106
+ rescue ThreadError
107
+ retry
108
+ end
109
+ yield
110
+ end
111
+ end
112
+ self
113
+ end
114
+
115
+
116
+ # Obtains a lock, runs the block, and releases the lock when the block
117
+ # completes. See the example under Mutex.
118
+
119
+ def synchronize
120
+ lock
121
+ begin
122
+ yield
123
+ ensure
124
+ unlock
125
+ end
126
+ end
127
+
128
+ end
129
+ end
@@ -0,0 +1,287 @@
1
+ require 'enumerator'
2
+ require 'iowa/Mutex'
3
+ require 'iowa/Constants'
4
+ require 'iowa/Hash'
5
+
6
+ module Iowa
7
+ module Caches
8
+
9
+ #++
10
+ # Iowa::Caches::LRUCache is an LRU cache based on a linked list.
11
+ # It provides efficient random access to elements, like a hash,
12
+ # along with efficient stack or queue-like behaviors -- elements can
13
+ # be pushed, poped, shifted, and unshifted from the cache.
14
+
15
+ class LRUCache
16
+ include Enumerable
17
+
18
+ # * Iowa::Caches::LRUCache.new
19
+ # * Iowa::Caches::LRUCache.new(:maxsize => 20)
20
+ # * Iowa::Caches::LRUCache.new(20)
21
+ # * Iowa::Caches::LRUCache.new(:maxsize => 20, :ttl => 3600)
22
+ # * Iowa::Caches::LRUCache.new(20,3600)
23
+ #
24
+ # If called with no arguments, the cache will default to a max size
25
+ # of 20 elements, with no max time to live (ttl) on the elements.
26
+ #
27
+ # If called using a hash with keyword arguments, the :maxsize is the
28
+ # maximum number of elements to keep in the hash, and :ttl is the
29
+ # maximum age allowed for elements in the hash.
30
+ #
31
+ # If called with list arguments, the first is the max size, and the
32
+ # second is the TTL.
33
+
34
+ def initialize(args = {Cmaxsize => 20, Cttl => nil}, ttlarg = nil)
35
+ if args.kind_of? ::Hash
36
+ oargs = args
37
+ args = Iowa::Hash.new
38
+ args.step_merge!(oargs)
39
+ end
40
+ args.stringify_keys! if args.respond_to? :stringify_keys!
41
+ begin
42
+ @max = args[Cmaxsize] || 20
43
+ @maxttl = args[Cttl]
44
+ @mutex = Iowa::Mutex.new
45
+ rescue Exception
46
+ args = {Cmaxsize => args || 20, Cttl => ttlarg}
47
+ retry
48
+ end
49
+ @finalizers = []
50
+ @head = Node.new
51
+ @tail = Node.new
52
+ @lookup = Hash.new
53
+ node_join(@head,@tail)
54
+ end
55
+
56
+
57
+ # Check to see if the given key is in the cache.
58
+
59
+ def include?(v)
60
+ @lookup.has_key?(v)
61
+ end
62
+
63
+ def [](v)
64
+ @mutex.lock
65
+ if @lookup.has_key?(v)
66
+ n = @lookup[v]
67
+ n.age = Time.now
68
+ node_delete(n)
69
+ node_join(n,@head.next_node)
70
+ node_join(@head,n)
71
+ node_prune
72
+ @mutex.unlock
73
+ n.value
74
+ else
75
+ node_prune
76
+ @mutex.unlock
77
+ nil
78
+ end
79
+ end
80
+
81
+ def []=(k,v)
82
+ @mutex.lock
83
+ if @lookup.has_key?(k)
84
+ n = @lookup[k]
85
+ n.value = v
86
+ n.age = Time.now
87
+ node_delete(n)
88
+ node_join(n,@head.next_node)
89
+ node_join(@head,n)
90
+ else
91
+ n = Node.new(k,v,Time.now,@head,@head.next_node)
92
+ node_join(n,@head.next_node)
93
+ node_join(@head,n)
94
+ @lookup[k] = n
95
+ end
96
+ node_prune
97
+ @mutex.unlock
98
+ v
99
+ end
100
+
101
+ def empty?
102
+ @lookup.empty?
103
+ end
104
+
105
+ def delete(k)
106
+ @mutex.lock
107
+ n = @lookup.delete(k)
108
+ node_purge(n) if n
109
+ node_prune
110
+ @mutex.unlock
111
+ n
112
+ end
113
+
114
+ def first
115
+ @head.next_node.value
116
+ end
117
+
118
+ def last
119
+ @tail.prev_node.value
120
+ end
121
+
122
+ def shift
123
+ @mutex.lock
124
+ k = @head.next_node.key
125
+ n = @lookup.delete(k)
126
+ node_delete(n) if n
127
+ node_prune
128
+ @mutex.unlock
129
+ end
130
+
131
+ def unshift(v)
132
+ @mutex.lock
133
+ if @lookup.has_key?(v)
134
+ n = @lookup[v]
135
+ node_delete(n)
136
+ node_join(n,@head.next_node)
137
+ node_join(@head,n)
138
+ else
139
+ n = Node.new(v,v,Time.now,@head,@head.next_node)
140
+ node_join(n,@head.next_node)
141
+ node_join(@head,n)
142
+ @lookup[v] = n
143
+ end
144
+ node_prune
145
+ @mutex.unlock
146
+ v
147
+ end
148
+
149
+ def pop
150
+ @mutex.lock
151
+ k = @tail.prev_node.key
152
+ n = @lookup.delete(k)
153
+ node_delete(n) if n
154
+ node_prune
155
+ @mutex.unlock
156
+ end
157
+
158
+ def push(v)
159
+ @mutex.lock
160
+ if @lookup.has_key?(v)
161
+ n = @lookup[v]
162
+ node_delete(n)
163
+ node_join(@tail.prev_node,n)
164
+ node_join(n,@tail)
165
+ else
166
+ n = Node.new(v,v,Time.now,@tail.prev_node,@tail)
167
+ node_join(@tail.prev_node,n)
168
+ node_join(n,@tail)
169
+ @lookup[v] = n
170
+ end
171
+ node_prune
172
+ @mutex.unlock
173
+ v
174
+ end
175
+
176
+ def queue
177
+ r = []
178
+ n = @head
179
+ while (n = n.next_node) and n != @tail
180
+ r << n.key
181
+ end
182
+ r
183
+ end
184
+
185
+ def to_a
186
+ r = []
187
+ n = @head
188
+ while (n = n.next_node) and n != @tail
189
+ r << n.value
190
+ end
191
+ r
192
+ end
193
+
194
+ def length
195
+ @lookup.length
196
+ end
197
+ alias :size :length
198
+
199
+ def each
200
+ n = @head
201
+ while (n = n.next_node) and n != @tail
202
+ yield(n.key,n.value)
203
+ end
204
+ end
205
+
206
+ def maxsize
207
+ @max
208
+ end
209
+
210
+ def maxsize=(v)
211
+ @max = v
212
+ node_prune
213
+ end
214
+ alias :size= :maxsize=
215
+
216
+ def ttl
217
+ @maxttl
218
+ end
219
+
220
+ def ttl=(v)
221
+ @maxttl = v
222
+ node_prune
223
+ end
224
+
225
+ # Adds a finalization method to the cache that will be called before
226
+ # the object in the cache is expired.
227
+
228
+ def add_finalizer(*args,&block)
229
+ @finalizers.push [block,args]
230
+ end
231
+
232
+ private
233
+
234
+ def node_delete(n)
235
+ node_join(n.prev_node,n.next_node)
236
+ end
237
+
238
+ def node_purge(n)
239
+ node_join(n.prev_node,n.next_node)
240
+ v = n.value
241
+ k = n.key
242
+ n.value = nil
243
+ n.key = nil
244
+ n.next_node = nil
245
+ n.prev_node = nil
246
+ do_finalization(k,v) if @finalizers
247
+ v
248
+ end
249
+
250
+ def node_join(a,b)
251
+ a.next_node = b
252
+ b.prev_node = a
253
+ end
254
+
255
+ def node_prune
256
+ node_purge(@lookup.delete(@tail.prev_node.key)) while @lookup.size > @max
257
+ if @maxttl
258
+ expiration_date = Time.now - @maxttl
259
+ while (n = @tail.prev_node).age < expiration_date
260
+ node_purge(@lookup.delete(n.key))
261
+ end
262
+ end
263
+ end
264
+
265
+ # Is called when an object in the cache is expired. Iterates through
266
+ # the defined finalization methods, if any.
267
+ def do_finalization(key,obj)
268
+ @finalizers.each do |f|
269
+ f[0].call(key,obj,*f[1])
270
+ end
271
+ end
272
+
273
+ class Node
274
+ attr_accessor :key, :value, :age, :prev_node, :next_node
275
+
276
+ def initialize(key=nil,value=nil,age=Time.now,prev_node=nil,next_node=nil)
277
+ @key = key
278
+ @value = value
279
+ @age = age
280
+ @prev_node = prev_node
281
+ @next_node = next_node
282
+ end
283
+ end
284
+
285
+ end
286
+ end
287
+ end