passenger 3.0.21 → 3.9.1.beta

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of passenger might be problematic. Click here for more details.

Files changed (835) hide show
  1. data/DEVELOPERS.TXT +4 -10
  2. data/NEWS +19 -27
  3. data/Rakefile +20 -19
  4. data/bin/passenger +3 -2
  5. data/bin/passenger-config +35 -5
  6. data/bin/passenger-install-apache2-module +12 -12
  7. data/bin/passenger-install-nginx-module +55 -38
  8. data/bin/passenger-memory-stats +3 -1
  9. data/bin/passenger-status +7 -35
  10. data/build/agents.rb +107 -21
  11. data/build/apache2.rb +11 -46
  12. data/build/basics.rb +61 -9
  13. data/build/common_library.rb +59 -142
  14. data/build/cxx_tests.rb +111 -110
  15. data/build/documentation.rb +33 -0
  16. data/build/misc.rb +30 -12
  17. data/build/nginx.rb +10 -39
  18. data/build/oxt_tests.rb +1 -0
  19. data/build/ruby_extension.rb +1 -5
  20. data/build/test_basics.rb +3 -2
  21. data/dev/copy_boost_headers.rb +2 -1
  22. data/doc/Architectural overview.html +49 -90
  23. data/doc/DebuggingAndStressTesting.txt.md +49 -0
  24. data/doc/Packaging.txt.md +254 -0
  25. data/doc/Security of user switching support.html +35 -66
  26. data/doc/Users guide Apache.html +588 -758
  27. data/doc/Users guide Apache.idmap.txt +253 -136
  28. data/doc/Users guide Apache.txt +154 -109
  29. data/doc/Users guide Nginx.html +544 -660
  30. data/doc/Users guide Nginx.idmap.txt +179 -91
  31. data/doc/Users guide Nginx.txt +192 -118
  32. data/doc/Users guide Standalone.html +65 -48
  33. data/doc/Users guide Standalone.idmap.txt +10 -2
  34. data/doc/Users guide Standalone.txt +4 -0
  35. data/doc/images/glyphicons-halflings-white.png +0 -0
  36. data/doc/images/glyphicons-halflings.png +0 -0
  37. data/doc/images/phusion_banner_small.png +0 -0
  38. data/doc/images/{smart-lv2.png → smart.png} +0 -0
  39. data/doc/images/{smart-lv2.svg → smart.svg} +0 -0
  40. data/doc/templates/bootstrap.min.css +397 -0
  41. data/doc/templates/markdown.html.erb +117 -0
  42. data/doc/users_guide_snippets/analysis_and_system_maintenance.txt +2 -1
  43. data/doc/users_guide_snippets/appendix_c_spawning_methods.txt +26 -48
  44. data/doc/users_guide_snippets/passenger_spawn_method.txt +18 -30
  45. data/doc/users_guide_snippets/support_information.txt +30 -0
  46. data/ext/apache2/Bucket.cpp +9 -26
  47. data/ext/apache2/Bucket.h +13 -10
  48. data/ext/apache2/Configuration.cpp +70 -58
  49. data/ext/apache2/Configuration.hpp +19 -47
  50. data/ext/apache2/DirectoryMapper.h +7 -7
  51. data/ext/apache2/Hooks.cpp +150 -313
  52. data/ext/boost/algorithm/string/detail/case_conv.hpp +4 -2
  53. data/ext/boost/algorithm/string/detail/find_format.hpp +20 -20
  54. data/ext/boost/algorithm/string/detail/find_format_all.hpp +23 -23
  55. data/ext/boost/algorithm/string/detail/find_format_store.hpp +2 -2
  56. data/ext/boost/algorithm/string/detail/formatter.hpp +25 -0
  57. data/ext/boost/algorithm/string/formatter.hpp +20 -3
  58. data/ext/boost/assert.hpp +85 -4
  59. data/ext/boost/bind/bind.hpp +1 -1
  60. data/ext/boost/concept/detail/backward_compatibility.hpp +1 -1
  61. data/ext/boost/concept_check.hpp +140 -64
  62. data/ext/boost/config.hpp +1 -1
  63. data/ext/boost/config/auto_link.hpp +8 -6
  64. data/ext/boost/config/compiler/borland.hpp +12 -2
  65. data/ext/boost/config/compiler/clang.hpp +89 -30
  66. data/ext/boost/config/compiler/codegear.hpp +3 -2
  67. data/ext/boost/config/compiler/common_edg.hpp +7 -5
  68. data/ext/boost/config/compiler/cray.hpp +61 -0
  69. data/ext/boost/config/compiler/digitalmars.hpp +9 -1
  70. data/ext/boost/config/compiler/gcc.hpp +33 -24
  71. data/ext/boost/config/compiler/gcc_xml.hpp +4 -0
  72. data/ext/boost/config/compiler/hp_acc.hpp +12 -1
  73. data/ext/boost/config/compiler/intel.hpp +78 -4
  74. data/ext/boost/config/compiler/metrowerks.hpp +4 -1
  75. data/ext/boost/config/compiler/mpw.hpp +4 -1
  76. data/ext/boost/config/compiler/nvcc.hpp +8 -66
  77. data/ext/boost/config/compiler/pathscale.hpp +80 -0
  78. data/ext/boost/config/compiler/pgi.hpp +5 -5
  79. data/ext/boost/config/compiler/sunpro_cc.hpp +4 -1
  80. data/ext/boost/config/compiler/vacpp.hpp +37 -13
  81. data/ext/boost/config/compiler/visualc.hpp +24 -11
  82. data/ext/boost/config/platform/bsd.hpp +1 -1
  83. data/ext/boost/config/platform/cray.hpp +18 -0
  84. data/ext/boost/config/platform/cygwin.hpp +10 -0
  85. data/ext/boost/config/platform/linux.hpp +5 -0
  86. data/ext/boost/config/platform/macos.hpp +5 -4
  87. data/ext/boost/config/platform/symbian.hpp +5 -2
  88. data/ext/boost/config/platform/vms.hpp +25 -0
  89. data/ext/boost/config/platform/win32.hpp +7 -1
  90. data/ext/boost/config/select_compiler_config.hpp +8 -25
  91. data/ext/boost/config/select_platform_config.hpp +8 -1
  92. data/ext/boost/config/select_stdlib_config.hpp +9 -1
  93. data/ext/boost/config/stdlib/dinkumware.hpp +6 -9
  94. data/ext/boost/config/stdlib/libcomo.hpp +1 -4
  95. data/ext/boost/config/stdlib/libcpp.hpp +36 -0
  96. data/ext/boost/config/stdlib/libstdcpp3.hpp +37 -11
  97. data/ext/boost/config/stdlib/modena.hpp +1 -4
  98. data/ext/boost/config/stdlib/msl.hpp +1 -4
  99. data/ext/boost/config/stdlib/roguewave.hpp +9 -6
  100. data/ext/boost/config/stdlib/sgi.hpp +12 -4
  101. data/ext/boost/config/stdlib/stlport.hpp +11 -4
  102. data/ext/boost/config/stdlib/vacpp.hpp +11 -4
  103. data/ext/boost/config/suffix.hpp +71 -6
  104. data/ext/boost/config/warning_disable.hpp +1 -1
  105. data/ext/boost/container/container_fwd.hpp +177 -0
  106. data/ext/boost/cstdint.hpp +17 -12
  107. data/ext/boost/current_function.hpp +2 -1
  108. data/ext/boost/date_time/c_time.hpp +17 -1
  109. data/ext/boost/date_time/compiler_config.hpp +13 -15
  110. data/ext/boost/date_time/date_formatting.hpp +7 -1
  111. data/ext/boost/date_time/filetime_functions.hpp +4 -4
  112. data/ext/boost/date_time/gregorian_calendar.ipp +2 -2
  113. data/ext/boost/date_time/strings_from_facet.hpp +3 -3
  114. data/ext/boost/date_time/time_facet.hpp +101 -101
  115. data/ext/boost/detail/endian.hpp +4 -2
  116. data/ext/boost/detail/fenv.hpp +74 -0
  117. data/ext/boost/detail/sp_typeinfo.hpp +6 -0
  118. data/ext/boost/exception/detail/clone_current_exception.hpp +47 -0
  119. data/ext/boost/exception/detail/exception_ptr.hpp +194 -122
  120. data/ext/boost/exception/detail/type_info.hpp +3 -3
  121. data/ext/boost/exception/diagnostic_information.hpp +37 -21
  122. data/ext/boost/exception/exception.hpp +21 -1
  123. data/ext/boost/exception/info.hpp +0 -1
  124. data/ext/boost/function.hpp +2 -2
  125. data/ext/boost/function/function_base.hpp +15 -9
  126. data/ext/boost/function/function_template.hpp +26 -48
  127. data/ext/boost/integer_fwd.hpp +0 -16
  128. data/ext/boost/integer_traits.hpp +2 -2
  129. data/ext/boost/iterator.hpp +1 -1
  130. data/ext/boost/iterator/iterator_adaptor.hpp +1 -7
  131. data/ext/boost/iterator/iterator_facade.hpp +13 -13
  132. data/ext/boost/iterator/transform_iterator.hpp +5 -20
  133. data/ext/boost/lexical_cast.hpp +1655 -673
  134. data/ext/boost/math/policies/policy.hpp +982 -0
  135. data/ext/boost/math/special_functions/detail/fp_traits.hpp +570 -0
  136. data/ext/boost/math/special_functions/detail/round_fwd.hpp +80 -0
  137. data/ext/boost/math/special_functions/fpclassify.hpp +533 -0
  138. data/ext/boost/math/special_functions/math_fwd.hpp +1070 -0
  139. data/ext/boost/math/special_functions/sign.hpp +145 -0
  140. data/ext/boost/math/tools/config.hpp +321 -0
  141. data/ext/boost/math/tools/promotion.hpp +150 -0
  142. data/ext/boost/math/tools/real_cast.hpp +29 -0
  143. data/ext/boost/math/tools/user.hpp +97 -0
  144. data/ext/boost/move/move.hpp +1222 -0
  145. data/ext/boost/mpl/O1_size.hpp +40 -0
  146. data/ext/boost/mpl/O1_size_fwd.hpp +24 -0
  147. data/ext/boost/mpl/advance.hpp +76 -0
  148. data/ext/boost/mpl/advance_fwd.hpp +28 -0
  149. data/ext/boost/mpl/at.hpp +52 -0
  150. data/ext/boost/mpl/at_fwd.hpp +24 -0
  151. data/ext/boost/mpl/aux_/O1_size_impl.hpp +87 -0
  152. data/ext/boost/mpl/aux_/advance_backward.hpp +128 -0
  153. data/ext/boost/mpl/aux_/advance_forward.hpp +127 -0
  154. data/ext/boost/mpl/aux_/arithmetic_op.hpp +92 -0
  155. data/ext/boost/mpl/aux_/at_impl.hpp +45 -0
  156. data/ext/boost/mpl/aux_/begin_end_impl.hpp +101 -0
  157. data/ext/boost/mpl/aux_/clear_impl.hpp +35 -0
  158. data/ext/boost/mpl/aux_/comparison_op.hpp +83 -0
  159. data/ext/boost/mpl/aux_/config/forwarding.hpp +27 -0
  160. data/ext/boost/mpl/aux_/config/typeof.hpp +38 -0
  161. data/ext/boost/mpl/aux_/contains_impl.hpp +61 -0
  162. data/ext/boost/mpl/aux_/find_if_pred.hpp +31 -0
  163. data/ext/boost/mpl/aux_/fold_impl.hpp +43 -0
  164. data/ext/boost/mpl/aux_/has_begin.hpp +23 -0
  165. data/ext/boost/mpl/aux_/has_size.hpp +23 -0
  166. data/ext/boost/mpl/aux_/has_tag.hpp +23 -0
  167. data/ext/boost/mpl/aux_/inserter_algorithm.hpp +159 -0
  168. data/ext/boost/mpl/aux_/is_msvc_eti_arg.hpp +64 -0
  169. data/ext/boost/mpl/aux_/iter_apply.hpp +47 -0
  170. data/ext/boost/mpl/aux_/iter_fold_if_impl.hpp +210 -0
  171. data/ext/boost/mpl/aux_/iter_fold_impl.hpp +42 -0
  172. data/ext/boost/mpl/aux_/lambda_spec.hpp +49 -0
  173. data/ext/boost/mpl/aux_/largest_int.hpp +63 -0
  174. data/ext/boost/mpl/aux_/msvc_eti_base.hpp +77 -0
  175. data/ext/boost/mpl/aux_/msvc_type.hpp +62 -0
  176. data/ext/boost/mpl/aux_/numeric_cast_utils.hpp +77 -0
  177. data/ext/boost/mpl/aux_/numeric_op.hpp +315 -0
  178. data/ext/boost/mpl/aux_/preprocessed/gcc/advance_backward.hpp +97 -0
  179. data/ext/boost/mpl/aux_/preprocessed/gcc/advance_forward.hpp +97 -0
  180. data/ext/boost/mpl/aux_/preprocessed/gcc/equal_to.hpp +94 -0
  181. data/ext/boost/mpl/aux_/preprocessed/gcc/fold_impl.hpp +180 -0
  182. data/ext/boost/mpl/aux_/preprocessed/gcc/greater.hpp +94 -0
  183. data/ext/boost/mpl/aux_/preprocessed/gcc/greater_equal.hpp +94 -0
  184. data/ext/boost/mpl/aux_/preprocessed/gcc/iter_fold_if_impl.hpp +133 -0
  185. data/ext/boost/mpl/aux_/preprocessed/gcc/iter_fold_impl.hpp +180 -0
  186. data/ext/boost/mpl/aux_/preprocessed/gcc/less.hpp +94 -0
  187. data/ext/boost/mpl/aux_/preprocessed/gcc/less_equal.hpp +94 -0
  188. data/ext/boost/mpl/aux_/preprocessed/gcc/list.hpp +323 -0
  189. data/ext/boost/mpl/aux_/preprocessed/gcc/minus.hpp +146 -0
  190. data/ext/boost/mpl/aux_/preprocessed/gcc/not_equal_to.hpp +94 -0
  191. data/ext/boost/mpl/aux_/preprocessed/gcc/plus.hpp +146 -0
  192. data/ext/boost/mpl/aux_/preprocessed/gcc/reverse_fold_impl.hpp +231 -0
  193. data/ext/boost/mpl/aux_/preprocessed/gcc/times.hpp +146 -0
  194. data/ext/boost/mpl/aux_/preprocessed/gcc/vector.hpp +323 -0
  195. data/ext/boost/mpl/aux_/preprocessor/default_params.hpp +67 -0
  196. data/ext/boost/mpl/aux_/push_back_impl.hpp +70 -0
  197. data/ext/boost/mpl/aux_/push_front_impl.hpp +71 -0
  198. data/ext/boost/mpl/aux_/reverse_fold_impl.hpp +44 -0
  199. data/ext/boost/mpl/aux_/size_impl.hpp +52 -0
  200. data/ext/boost/mpl/aux_/traits_lambda_spec.hpp +63 -0
  201. data/ext/boost/mpl/back_fwd.hpp +24 -0
  202. data/ext/boost/mpl/back_inserter.hpp +34 -0
  203. data/ext/boost/mpl/begin_end.hpp +57 -0
  204. data/ext/boost/mpl/begin_end_fwd.hpp +27 -0
  205. data/ext/boost/mpl/clear.hpp +39 -0
  206. data/ext/boost/mpl/clear_fwd.hpp +24 -0
  207. data/ext/boost/mpl/comparison.hpp +24 -0
  208. data/ext/boost/mpl/contains.hpp +41 -0
  209. data/ext/boost/mpl/contains_fwd.hpp +25 -0
  210. data/ext/boost/mpl/deref.hpp +41 -0
  211. data/ext/boost/mpl/distance.hpp +78 -0
  212. data/ext/boost/mpl/distance_fwd.hpp +28 -0
  213. data/ext/boost/mpl/empty_fwd.hpp +24 -0
  214. data/ext/boost/mpl/equal_to.hpp +21 -0
  215. data/ext/boost/mpl/find.hpp +38 -0
  216. data/ext/boost/mpl/find_if.hpp +50 -0
  217. data/ext/boost/mpl/fold.hpp +48 -0
  218. data/ext/boost/mpl/front_fwd.hpp +24 -0
  219. data/ext/boost/mpl/front_inserter.hpp +33 -0
  220. data/ext/boost/mpl/greater.hpp +21 -0
  221. data/ext/boost/mpl/greater_equal.hpp +21 -0
  222. data/ext/boost/mpl/inserter.hpp +32 -0
  223. data/ext/boost/mpl/iter_fold.hpp +49 -0
  224. data/ext/boost/mpl/iter_fold_if.hpp +117 -0
  225. data/ext/boost/mpl/iterator_range.hpp +42 -0
  226. data/ext/boost/mpl/iterator_tags.hpp +27 -0
  227. data/ext/boost/mpl/less.hpp +21 -0
  228. data/ext/boost/mpl/less_equal.hpp +21 -0
  229. data/ext/boost/mpl/limits/list.hpp +21 -0
  230. data/ext/boost/mpl/limits/vector.hpp +21 -0
  231. data/ext/boost/mpl/list.hpp +57 -0
  232. data/ext/boost/mpl/list/aux_/O1_size.hpp +33 -0
  233. data/ext/boost/mpl/list/aux_/begin_end.hpp +44 -0
  234. data/ext/boost/mpl/list/aux_/clear.hpp +34 -0
  235. data/ext/boost/mpl/list/aux_/empty.hpp +34 -0
  236. data/ext/boost/mpl/list/aux_/front.hpp +33 -0
  237. data/ext/boost/mpl/list/aux_/include_preprocessed.hpp +35 -0
  238. data/ext/boost/mpl/list/aux_/item.hpp +55 -0
  239. data/ext/boost/mpl/list/aux_/iterator.hpp +76 -0
  240. data/ext/boost/mpl/list/aux_/pop_front.hpp +34 -0
  241. data/ext/boost/mpl/list/aux_/preprocessed/plain/list10.hpp +149 -0
  242. data/ext/boost/mpl/list/aux_/preprocessed/plain/list20.hpp +169 -0
  243. data/ext/boost/mpl/list/aux_/push_back.hpp +36 -0
  244. data/ext/boost/mpl/list/aux_/push_front.hpp +39 -0
  245. data/ext/boost/mpl/list/aux_/size.hpp +33 -0
  246. data/ext/boost/mpl/list/aux_/tag.hpp +24 -0
  247. data/ext/boost/mpl/list/list0.hpp +42 -0
  248. data/ext/boost/mpl/list/list10.hpp +43 -0
  249. data/ext/boost/mpl/list/list20.hpp +43 -0
  250. data/ext/boost/mpl/long.hpp +22 -0
  251. data/ext/boost/mpl/long_fwd.hpp +27 -0
  252. data/ext/boost/mpl/minus.hpp +21 -0
  253. data/ext/boost/mpl/multiplies.hpp +53 -0
  254. data/ext/boost/mpl/negate.hpp +81 -0
  255. data/ext/boost/mpl/not_equal_to.hpp +21 -0
  256. data/ext/boost/mpl/numeric_cast.hpp +41 -0
  257. data/ext/boost/mpl/pair.hpp +70 -0
  258. data/ext/boost/mpl/plus.hpp +21 -0
  259. data/ext/boost/mpl/pop_back_fwd.hpp +24 -0
  260. data/ext/boost/mpl/pop_front_fwd.hpp +24 -0
  261. data/ext/boost/mpl/prior.hpp +19 -0
  262. data/ext/boost/mpl/push_back.hpp +53 -0
  263. data/ext/boost/mpl/push_back_fwd.hpp +24 -0
  264. data/ext/boost/mpl/push_front.hpp +52 -0
  265. data/ext/boost/mpl/push_front_fwd.hpp +24 -0
  266. data/ext/boost/mpl/remove_if.hpp +83 -0
  267. data/ext/boost/mpl/reverse_fold.hpp +50 -0
  268. data/ext/boost/mpl/same_as.hpp +55 -0
  269. data/ext/boost/mpl/sequence_tag.hpp +124 -0
  270. data/ext/boost/mpl/sequence_tag_fwd.hpp +26 -0
  271. data/ext/boost/mpl/size.hpp +42 -0
  272. data/ext/boost/mpl/size_fwd.hpp +24 -0
  273. data/ext/boost/mpl/tag.hpp +52 -0
  274. data/ext/boost/mpl/times.hpp +21 -0
  275. data/ext/boost/mpl/vector.hpp +57 -0
  276. data/ext/boost/mpl/vector/aux_/O1_size.hpp +56 -0
  277. data/ext/boost/mpl/vector/aux_/at.hpp +116 -0
  278. data/ext/boost/mpl/vector/aux_/back.hpp +59 -0
  279. data/ext/boost/mpl/vector/aux_/begin_end.hpp +49 -0
  280. data/ext/boost/mpl/vector/aux_/clear.hpp +55 -0
  281. data/ext/boost/mpl/vector/aux_/empty.hpp +68 -0
  282. data/ext/boost/mpl/vector/aux_/front.hpp +56 -0
  283. data/ext/boost/mpl/vector/aux_/include_preprocessed.hpp +55 -0
  284. data/ext/boost/mpl/vector/aux_/item.hpp +103 -0
  285. data/ext/boost/mpl/vector/aux_/iterator.hpp +130 -0
  286. data/ext/boost/mpl/vector/aux_/pop_back.hpp +40 -0
  287. data/ext/boost/mpl/vector/aux_/pop_front.hpp +40 -0
  288. data/ext/boost/mpl/vector/aux_/preprocessed/plain/vector10.hpp +829 -0
  289. data/ext/boost/mpl/vector/aux_/preprocessed/plain/vector20.hpp +1144 -0
  290. data/ext/boost/mpl/vector/aux_/preprocessed/typeof_based/vector10.hpp +139 -0
  291. data/ext/boost/mpl/vector/aux_/preprocessed/typeof_based/vector20.hpp +159 -0
  292. data/ext/boost/mpl/vector/aux_/push_back.hpp +40 -0
  293. data/ext/boost/mpl/vector/aux_/push_front.hpp +40 -0
  294. data/ext/boost/mpl/vector/aux_/size.hpp +49 -0
  295. data/ext/boost/mpl/vector/aux_/tag.hpp +32 -0
  296. data/ext/boost/mpl/vector/aux_/vector0.hpp +52 -0
  297. data/ext/boost/mpl/vector/vector0.hpp +34 -0
  298. data/ext/boost/mpl/vector/vector10.hpp +45 -0
  299. data/ext/boost/mpl/vector/vector20.hpp +45 -0
  300. data/ext/boost/none.hpp +1 -1
  301. data/ext/boost/numeric/conversion/bounds.hpp +24 -0
  302. data/ext/boost/numeric/conversion/cast.hpp +61 -0
  303. data/ext/boost/numeric/conversion/conversion_traits.hpp +39 -0
  304. data/ext/boost/numeric/conversion/converter.hpp +68 -0
  305. data/ext/boost/numeric/conversion/converter_policies.hpp +186 -0
  306. data/ext/boost/numeric/conversion/detail/bounds.hpp +58 -0
  307. data/ext/boost/numeric/conversion/detail/conversion_traits.hpp +97 -0
  308. data/ext/boost/numeric/conversion/detail/converter.hpp +602 -0
  309. data/ext/boost/numeric/conversion/detail/int_float_mixture.hpp +72 -0
  310. data/ext/boost/numeric/conversion/detail/is_subranged.hpp +234 -0
  311. data/ext/boost/numeric/conversion/detail/meta.hpp +120 -0
  312. data/ext/boost/numeric/conversion/detail/numeric_cast_traits.hpp +138 -0
  313. data/ext/boost/numeric/conversion/detail/preprocessed/numeric_cast_traits_common.hpp +1741 -0
  314. data/ext/boost/numeric/conversion/detail/preprocessed/numeric_cast_traits_long_long.hpp +347 -0
  315. data/ext/boost/numeric/conversion/detail/sign_mixture.hpp +72 -0
  316. data/ext/boost/numeric/conversion/detail/udt_builtin_mixture.hpp +69 -0
  317. data/ext/boost/numeric/conversion/int_float_mixture_enum.hpp +29 -0
  318. data/ext/boost/numeric/conversion/numeric_cast_traits.hpp +31 -0
  319. data/ext/boost/numeric/conversion/sign_mixture_enum.hpp +29 -0
  320. data/ext/boost/numeric/conversion/udt_builtin_mixture_enum.hpp +26 -0
  321. data/ext/boost/operators.hpp +3 -1
  322. data/ext/boost/optional/optional.hpp +146 -79
  323. data/ext/boost/optional/optional_fwd.hpp +8 -1
  324. data/ext/boost/preprocessor/cat.hpp +2 -2
  325. data/ext/boost/preprocessor/config/config.hpp +39 -4
  326. data/ext/boost/preprocessor/facilities/intercept.hpp +277 -0
  327. data/ext/boost/preprocessor/facilities/overload.hpp +25 -0
  328. data/ext/boost/preprocessor/iteration/detail/iter/forward1.hpp +3 -3
  329. data/ext/boost/preprocessor/iteration/iterate.hpp +3 -3
  330. data/ext/boost/preprocessor/punctuation/paren.hpp +23 -0
  331. data/ext/boost/preprocessor/repetition/enum_shifted_params.hpp +44 -0
  332. data/ext/boost/preprocessor/seq/cat.hpp +5 -4
  333. data/ext/boost/preprocessor/seq/size.hpp +0 -1
  334. data/ext/boost/preprocessor/tuple/eat.hpp +83 -34
  335. data/ext/boost/preprocessor/tuple/elem.hpp +161 -355
  336. data/ext/boost/preprocessor/tuple/rem.hpp +110 -48
  337. data/ext/boost/preprocessor/tuple/to_list.hpp +90 -36
  338. data/ext/boost/preprocessor/variadic/elem.hpp +94 -0
  339. data/ext/boost/preprocessor/variadic/size.hpp +30 -0
  340. data/ext/boost/range/begin.hpp +17 -6
  341. data/ext/boost/range/concepts.hpp +37 -2
  342. data/ext/boost/range/detail/safe_bool.hpp +72 -0
  343. data/ext/boost/range/end.hpp +14 -9
  344. data/ext/boost/range/iterator_range_core.hpp +120 -12
  345. data/ext/boost/range/size.hpp +21 -5
  346. data/ext/boost/smart_ptr/detail/shared_count.hpp +88 -0
  347. data/ext/boost/smart_ptr/detail/sp_counted_base.hpp +3 -0
  348. data/ext/boost/smart_ptr/detail/sp_counted_base_aix.hpp +142 -0
  349. data/ext/boost/smart_ptr/detail/sp_counted_base_gcc_mips.hpp +9 -0
  350. data/ext/boost/smart_ptr/detail/sp_counted_impl.hpp +10 -2
  351. data/ext/boost/smart_ptr/detail/sp_has_sync.hpp +5 -1
  352. data/ext/boost/smart_ptr/detail/spinlock.hpp +4 -1
  353. data/ext/boost/smart_ptr/detail/spinlock_gcc_arm.hpp +20 -3
  354. data/ext/boost/smart_ptr/detail/spinlock_pool.hpp +4 -0
  355. data/ext/boost/smart_ptr/make_shared.hpp +591 -22
  356. data/ext/boost/smart_ptr/shared_array.hpp +29 -1
  357. data/ext/boost/smart_ptr/shared_ptr.hpp +29 -13
  358. data/ext/boost/smart_ptr/weak_ptr.hpp +24 -12
  359. data/ext/boost/src/pthread/once.cpp +9 -7
  360. data/ext/boost/src/pthread/thread.cpp +32 -28
  361. data/ext/boost/src/pthread/timeconv.inl +4 -5
  362. data/ext/boost/src/tss_null.cpp +5 -1
  363. data/ext/boost/static_assert.hpp +8 -2
  364. data/ext/boost/thread/detail/config.hpp +19 -4
  365. data/ext/boost/thread/detail/move.hpp +11 -5
  366. data/ext/boost/thread/detail/thread.hpp +59 -43
  367. data/ext/boost/thread/exceptions.hpp +9 -9
  368. data/ext/boost/thread/future.hpp +150 -82
  369. data/ext/boost/thread/locks.hpp +101 -60
  370. data/ext/boost/thread/pthread/condition_variable.hpp +79 -32
  371. data/ext/boost/thread/pthread/condition_variable_fwd.hpp +12 -3
  372. data/ext/boost/thread/pthread/mutex.hpp +17 -14
  373. data/ext/boost/thread/pthread/once.hpp +3 -4
  374. data/ext/boost/thread/pthread/pthread_mutex_scoped_lock.hpp +12 -2
  375. data/ext/boost/thread/pthread/recursive_mutex.hpp +19 -19
  376. data/ext/boost/thread/pthread/shared_mutex.hpp +13 -13
  377. data/ext/boost/thread/pthread/thread_data.hpp +40 -12
  378. data/ext/boost/thread/thread_time.hpp +5 -0
  379. data/ext/boost/throw_exception.hpp +1 -1
  380. data/ext/boost/token_functions.hpp +34 -10
  381. data/ext/boost/type_traits/add_rvalue_reference.hpp +66 -0
  382. data/ext/boost/type_traits/alignment_of.hpp +1 -1
  383. data/ext/boost/type_traits/detail/bool_trait_def.hpp +26 -3
  384. data/ext/boost/type_traits/detail/bool_trait_undef.hpp +3 -2
  385. data/ext/boost/type_traits/detail/cv_traits_impl.hpp +1 -1
  386. data/ext/boost/type_traits/detail/size_t_trait_def.hpp +6 -4
  387. data/ext/boost/type_traits/detail/type_trait_def.hpp +8 -2
  388. data/ext/boost/type_traits/function_traits.hpp +1 -1
  389. data/ext/boost/type_traits/has_nothrow_constructor.hpp +53 -0
  390. data/ext/boost/type_traits/has_nothrow_copy.hpp +19 -5
  391. data/ext/boost/type_traits/has_trivial_constructor.hpp +51 -0
  392. data/ext/boost/type_traits/has_trivial_copy.hpp +20 -5
  393. data/ext/boost/type_traits/has_trivial_destructor.hpp +12 -5
  394. data/ext/boost/type_traits/intrinsics.hpp +119 -71
  395. data/ext/boost/type_traits/is_const.hpp +5 -5
  396. data/ext/boost/type_traits/is_convertible.hpp +14 -13
  397. data/ext/boost/type_traits/is_enum.hpp +1 -1
  398. data/ext/boost/type_traits/is_floating_point.hpp +27 -0
  399. data/ext/boost/type_traits/is_function.hpp +3 -3
  400. data/ext/boost/type_traits/is_fundamental.hpp +1 -1
  401. data/ext/boost/type_traits/is_member_function_pointer.hpp +2 -2
  402. data/ext/boost/type_traits/is_member_pointer.hpp +2 -2
  403. data/ext/boost/type_traits/is_pod.hpp +11 -3
  404. data/ext/boost/type_traits/is_pointer.hpp +2 -2
  405. data/ext/boost/type_traits/is_signed.hpp +8 -3
  406. data/ext/boost/type_traits/is_union.hpp +8 -0
  407. data/ext/boost/type_traits/is_unsigned.hpp +9 -4
  408. data/ext/boost/type_traits/is_volatile.hpp +5 -5
  409. data/ext/boost/type_traits/remove_cv.hpp +4 -3
  410. data/ext/boost/type_traits/remove_pointer.hpp +51 -2
  411. data/ext/boost/type_traits/remove_reference.hpp +2 -2
  412. data/ext/boost/type_traits/type_with_alignment.hpp +8 -2
  413. data/ext/boost/utility/declval.hpp +44 -0
  414. data/ext/boost/utility/detail/in_place_factory_prefix.hpp +36 -0
  415. data/ext/boost/utility/detail/in_place_factory_suffix.hpp +23 -0
  416. data/ext/boost/utility/detail/result_of_iterate.hpp +142 -0
  417. data/ext/boost/utility/in_place_factory.hpp +88 -0
  418. data/ext/boost/utility/result_of.hpp +103 -0
  419. data/ext/boost/utility/swap.hpp +55 -0
  420. data/ext/common/AnsiColorConstants.h +36 -0
  421. data/ext/common/ApplicationPool2/Common.h +87 -0
  422. data/ext/common/ApplicationPool2/ComponentInfo.h +53 -0
  423. data/ext/common/ApplicationPool2/Group.h +648 -0
  424. data/ext/common/ApplicationPool2/Implementation.cpp +580 -0
  425. data/ext/common/ApplicationPool2/Options.h +576 -0
  426. data/ext/common/ApplicationPool2/PipeWatcher.h +61 -0
  427. data/ext/common/ApplicationPool2/Pool.h +1181 -0
  428. data/ext/common/ApplicationPool2/Process.h +425 -0
  429. data/ext/common/ApplicationPool2/README.md +96 -0
  430. data/ext/common/ApplicationPool2/Session.h +158 -0
  431. data/ext/common/ApplicationPool2/Socket.h +246 -0
  432. data/ext/common/ApplicationPool2/Spawner.h +2212 -0
  433. data/ext/common/ApplicationPool2/SuperGroup.h +749 -0
  434. data/ext/common/BackgroundEventLoop.cpp +129 -0
  435. data/ext/common/BackgroundEventLoop.h +61 -0
  436. data/ext/common/Constants.h +3 -1
  437. data/ext/common/EventedBufferedInput.h +331 -0
  438. data/ext/common/EventedMessageServer.h +17 -34
  439. data/ext/common/EventedServer.h +2 -2
  440. data/ext/common/Exceptions.h +71 -19
  441. data/ext/common/FileDescriptor.h +8 -6
  442. data/ext/common/HttpConstants.h +167 -0
  443. data/ext/common/IniFile.h +24 -0
  444. data/ext/common/Logging.h +62 -849
  445. data/ext/common/MessageReadersWriters.h +19 -0
  446. data/ext/common/MessageServer.h +11 -14
  447. data/ext/common/MultiLibeio.cpp +198 -0
  448. data/ext/common/MultiLibeio.h +67 -0
  449. data/ext/common/ResourceLocator.h +24 -41
  450. data/ext/common/SafeLibev.h +186 -14
  451. data/ext/common/StaticString.h +23 -3
  452. data/ext/common/UnionStation.h +972 -0
  453. data/ext/common/Utils.cpp +168 -24
  454. data/ext/common/Utils.h +25 -3
  455. data/ext/common/Utils/CachedFileStat.hpp +4 -3
  456. data/ext/common/Utils/FileChangeChecker.h +2 -2
  457. data/ext/common/Utils/HashMap.h +50 -0
  458. data/ext/common/Utils/IOUtils.cpp +229 -68
  459. data/ext/common/Utils/IOUtils.h +134 -3
  460. data/ext/common/Utils/Lock.h +28 -0
  461. data/ext/common/Utils/MemoryBarrier.h +52 -0
  462. data/ext/common/Utils/PriorityQueue.h +54 -0
  463. data/ext/common/Utils/ProcessMetricsCollector.h +9 -11
  464. data/ext/common/Utils/ScopeGuard.h +50 -1
  465. data/ext/common/Utils/SmallVector.h +653 -0
  466. data/ext/common/Utils/StrIntUtils.cpp +26 -2
  467. data/ext/common/Utils/StrIntUtils.h +18 -2
  468. data/ext/common/Utils/StringMap.h +125 -8
  469. data/ext/common/Utils/Template.h +212 -0
  470. data/ext/common/Utils/fib.c +699 -0
  471. data/ext/common/Utils/fib.h +101 -0
  472. data/ext/common/Utils/fibpriv.h +67 -0
  473. data/ext/common/Utils/json-forwards.h +249 -0
  474. data/ext/common/Utils/json.h +1855 -0
  475. data/ext/common/Utils/jsoncpp.cpp +4230 -0
  476. data/ext/common/agents/Base.cpp +1126 -0
  477. data/ext/common/{AgentBase.h → agents/Base.h} +5 -1
  478. data/ext/common/agents/EnvPrinter.c +16 -0
  479. data/ext/common/agents/HelperAgent/AgentOptions.h +81 -0
  480. data/ext/common/{HelperAgent → agents/HelperAgent}/BacktracesServer.h +3 -2
  481. data/ext/common/agents/HelperAgent/FileBackedPipe.h +732 -0
  482. data/ext/common/agents/HelperAgent/Main.cpp +497 -0
  483. data/ext/common/agents/HelperAgent/RequestHandler.cpp +283 -0
  484. data/ext/common/agents/HelperAgent/RequestHandler.h +2139 -0
  485. data/ext/common/agents/HelperAgent/ScgiRequestParser.h +451 -0
  486. data/ext/common/{LoggingAgent → agents/LoggingAgent}/DataStoreId.h +1 -1
  487. data/ext/common/{LoggingAgent → agents/LoggingAgent}/FilterSupport.cpp +1 -1
  488. data/ext/common/{LoggingAgent → agents/LoggingAgent}/FilterSupport.h +0 -0
  489. data/ext/common/{LoggingAgent → agents/LoggingAgent}/LoggingServer.h +18 -16
  490. data/ext/common/{LoggingAgent → agents/LoggingAgent}/Main.cpp +15 -13
  491. data/ext/common/{LoggingAgent → agents/LoggingAgent}/RemoteSender.h +6 -6
  492. data/ext/common/agents/SpawnPreparer.cpp +127 -0
  493. data/ext/common/{Watchdog.cpp → agents/Watchdog/Main.cpp} +63 -25
  494. data/ext/libeio/Changes +72 -0
  495. data/ext/{google/COPYING → libeio/LICENSE} +17 -9
  496. data/ext/libeio/Makefile.am +15 -0
  497. data/ext/libeio/Makefile.in +694 -0
  498. data/ext/libeio/aclocal.m4 +9418 -0
  499. data/ext/libeio/autogen.sh +3 -0
  500. data/ext/libeio/config.guess +1501 -0
  501. data/ext/libeio/config.h.in +136 -0
  502. data/ext/libeio/config.sub +1705 -0
  503. data/ext/libeio/configure +14822 -0
  504. data/ext/libeio/configure.ac +22 -0
  505. data/ext/libeio/demo.c +194 -0
  506. data/ext/libeio/ecb.h +457 -0
  507. data/ext/libeio/eio.c +2816 -0
  508. data/ext/libeio/eio.h +411 -0
  509. data/ext/libeio/install-sh +520 -0
  510. data/ext/libeio/libeio.m4 +211 -0
  511. data/ext/libeio/ltmain.sh +9636 -0
  512. data/ext/libeio/missing +376 -0
  513. data/ext/libeio/xthread.h +166 -0
  514. data/ext/libev/Changes +125 -7
  515. data/ext/libev/Makefile.am +5 -3
  516. data/ext/libev/Makefile.in +209 -120
  517. data/ext/libev/aclocal.m4 +6027 -4619
  518. data/ext/libev/autogen.sh +1 -4
  519. data/ext/libev/config.h.in +11 -7
  520. data/ext/libev/configure +7312 -14993
  521. data/ext/libev/configure.ac +12 -5
  522. data/ext/libev/depcomp +630 -0
  523. data/ext/libev/ev++.h +48 -32
  524. data/ext/libev/ev.c +1173 -391
  525. data/ext/libev/ev.h +315 -181
  526. data/ext/libev/ev_epoll.c +66 -15
  527. data/ext/libev/ev_kqueue.c +20 -18
  528. data/ext/libev/ev_poll.c +27 -23
  529. data/ext/libev/ev_port.c +39 -19
  530. data/ext/libev/ev_select.c +23 -17
  531. data/ext/libev/ev_vars.h +25 -8
  532. data/ext/libev/ev_win32.c +6 -6
  533. data/ext/libev/ev_wrap.h +22 -2
  534. data/ext/libev/event.c +18 -17
  535. data/ext/libev/event.h +16 -4
  536. data/ext/libev/libev.m4 +10 -6
  537. data/ext/libev/ltmain.sh +7353 -5811
  538. data/ext/nginx/Configuration.c +74 -42
  539. data/ext/nginx/Configuration.h +3 -5
  540. data/ext/nginx/ContentHandler.c +26 -83
  541. data/ext/nginx/ContentHandler.h +1 -1
  542. data/ext/nginx/config +13 -9
  543. data/ext/nginx/ngx_http_passenger_module.c +3 -7
  544. data/ext/oxt/detail/backtrace_enabled.hpp +5 -102
  545. data/ext/oxt/detail/context.hpp +90 -0
  546. data/ext/oxt/detail/spin_lock_darwin.hpp +4 -0
  547. data/ext/oxt/detail/spin_lock_gcc_x86.hpp +4 -0
  548. data/ext/oxt/detail/spin_lock_pthreads.hpp +14 -0
  549. data/ext/oxt/detail/tracable_exception_enabled.hpp +2 -2
  550. data/ext/oxt/dynamic_thread_group.hpp +27 -1
  551. data/ext/oxt/implementation.cpp +415 -0
  552. data/ext/oxt/{thread.cpp → initialize.hpp} +13 -6
  553. data/ext/oxt/macros.hpp +32 -1
  554. data/ext/oxt/spin_lock.hpp +6 -11
  555. data/ext/oxt/system_calls.cpp +204 -16
  556. data/ext/oxt/system_calls.hpp +85 -45
  557. data/ext/oxt/thread.hpp +13 -117
  558. data/ext/ruby/passenger_native_support.c +82 -237
  559. data/helper-scripts/backtrace-sanitizer.rb +114 -0
  560. data/helper-scripts/classic-rails-loader.rb +135 -0
  561. data/helper-scripts/classic-rails-preloader.rb +161 -0
  562. data/helper-scripts/node-loader.js +314 -0
  563. data/helper-scripts/rack-loader.rb +104 -0
  564. data/helper-scripts/rack-preloader.rb +132 -0
  565. data/helper-scripts/wsgi-loader.py +231 -0
  566. data/helper-scripts/wsgi-preloader.py +1 -0
  567. data/lib/phusion_passenger.rb +159 -61
  568. data/lib/phusion_passenger/abstract_installer.rb +182 -87
  569. data/lib/phusion_passenger/admin_tools/server_instance.rb +25 -19
  570. data/lib/phusion_passenger/analytics_logger.rb +5 -4
  571. data/lib/phusion_passenger/classic_rails/{request_handler.rb → thread_handler_extension.rb} +4 -40
  572. data/lib/phusion_passenger/classic_rails_extensions/init.rb +5 -3
  573. data/lib/phusion_passenger/common_library.rb +441 -0
  574. data/lib/phusion_passenger/console_text_template.rb +4 -16
  575. data/lib/phusion_passenger/constants.rb +1 -8
  576. data/lib/phusion_passenger/debug_logging.rb +5 -2
  577. data/lib/phusion_passenger/dependencies.rb +51 -13
  578. data/lib/phusion_passenger/loader_shared_helpers.rb +318 -0
  579. data/lib/phusion_passenger/message_channel.rb +3 -47
  580. data/lib/phusion_passenger/message_client.rb +2 -2
  581. data/lib/phusion_passenger/native_support.rb +36 -15
  582. data/lib/phusion_passenger/packaging.rb +8 -11
  583. data/lib/phusion_passenger/platform_info.rb +25 -17
  584. data/lib/phusion_passenger/platform_info/apache.rb +10 -7
  585. data/lib/phusion_passenger/platform_info/binary_compatibility.rb +10 -30
  586. data/lib/phusion_passenger/platform_info/compiler.rb +93 -34
  587. data/lib/phusion_passenger/platform_info/ruby.rb +37 -97
  588. data/lib/phusion_passenger/preloader_shared_helpers.rb +121 -0
  589. data/lib/phusion_passenger/public_api.rb +1 -4
  590. data/lib/phusion_passenger/rack/{request_handler.rb → thread_handler_extension.rb} +14 -63
  591. data/lib/phusion_passenger/rails3_extensions/init.rb +9 -8
  592. data/lib/phusion_passenger/request_handler.rb +500 -0
  593. data/lib/phusion_passenger/request_handler/thread_handler.rb +360 -0
  594. data/lib/phusion_passenger/ruby_core_enhancements.rb +142 -0
  595. data/lib/phusion_passenger/standalone/command.rb +36 -15
  596. data/lib/phusion_passenger/standalone/package_runtime_command.rb +16 -8
  597. data/lib/phusion_passenger/standalone/runtime_installer.rb +169 -72
  598. data/lib/phusion_passenger/standalone/start_command.rb +44 -39
  599. data/lib/phusion_passenger/standalone/utils.rb +5 -5
  600. data/lib/phusion_passenger/utils.rb +35 -914
  601. data/lib/phusion_passenger/utils/ansi_colors.rb +59 -0
  602. data/lib/phusion_passenger/utils/file_system_watcher.rb +1 -1
  603. data/lib/phusion_passenger/utils/robust_interruption.rb +134 -0
  604. data/lib/phusion_passenger/utils/tee_input.rb +174 -0
  605. data/lib/phusion_passenger/utils/tmpio.rb +33 -0
  606. data/lib/phusion_passenger/utils/unseekable_socket.rb +6 -0
  607. data/resources/mime.types +5 -1
  608. data/{lib/phusion_passenger/templates → resources}/standalone_default_root/index.html +0 -0
  609. data/{lib/phusion_passenger → resources}/templates/apache2/apache_must_be_compiled_with_compatible_mpm.txt.erb +0 -0
  610. data/{lib/phusion_passenger → resources}/templates/apache2/config_snippets.txt.erb +0 -0
  611. data/{lib/phusion_passenger → resources}/templates/apache2/deployment_example.txt.erb +0 -0
  612. data/{lib/phusion_passenger → resources}/templates/apache2/no_write_permission_to_passenger_root.txt.erb +0 -0
  613. data/{lib/phusion_passenger → resources}/templates/apache2/possible_solutions_for_compilation_and_installation_problems.txt.erb +0 -0
  614. data/{lib/phusion_passenger → resources}/templates/apache2/run_installer_as_root.txt.erb +0 -0
  615. data/{lib/phusion_passenger → resources}/templates/apache2/welcome.txt.erb +0 -0
  616. data/{lib/phusion_passenger → resources}/templates/error_layout.css +6 -0
  617. data/resources/templates/error_layout.html.template +89 -0
  618. data/resources/templates/general_error.html.template +1 -0
  619. data/resources/templates/general_error_with_html.html.template +1 -0
  620. data/{lib/phusion_passenger → resources}/templates/nginx/ask_for_extra_configure_flags.txt.erb +0 -0
  621. data/{lib/phusion_passenger → resources}/templates/nginx/cannot_write_to_dir.txt.erb +0 -0
  622. data/{lib/phusion_passenger → resources}/templates/nginx/config_snippets.txt.erb +0 -0
  623. data/{lib/phusion_passenger → resources}/templates/nginx/config_snippets_inserted.txt.erb +0 -0
  624. data/{lib/phusion_passenger → resources}/templates/nginx/confirm_extra_configure_flags.txt.erb +0 -0
  625. data/{lib/phusion_passenger → resources}/templates/nginx/deployment_example.txt.erb +0 -0
  626. data/resources/templates/nginx/not_available_when_natively_packaged.txt.erb +8 -0
  627. data/{lib/phusion_passenger → resources}/templates/nginx/pcre_could_not_be_downloaded.txt.erb +0 -0
  628. data/{lib/phusion_passenger → resources}/templates/nginx/pcre_could_not_be_extracted.txt.erb +0 -0
  629. data/{lib/phusion_passenger → resources}/templates/nginx/possible_solutions_for_compilation_and_installation_problems.txt.erb +0 -0
  630. data/{lib/phusion_passenger → resources}/templates/nginx/possible_solutions_for_download_and_extraction_problems.txt.erb +0 -0
  631. data/{lib/phusion_passenger → resources}/templates/nginx/query_download_and_install.txt.erb +0 -0
  632. data/{lib/phusion_passenger → resources}/templates/nginx/run_installer_as_root.txt.erb +0 -0
  633. data/{lib/phusion_passenger → resources}/templates/nginx/welcome.txt.erb +0 -0
  634. data/{lib/phusion_passenger → resources}/templates/standalone/cannot_write_to_dir.txt.erb +0 -0
  635. data/{lib/phusion_passenger → resources}/templates/standalone/config.erb +26 -5
  636. data/{lib/phusion_passenger → resources}/templates/standalone/possible_solutions_for_download_and_extraction_problems.txt.erb +0 -0
  637. data/{lib/phusion_passenger → resources}/templates/standalone/run_installer_as_root.txt.erb +0 -0
  638. data/{lib/phusion_passenger → resources}/templates/standalone/welcome.txt.erb +0 -0
  639. data/resources/templates/undisclosed_error.html.template +25 -0
  640. data/test/config.json.example +42 -0
  641. data/test/cxx/ApplicationPool2/DirectSpawnerTest.cpp +86 -0
  642. data/test/cxx/ApplicationPool2/OptionsTest.cpp +44 -0
  643. data/test/cxx/ApplicationPool2/PoolTest.cpp +1234 -0
  644. data/test/cxx/ApplicationPool2/ProcessTest.cpp +131 -0
  645. data/test/cxx/ApplicationPool2/SmartSpawnerTest.cpp +229 -0
  646. data/test/cxx/ApplicationPool2/SpawnerTestCases.cpp +744 -0
  647. data/test/cxx/BufferedIOTest.cpp +7 -7
  648. data/test/cxx/CxxTestMain.cpp +65 -2
  649. data/test/cxx/FileBackedPipeTest.cpp +626 -0
  650. data/test/cxx/FileChangeCheckerTest.cpp +20 -18
  651. data/test/cxx/FilterSupportTest.cpp +5 -5
  652. data/test/cxx/IOUtilsTest.cpp +11 -4
  653. data/test/cxx/MessageReadersWritersTest.cpp +1 -1
  654. data/test/cxx/MessageServerTest.cpp +31 -30
  655. data/test/cxx/RequestHandlerTest.cpp +777 -0
  656. data/test/cxx/ScgiRequestParserTest.cpp +36 -16
  657. data/test/cxx/ServerInstanceDirTest.cpp +1 -1
  658. data/test/cxx/StringMapTest.cpp +61 -0
  659. data/test/cxx/TemplateTest.cpp +118 -0
  660. data/test/cxx/TestSupport.cpp +25 -68
  661. data/test/cxx/TestSupport.h +81 -41
  662. data/test/cxx/{LoggingTest.cpp → UnionStationTest.cpp} +79 -74
  663. data/test/cxx/UtilsTest.cpp +59 -5
  664. data/test/integration_tests/apache2_tests.rb +2 -2
  665. data/test/integration_tests/nginx_tests.rb +1 -1
  666. data/test/integration_tests/spec_helper.rb +7 -5
  667. data/test/oxt/oxt_test_main.cpp +2 -0
  668. data/test/oxt/syscall_interruption_test.cpp +1 -0
  669. data/test/ruby/classic_rails/loader_spec.rb +48 -0
  670. data/test/ruby/classic_rails/preloader_spec.rb +54 -0
  671. data/test/ruby/rack/loader_spec.rb +62 -0
  672. data/test/ruby/rack/preloader_spec.rb +74 -0
  673. data/test/ruby/{abstract_request_handler_spec.rb → request_handler_spec.rb} +31 -68
  674. data/test/ruby/shared/loader_spec.rb +241 -0
  675. data/test/ruby/shared/rails/analytics_logging_extensions_spec.rb +141 -182
  676. data/test/ruby/shared/ruby_loader_spec.rb +55 -0
  677. data/test/ruby/spec_helper.rb +8 -53
  678. data/test/ruby/utils/file_system_watcher_spec.rb +9 -1
  679. data/test/ruby/utils_spec.rb +10 -683
  680. data/test/stub/rack/config.ru +28 -3
  681. data/test/stub/rack/start.rb +47 -0
  682. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/Rakefile +0 -0
  683. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/app/controllers/application_controller.rb +0 -2
  684. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/app/controllers/bar_controller_1.rb +0 -0
  685. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/app/controllers/bar_controller_2.rb +0 -0
  686. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/app/controllers/foo_controller.rb +0 -0
  687. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/app/helpers/application_helper.rb +0 -0
  688. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/config/boot.rb +0 -0
  689. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/config/database.yml +3 -3
  690. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/config/environment.rb +5 -2
  691. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/config/environments/development.rb +0 -0
  692. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/config/environments/production.rb +0 -0
  693. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/config/environments/staging.rb +0 -0
  694. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/config/initializers/inflections.rb +0 -0
  695. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/config/initializers/mime_types.rb +0 -0
  696. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/config/routes.rb +1 -0
  697. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/script/about +0 -0
  698. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/script/console +0 -0
  699. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/script/dbconsole +0 -0
  700. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/script/destroy +0 -0
  701. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/script/generate +0 -0
  702. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/script/performance/benchmarker +0 -0
  703. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/script/performance/profiler +0 -0
  704. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/script/performance/request +0 -0
  705. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/script/plugin +0 -0
  706. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/script/process/inspector +0 -0
  707. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/script/process/reaper +0 -0
  708. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/script/process/spawner +0 -0
  709. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/script/runner +0 -0
  710. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/script/server +0 -0
  711. data/test/stub/{rails_apps/3.0/empty → rails3.0}/Gemfile +0 -0
  712. data/test/stub/rails3.0/Gemfile.lock +80 -0
  713. data/test/stub/{rails_apps/3.0/empty → rails3.0}/Rakefile +0 -0
  714. data/test/stub/{rails_apps/3.0/empty → rails3.0}/app/controllers/application_controller.rb +0 -0
  715. data/test/stub/{rails_apps/3.0/empty → rails3.0}/app/helpers/application_helper.rb +0 -0
  716. data/test/stub/{rails_apps/3.0/empty → rails3.0}/app/views/layouts/application.html.erb +0 -0
  717. data/test/stub/{rails_apps/3.0/empty → rails3.0}/config.ru +0 -0
  718. data/test/stub/{rails_apps/3.0/empty → rails3.0}/config/application.rb +0 -0
  719. data/test/stub/{rails_apps/3.0/empty → rails3.0}/config/boot.rb +0 -0
  720. data/test/stub/{rails_apps/3.0/empty → rails3.0}/config/database.yml +0 -0
  721. data/test/stub/{rails_apps/3.0/empty → rails3.0}/config/environment.rb +0 -0
  722. data/test/stub/{rails_apps/3.0/empty → rails3.0}/config/environments/development.rb +0 -0
  723. data/test/stub/{rails_apps/3.0/empty → rails3.0}/config/environments/production.rb +0 -0
  724. data/test/stub/{rails_apps/3.0/empty → rails3.0}/config/environments/test.rb +0 -0
  725. data/test/stub/{rails_apps/3.0/empty → rails3.0}/config/initializers/backtrace_silencers.rb +0 -0
  726. data/test/stub/{rails_apps/3.0/empty → rails3.0}/config/initializers/inflections.rb +0 -0
  727. data/test/stub/{rails_apps/3.0/empty → rails3.0}/config/initializers/mime_types.rb +0 -0
  728. data/test/stub/{rails_apps/3.0/empty → rails3.0}/config/initializers/passenger.rb +0 -0
  729. data/test/stub/{rails_apps/3.0/empty → rails3.0}/config/initializers/secret_token.rb +0 -0
  730. data/test/stub/{rails_apps/3.0/empty → rails3.0}/config/initializers/session_store.rb +0 -0
  731. data/test/stub/{rails_apps/3.0/empty → rails3.0}/config/locales/en.yml +0 -0
  732. data/test/stub/{rails_apps/3.0/empty → rails3.0}/config/routes.rb +0 -0
  733. data/test/stub/{rails_apps/3.0/empty → rails3.0}/db/seeds.rb +0 -0
  734. data/test/stub/{rails_apps/3.0/empty → rails3.0}/doc/README_FOR_APP +0 -0
  735. data/test/stub/{rails_apps/3.0/empty → rails3.0}/public/404.html +0 -0
  736. data/test/stub/{rails_apps/3.0/empty → rails3.0}/public/422.html +0 -0
  737. data/test/stub/{rails_apps/3.0/empty → rails3.0}/public/500.html +0 -0
  738. data/test/stub/{rails_apps/3.0/empty → rails3.0}/public/favicon.ico +0 -0
  739. data/test/stub/{rails_apps/3.0/empty → rails3.0}/public/index.html +0 -0
  740. data/test/stub/{rails_apps/3.0/empty → rails3.0}/public/robots.txt +0 -0
  741. data/test/stub/{rails_apps/3.0/empty → rails3.0}/script/rails +0 -0
  742. data/test/stub/{rails_apps/3.0/empty → rails3.0}/test/performance/browsing_test.rb +0 -0
  743. data/test/stub/{rails_apps/3.0/empty → rails3.0}/test/test_helper.rb +0 -0
  744. data/test/stub/start_error.pl +24 -0
  745. data/test/stub/wsgi/passenger_wsgi.py +71 -3
  746. data/test/support/apache2_controller.rb +2 -2
  747. data/test/support/placebo-preloader.rb +88 -0
  748. data/test/support/test_helper.rb +1 -14
  749. data/test/tut/tut.h +11 -4
  750. metadata +590 -326
  751. data.tar.gz.asc +0 -12
  752. data/PACKAGING.TXT +0 -25
  753. data/build/config.rb +0 -46
  754. data/ext/apache2/HelperAgent.cpp +0 -364
  755. data/ext/boost/call_traits.hpp +0 -24
  756. data/ext/boost/detail/call_traits.hpp +0 -164
  757. data/ext/common/AbstractSpawnManager.h +0 -110
  758. data/ext/common/AgentBase.cpp +0 -432
  759. data/ext/common/ApplicationPool/Client.h +0 -788
  760. data/ext/common/ApplicationPool/Interface.h +0 -295
  761. data/ext/common/ApplicationPool/Pool.h +0 -1327
  762. data/ext/common/ApplicationPool/Server.h +0 -479
  763. data/ext/common/MessageChannel.h +0 -494
  764. data/ext/common/PoolOptions.h +0 -518
  765. data/ext/common/Process.h +0 -253
  766. data/ext/common/Session.h +0 -436
  767. data/ext/common/SpawnManager.h +0 -611
  768. data/ext/google/ChangeLog +0 -167
  769. data/ext/google/dense_hash_map +0 -310
  770. data/ext/google/dense_hash_set +0 -287
  771. data/ext/google/sparse_hash_map +0 -294
  772. data/ext/google/sparse_hash_set +0 -275
  773. data/ext/google/sparsehash/densehashtable.h +0 -1062
  774. data/ext/google/sparsehash/sparseconfig.h +0 -55
  775. data/ext/google/sparsehash/sparsehashtable.h +0 -1015
  776. data/ext/google/sparsetable +0 -1468
  777. data/ext/google/type_traits.h +0 -250
  778. data/ext/nginx/HelperAgent.cpp +0 -1355
  779. data/ext/nginx/ScgiRequestParser.h +0 -375
  780. data/ext/oxt/backtrace.cpp +0 -185
  781. data/ext/oxt/tracable_exception.cpp +0 -89
  782. data/helper-scripts/passenger-spawn-server +0 -106
  783. data/lib/phusion_passenger/abstract_request_handler.rb +0 -766
  784. data/lib/phusion_passenger/abstract_server.rb +0 -372
  785. data/lib/phusion_passenger/abstract_server_collection.rb +0 -335
  786. data/lib/phusion_passenger/app_process.rb +0 -174
  787. data/lib/phusion_passenger/classic_rails/application_spawner.rb +0 -344
  788. data/lib/phusion_passenger/classic_rails/framework_spawner.rb +0 -311
  789. data/lib/phusion_passenger/exceptions.rb +0 -103
  790. data/lib/phusion_passenger/html_template.rb +0 -107
  791. data/lib/phusion_passenger/rack/application_spawner.rb +0 -231
  792. data/lib/phusion_passenger/spawn_manager.rb +0 -359
  793. data/lib/phusion_passenger/templates/app_exited_during_initialization.html.erb +0 -38
  794. data/lib/phusion_passenger/templates/app_init_error.html.erb +0 -64
  795. data/lib/phusion_passenger/templates/database_error.html.erb +0 -66
  796. data/lib/phusion_passenger/templates/error_layout.html.erb +0 -39
  797. data/lib/phusion_passenger/templates/framework_init_error.html.erb +0 -39
  798. data/lib/phusion_passenger/templates/general_error.html.erb +0 -22
  799. data/lib/phusion_passenger/templates/load_error.html.erb +0 -46
  800. data/lib/phusion_passenger/templates/version_not_found.html.erb +0 -34
  801. data/lib/phusion_passenger/utils/rewindable_input.rb +0 -125
  802. data/lib/phusion_passenger/wsgi/application_spawner.rb +0 -108
  803. data/test/config.yml.example +0 -41
  804. data/test/cxx/ApplicationPool_PoolTest.cpp +0 -33
  805. data/test/cxx/ApplicationPool_PoolTestCases.cpp +0 -1029
  806. data/test/cxx/ApplicationPool_ServerTest.cpp +0 -308
  807. data/test/cxx/ApplicationPool_Server_PoolTest.cpp +0 -80
  808. data/test/cxx/MessageChannelTest.cpp +0 -557
  809. data/test/cxx/PoolOptionsTest.cpp +0 -116
  810. data/test/cxx/SpawnManagerTest.cpp +0 -161
  811. data/test/ruby/abstract_server_collection_spec.rb +0 -247
  812. data/test/ruby/abstract_server_spec.rb +0 -61
  813. data/test/ruby/app_process_spec.rb +0 -43
  814. data/test/ruby/classic_rails/application_spawner_spec.rb +0 -89
  815. data/test/ruby/classic_rails/framework_spawner_spec.rb +0 -92
  816. data/test/ruby/rack/application_spawner_spec.rb +0 -116
  817. data/test/ruby/shared/abstract_server_spec.rb +0 -23
  818. data/test/ruby/shared/spawners/classic_rails/framework_spawner_spec.rb +0 -38
  819. data/test/ruby/shared/spawners/classic_rails/lack_of_rails_gem_version_spec.rb +0 -19
  820. data/test/ruby/shared/spawners/classic_rails/spawner_spec.rb +0 -15
  821. data/test/ruby/shared/spawners/non_preloading_spawner_spec.rb +0 -27
  822. data/test/ruby/shared/spawners/preloading_spawner_spec.rb +0 -29
  823. data/test/ruby/shared/spawners/reload_all_spec.rb +0 -36
  824. data/test/ruby/shared/spawners/reload_single_spec.rb +0 -52
  825. data/test/ruby/shared/spawners/spawn_server_spec.rb +0 -28
  826. data/test/ruby/shared/spawners/spawner_spec.rb +0 -273
  827. data/test/ruby/shared/utils/pseudo_io_spec.rb +0 -60
  828. data/test/ruby/spawn_manager_spec.rb +0 -134
  829. data/test/ruby/wsgi/application_spawner_spec.rb +0 -50
  830. data/test/stub/message_channel.rb +0 -11
  831. data/test/stub/message_channel_2.rb +0 -12
  832. data/test/stub/message_channel_3.rb +0 -19
  833. data/test/stub/rails_apps/3.0/empty/Gemfile.lock +0 -73
  834. data/test/stub/spawn_server.rb +0 -22
  835. metadata.gz.asc +0 -12
@@ -1,275 +0,0 @@
1
- // Copyright (c) 2005, Google Inc.
2
- // All rights reserved.
3
- //
4
- // Redistribution and use in source and binary forms, with or without
5
- // modification, are permitted provided that the following conditions are
6
- // met:
7
- //
8
- // * Redistributions of source code must retain the above copyright
9
- // notice, this list of conditions and the following disclaimer.
10
- // * Redistributions in binary form must reproduce the above
11
- // copyright notice, this list of conditions and the following disclaimer
12
- // in the documentation and/or other materials provided with the
13
- // distribution.
14
- // * Neither the name of Google Inc. nor the names of its
15
- // contributors may be used to endorse or promote products derived from
16
- // this software without specific prior written permission.
17
- //
18
- // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19
- // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20
- // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21
- // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22
- // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23
- // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24
- // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25
- // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26
- // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27
- // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28
- // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
-
30
- // ---
31
- // Author: Craig Silverstein
32
- //
33
- // This is just a very thin wrapper over sparsehashtable.h, just
34
- // like sgi stl's stl_hash_set is a very thin wrapper over
35
- // stl_hashtable. The major thing we define is operator[], because
36
- // we have a concept of a data_type which stl_hashtable doesn't
37
- // (it only has a key and a value).
38
- //
39
- // This is more different from sparse_hash_map than you might think,
40
- // because all iterators for sets are const (you obviously can't
41
- // change the key, and for sets there is no value).
42
- //
43
- // We adhere mostly to the STL semantics for hash-set. One important
44
- // exception is that insert() invalidates iterators entirely. On the
45
- // plus side, though, delete() doesn't invalidate iterators at all, or
46
- // even change the ordering of elements.
47
- //
48
- // Here are a few "power user" tips:
49
- //
50
- // 1) set_deleted_key():
51
- // Unlike STL's hash_map, if you want to use erase() you
52
- // *must* call set_deleted_key() after construction.
53
- //
54
- // 2) resize(0):
55
- // When an item is deleted, its memory isn't freed right
56
- // away. This allows you to iterate over a hashtable,
57
- // and call erase(), without invalidating the iterator.
58
- // To force the memory to be freed, call resize(0).
59
- // For tr1 compatibility, this can also be called as rehash(0).
60
- //
61
- // 3) min_load_factor(0.0)
62
- // Setting the minimum load factor to 0.0 guarantees that
63
- // the hash table will never shrink.
64
- //
65
- // Guide to what kind of hash_set to use:
66
- // (1) dense_hash_set: fastest, uses the most memory
67
- // (2) sparse_hash_set: slowest, uses the least memory
68
- // (3) hash_set /unordered_set (STL): in the middle
69
- // Typically I use sparse_hash_set when I care about space and/or when
70
- // I need to save the hashtable on disk. I use hash_set otherwise. I
71
- // don't personally use dense_hash_set ever; some people use it for
72
- // small sets with lots of lookups.
73
- //
74
- // - dense_hash_set has, typically, a factor of 2 memory overhead (if your
75
- // data takes up X bytes, the hash_set uses X more bytes in overhead).
76
- // - sparse_hash_set has about 2 bits overhead per entry.
77
- // - sparse_hash_map can be 3-7 times slower than the others for lookup and,
78
- // especially, inserts. See time_hash_map.cc for details.
79
- //
80
- // See /usr/(local/)?doc/sparsehash-*/sparse_hash_set.html
81
- // for information about how to use this class.
82
-
83
- #ifndef _SPARSE_HASH_SET_H_
84
- #define _SPARSE_HASH_SET_H_
85
-
86
- #include <google/sparsehash/sparseconfig.h>
87
- #include <stdio.h> // for FILE * in read()/write()
88
- #include <algorithm> // for the default template args
89
- #include <functional> // for equal_to
90
- #include <memory> // for alloc<>
91
- #include <utility> // for pair<>
92
- #include HASH_FUN_H // defined in config.h
93
- #include <google/sparsehash/sparsehashtable.h>
94
-
95
- _START_GOOGLE_NAMESPACE_
96
-
97
- using STL_NAMESPACE::pair;
98
-
99
- template <class Value,
100
- class HashFcn = SPARSEHASH_HASH<Value>, // defined in sparseconfig.h
101
- class EqualKey = STL_NAMESPACE::equal_to<Value>,
102
- class Alloc = STL_NAMESPACE::allocator<Value> >
103
- class sparse_hash_set {
104
- private:
105
- // Apparently identity is not stl-standard, so we define our own
106
- struct Identity {
107
- Value& operator()(Value& v) const { return v; }
108
- const Value& operator()(const Value& v) const { return v; }
109
- };
110
- struct SetKey {
111
- void operator()(Value* value, const Value& new_key) const {
112
- *value = new_key;
113
- }
114
- };
115
-
116
- // The actual data
117
- typedef sparse_hashtable<Value, Value, HashFcn,
118
- Identity, SetKey, EqualKey, Alloc> ht;
119
- ht rep;
120
-
121
- public:
122
- typedef typename ht::key_type key_type;
123
- typedef typename ht::value_type value_type;
124
- typedef typename ht::hasher hasher;
125
- typedef typename ht::key_equal key_equal;
126
- typedef Alloc allocator_type;
127
-
128
- typedef typename ht::size_type size_type;
129
- typedef typename ht::difference_type difference_type;
130
- typedef typename ht::const_pointer pointer;
131
- typedef typename ht::const_pointer const_pointer;
132
- typedef typename ht::const_reference reference;
133
- typedef typename ht::const_reference const_reference;
134
-
135
- typedef typename ht::const_iterator iterator;
136
- typedef typename ht::const_iterator const_iterator;
137
- typedef typename ht::const_local_iterator local_iterator;
138
- typedef typename ht::const_local_iterator const_local_iterator;
139
-
140
-
141
- // Iterator functions -- recall all iterators are const
142
- iterator begin() const { return rep.begin(); }
143
- iterator end() const { return rep.end(); }
144
-
145
- // These come from tr1's unordered_set. For us, a bucket has 0 or 1 elements.
146
- local_iterator begin(size_type i) const { return rep.begin(i); }
147
- local_iterator end(size_type i) const { return rep.end(i); }
148
-
149
-
150
- // Accessor functions
151
- // TODO(csilvers): implement Alloc get_allocator() const;
152
- hasher hash_funct() const { return rep.hash_funct(); }
153
- hasher hash_function() const { return hash_funct(); } // tr1 name
154
- key_equal key_eq() const { return rep.key_eq(); }
155
-
156
-
157
- // Constructors
158
- explicit sparse_hash_set(size_type expected_max_items_in_table = 0,
159
- const hasher& hf = hasher(),
160
- const key_equal& eql = key_equal())
161
- : rep(expected_max_items_in_table, hf, eql) { }
162
-
163
- template <class InputIterator>
164
- sparse_hash_set(InputIterator f, InputIterator l,
165
- size_type expected_max_items_in_table = 0,
166
- const hasher& hf = hasher(),
167
- const key_equal& eql = key_equal())
168
- : rep(expected_max_items_in_table, hf, eql) {
169
- rep.insert(f, l);
170
- }
171
- // We use the default copy constructor
172
- // We use the default operator=()
173
- // We use the default destructor
174
-
175
- void clear() { rep.clear(); }
176
- void swap(sparse_hash_set& hs) { rep.swap(hs.rep); }
177
-
178
-
179
- // Functions concerning size
180
- size_type size() const { return rep.size(); }
181
- size_type max_size() const { return rep.max_size(); }
182
- bool empty() const { return rep.empty(); }
183
- size_type bucket_count() const { return rep.bucket_count(); }
184
- size_type max_bucket_count() const { return rep.max_bucket_count(); }
185
-
186
- // These are tr1 methods. bucket() is the bucket the key is or would be in.
187
- size_type bucket_size(size_type i) const { return rep.bucket_size(i); }
188
- size_type bucket(const key_type& key) const { return rep.bucket(key); }
189
- float load_factor() const {
190
- return size() * 1.0f / bucket_count();
191
- }
192
- float max_load_factor() const {
193
- float shrink, grow;
194
- rep.get_resizing_parameters(&shrink, &grow);
195
- return grow;
196
- }
197
- void max_load_factor(float new_grow) {
198
- float shrink, grow;
199
- rep.get_resizing_parameters(&shrink, &grow);
200
- rep.set_resizing_parameters(shrink, new_grow);
201
- }
202
- // These aren't tr1 methods but perhaps ought to be.
203
- float min_load_factor() const {
204
- float shrink, grow;
205
- rep.get_resizing_parameters(&shrink, &grow);
206
- return shrink;
207
- }
208
- void min_load_factor(float new_shrink) {
209
- float shrink, grow;
210
- rep.get_resizing_parameters(&shrink, &grow);
211
- rep.set_resizing_parameters(new_shrink, grow);
212
- }
213
- // Deprecated; use min_load_factor() or max_load_factor() instead.
214
- void set_resizing_parameters(float shrink, float grow) {
215
- return rep.set_resizing_parameters(shrink, grow);
216
- }
217
-
218
- void resize(size_type hint) { rep.resize(hint); }
219
- void rehash(size_type hint) { resize(hint); } // the tr1 name
220
-
221
- // Lookup routines
222
- iterator find(const key_type& key) const { return rep.find(key); }
223
-
224
- size_type count(const key_type& key) const { return rep.count(key); }
225
-
226
- pair<iterator, iterator> equal_range(const key_type& key) const {
227
- return rep.equal_range(key);
228
- }
229
-
230
- // Insertion routines
231
- pair<iterator, bool> insert(const value_type& obj) {
232
- pair<typename ht::iterator, bool> p = rep.insert(obj);
233
- return pair<iterator, bool>(p.first, p.second); // const to non-const
234
- }
235
- template <class InputIterator>
236
- void insert(InputIterator f, InputIterator l) { rep.insert(f, l); }
237
- void insert(const_iterator f, const_iterator l) { rep.insert(f, l); }
238
- // required for std::insert_iterator; the passed-in iterator is ignored
239
- iterator insert(iterator, const value_type& obj) { return insert(obj).first; }
240
-
241
-
242
- // Deletion routines
243
- // THESE ARE NON-STANDARD! I make you specify an "impossible" key
244
- // value to identify deleted buckets. You can change the key as
245
- // time goes on, or get rid of it entirely to be insert-only.
246
- void set_deleted_key(const key_type& key) { rep.set_deleted_key(key); }
247
- void clear_deleted_key() { rep.clear_deleted_key(); }
248
-
249
- // These are standard
250
- size_type erase(const key_type& key) { return rep.erase(key); }
251
- void erase(iterator it) { rep.erase(it); }
252
- void erase(iterator f, iterator l) { rep.erase(f, l); }
253
-
254
-
255
- // Comparison
256
- bool operator==(const sparse_hash_set& hs) const { return rep == hs.rep; }
257
- bool operator!=(const sparse_hash_set& hs) const { return rep != hs.rep; }
258
-
259
-
260
- // I/O -- this is an add-on for writing metainformation to disk
261
- bool write_metadata(FILE *fp) { return rep.write_metadata(fp); }
262
- bool read_metadata(FILE *fp) { return rep.read_metadata(fp); }
263
- bool write_nopointer_data(FILE *fp) { return rep.write_nopointer_data(fp); }
264
- bool read_nopointer_data(FILE *fp) { return rep.read_nopointer_data(fp); }
265
- };
266
-
267
- template <class Val, class HashFcn, class EqualKey, class Alloc>
268
- inline void swap(sparse_hash_set<Val, HashFcn, EqualKey, Alloc>& hs1,
269
- sparse_hash_set<Val, HashFcn, EqualKey, Alloc>& hs2) {
270
- hs1.swap(hs2);
271
- }
272
-
273
- _END_GOOGLE_NAMESPACE_
274
-
275
- #endif /* _SPARSE_HASH_SET_H_ */
@@ -1,1062 +0,0 @@
1
- // Copyright (c) 2005, Google Inc.
2
- // All rights reserved.
3
- //
4
- // Redistribution and use in source and binary forms, with or without
5
- // modification, are permitted provided that the following conditions are
6
- // met:
7
- //
8
- // * Redistributions of source code must retain the above copyright
9
- // notice, this list of conditions and the following disclaimer.
10
- // * Redistributions in binary form must reproduce the above
11
- // copyright notice, this list of conditions and the following disclaimer
12
- // in the documentation and/or other materials provided with the
13
- // distribution.
14
- // * Neither the name of Google Inc. nor the names of its
15
- // contributors may be used to endorse or promote products derived from
16
- // this software without specific prior written permission.
17
- //
18
- // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19
- // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20
- // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21
- // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22
- // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23
- // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24
- // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25
- // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26
- // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27
- // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28
- // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
-
30
- // ---
31
- // Author: Craig Silverstein
32
- //
33
- // A dense hashtable is a particular implementation of
34
- // a hashtable: one that is meant to minimize memory allocation.
35
- // It does this by using an array to store all the data. We
36
- // steal a value from the key space to indicate "empty" array
37
- // elements (ie indices where no item lives) and another to indicate
38
- // "deleted" elements.
39
- //
40
- // (Note it is possible to change the value of the delete key
41
- // on the fly; you can even remove it, though after that point
42
- // the hashtable is insert_only until you set it again. The empty
43
- // value however can't be changed.)
44
- //
45
- // To minimize allocation and pointer overhead, we use internal
46
- // probing, in which the hashtable is a single table, and collisions
47
- // are resolved by trying to insert again in another bucket. The
48
- // most cache-efficient internal probing schemes are linear probing
49
- // (which suffers, alas, from clumping) and quadratic probing, which
50
- // is what we implement by default.
51
- //
52
- // Type requirements: value_type is required to be Copy Constructible
53
- // and Default Constructible. It is not required to be (and commonly
54
- // isn't) Assignable.
55
- //
56
- // You probably shouldn't use this code directly. Use
57
- // <google/dense_hash_map> or <google/dense_hash_set> instead.
58
-
59
- // You can change the following below:
60
- // HT_OCCUPANCY_FLT -- how full before we double size
61
- // HT_EMPTY_FLT -- how empty before we halve size
62
- // HT_MIN_BUCKETS -- default smallest bucket size
63
- //
64
- // You can also change enlarge_resize_percent (which defaults to
65
- // HT_OCCUPANCY_FLT), and shrink_resize_percent (which defaults to
66
- // HT_EMPTY_FLT) with set_resizing_parameters().
67
- //
68
- // How to decide what values to use?
69
- // shrink_resize_percent's default of .4 * OCCUPANCY_FLT, is probably good.
70
- // HT_MIN_BUCKETS is probably unnecessary since you can specify
71
- // (indirectly) the starting number of buckets at construct-time.
72
- // For enlarge_resize_percent, you can use this chart to try to trade-off
73
- // expected lookup time to the space taken up. By default, this
74
- // code uses quadratic probing, though you can change it to linear
75
- // via _JUMP below if you really want to.
76
- //
77
- // From http://www.augustana.ca/~mohrj/courses/1999.fall/csc210/lecture_notes/hashing.html
78
- // NUMBER OF PROBES / LOOKUP Successful Unsuccessful
79
- // Quadratic collision resolution 1 - ln(1-L) - L/2 1/(1-L) - L - ln(1-L)
80
- // Linear collision resolution [1+1/(1-L)]/2 [1+1/(1-L)2]/2
81
- //
82
- // -- enlarge_resize_percent -- 0.10 0.50 0.60 0.75 0.80 0.90 0.99
83
- // QUADRATIC COLLISION RES.
84
- // probes/successful lookup 1.05 1.44 1.62 2.01 2.21 2.85 5.11
85
- // probes/unsuccessful lookup 1.11 2.19 2.82 4.64 5.81 11.4 103.6
86
- // LINEAR COLLISION RES.
87
- // probes/successful lookup 1.06 1.5 1.75 2.5 3.0 5.5 50.5
88
- // probes/unsuccessful lookup 1.12 2.5 3.6 8.5 13.0 50.0 5000.0
89
-
90
- #ifndef _DENSEHASHTABLE_H_
91
- #define _DENSEHASHTABLE_H_
92
-
93
- // The probing method
94
- // Linear probing
95
- // #define JUMP_(key, num_probes) ( 1 )
96
- // Quadratic-ish probing
97
- #define JUMP_(key, num_probes) ( num_probes )
98
-
99
-
100
- #include <google/sparsehash/sparseconfig.h>
101
- #include <assert.h>
102
- #include <stdio.h>
103
- #include <stdlib.h> // for abort()
104
- #include <algorithm> // For swap(), eg
105
- #include <iostream> // For cerr
106
- #include <memory> // For uninitialized_fill, uninitialized_copy
107
- #include <utility> // for pair<>
108
- #include <iterator> // for facts about iterator tags
109
- #include <google/type_traits.h> // for true_type, integral_constant, etc.
110
-
111
- _START_GOOGLE_NAMESPACE_
112
-
113
- using STL_NAMESPACE::pair;
114
-
115
- // Hashtable class, used to implement the hashed associative containers
116
- // hash_set and hash_map.
117
-
118
- // Value: what is stored in the table (each bucket is a Value).
119
- // Key: something in a 1-to-1 correspondence to a Value, that can be used
120
- // to search for a Value in the table (find() takes a Key).
121
- // HashFcn: Takes a Key and returns an integer, the more unique the better.
122
- // ExtractKey: given a Value, returns the unique Key associated with it.
123
- // SetKey: given a Value* and a Key, modifies the value such that
124
- // ExtractKey(value) == key. We guarantee this is only called
125
- // with key == deleted_key or key == empty_key.
126
- // EqualKey: Given two Keys, says whether they are the same (that is,
127
- // if they are both associated with the same Value).
128
- // Alloc: STL allocator to use to allocate memory. Currently ignored.
129
-
130
- template <class Value, class Key, class HashFcn,
131
- class ExtractKey, class SetKey, class EqualKey, class Alloc>
132
- class dense_hashtable;
133
-
134
- template <class V, class K, class HF, class ExK, class SetK, class EqK, class A>
135
- struct dense_hashtable_iterator;
136
-
137
- template <class V, class K, class HF, class ExK, class SetK, class EqK, class A>
138
- struct dense_hashtable_const_iterator;
139
-
140
- // We're just an array, but we need to skip over empty and deleted elements
141
- template <class V, class K, class HF, class ExK, class SetK, class EqK, class A>
142
- struct dense_hashtable_iterator {
143
- public:
144
- typedef dense_hashtable_iterator<V,K,HF,ExK,SetK,EqK,A> iterator;
145
- typedef dense_hashtable_const_iterator<V,K,HF,ExK,SetK,EqK,A> const_iterator;
146
-
147
- typedef STL_NAMESPACE::forward_iterator_tag iterator_category;
148
- typedef V value_type;
149
- typedef ptrdiff_t difference_type;
150
- typedef size_t size_type;
151
- typedef V& reference; // Value
152
- typedef V* pointer;
153
-
154
- // "Real" constructor and default constructor
155
- dense_hashtable_iterator(const dense_hashtable<V,K,HF,ExK,SetK,EqK,A> *h,
156
- pointer it, pointer it_end, bool advance)
157
- : ht(h), pos(it), end(it_end) {
158
- if (advance) advance_past_empty_and_deleted();
159
- }
160
- dense_hashtable_iterator() { }
161
- // The default destructor is fine; we don't define one
162
- // The default operator= is fine; we don't define one
163
-
164
- // Happy dereferencer
165
- reference operator*() const { return *pos; }
166
- pointer operator->() const { return &(operator*()); }
167
-
168
- // Arithmetic. The only hard part is making sure that
169
- // we're not on an empty or marked-deleted array element
170
- void advance_past_empty_and_deleted() {
171
- while ( pos != end && (ht->test_empty(*this) || ht->test_deleted(*this)) )
172
- ++pos;
173
- }
174
- iterator& operator++() {
175
- assert(pos != end); ++pos; advance_past_empty_and_deleted(); return *this;
176
- }
177
- iterator operator++(int) { iterator tmp(*this); ++*this; return tmp; }
178
-
179
- // Comparison.
180
- bool operator==(const iterator& it) const { return pos == it.pos; }
181
- bool operator!=(const iterator& it) const { return pos != it.pos; }
182
-
183
-
184
- // The actual data
185
- const dense_hashtable<V,K,HF,ExK,SetK,EqK,A> *ht;
186
- pointer pos, end;
187
- };
188
-
189
-
190
- // Now do it all again, but with const-ness!
191
- template <class V, class K, class HF, class ExK, class SetK, class EqK, class A>
192
- struct dense_hashtable_const_iterator {
193
- public:
194
- typedef dense_hashtable_iterator<V,K,HF,ExK,SetK,EqK,A> iterator;
195
- typedef dense_hashtable_const_iterator<V,K,HF,ExK,SetK,EqK,A> const_iterator;
196
-
197
- typedef STL_NAMESPACE::forward_iterator_tag iterator_category;
198
- typedef V value_type;
199
- typedef ptrdiff_t difference_type;
200
- typedef size_t size_type;
201
- typedef const V& reference; // Value
202
- typedef const V* pointer;
203
-
204
- // "Real" constructor and default constructor
205
- dense_hashtable_const_iterator(
206
- const dense_hashtable<V,K,HF,ExK,SetK,EqK,A> *h,
207
- pointer it, pointer it_end, bool advance)
208
- : ht(h), pos(it), end(it_end) {
209
- if (advance) advance_past_empty_and_deleted();
210
- }
211
- dense_hashtable_const_iterator() { }
212
- // This lets us convert regular iterators to const iterators
213
- dense_hashtable_const_iterator(const iterator &it)
214
- : ht(it.ht), pos(it.pos), end(it.end) { }
215
- // The default destructor is fine; we don't define one
216
- // The default operator= is fine; we don't define one
217
-
218
- // Happy dereferencer
219
- reference operator*() const { return *pos; }
220
- pointer operator->() const { return &(operator*()); }
221
-
222
- // Arithmetic. The only hard part is making sure that
223
- // we're not on an empty or marked-deleted array element
224
- void advance_past_empty_and_deleted() {
225
- while ( pos != end && (ht->test_empty(*this) || ht->test_deleted(*this)) )
226
- ++pos;
227
- }
228
- const_iterator& operator++() {
229
- assert(pos != end); ++pos; advance_past_empty_and_deleted(); return *this;
230
- }
231
- const_iterator operator++(int) { const_iterator tmp(*this); ++*this; return tmp; }
232
-
233
- // Comparison.
234
- bool operator==(const const_iterator& it) const { return pos == it.pos; }
235
- bool operator!=(const const_iterator& it) const { return pos != it.pos; }
236
-
237
-
238
- // The actual data
239
- const dense_hashtable<V,K,HF,ExK,SetK,EqK,A> *ht;
240
- pointer pos, end;
241
- };
242
-
243
- template <class Value, class Key, class HashFcn,
244
- class ExtractKey, class SetKey, class EqualKey, class Alloc>
245
- class dense_hashtable {
246
- public:
247
- typedef Key key_type;
248
- typedef Value value_type;
249
- typedef HashFcn hasher;
250
- typedef EqualKey key_equal;
251
-
252
- typedef size_t size_type;
253
- typedef ptrdiff_t difference_type;
254
- typedef value_type* pointer;
255
- typedef const value_type* const_pointer;
256
- typedef value_type& reference;
257
- typedef const value_type& const_reference;
258
- typedef dense_hashtable_iterator<Value, Key, HashFcn,
259
- ExtractKey, SetKey, EqualKey, Alloc>
260
- iterator;
261
-
262
- typedef dense_hashtable_const_iterator<Value, Key, HashFcn,
263
- ExtractKey, SetKey, EqualKey, Alloc>
264
- const_iterator;
265
-
266
- // These come from tr1. For us they're the same as regular iterators.
267
- typedef iterator local_iterator;
268
- typedef const_iterator const_local_iterator;
269
-
270
- // How full we let the table get before we resize, by default.
271
- // Knuth says .8 is good -- higher causes us to probe too much,
272
- // though it saves memory.
273
- static const float HT_OCCUPANCY_FLT; // = 0.5;
274
-
275
- // How empty we let the table get before we resize lower, by default.
276
- // (0.0 means never resize lower.)
277
- // It should be less than OCCUPANCY_FLT / 2 or we thrash resizing
278
- static const float HT_EMPTY_FLT; // = 0.4 * HT_OCCUPANCY_FLT
279
-
280
- // Minimum size we're willing to let hashtables be.
281
- // Must be a power of two, and at least 4.
282
- // Note, however, that for a given hashtable, the initial size is a
283
- // function of the first constructor arg, and may be >HT_MIN_BUCKETS.
284
- static const size_t HT_MIN_BUCKETS = 4;
285
-
286
- // By default, if you don't specify a hashtable size at
287
- // construction-time, we use this size. Must be a power of two, and
288
- // at least HT_MIN_BUCKETS.
289
- static const size_t HT_DEFAULT_STARTING_BUCKETS = 32;
290
-
291
-
292
- // ITERATOR FUNCTIONS
293
- iterator begin() { return iterator(this, table,
294
- table + num_buckets, true); }
295
- iterator end() { return iterator(this, table + num_buckets,
296
- table + num_buckets, true); }
297
- const_iterator begin() const { return const_iterator(this, table,
298
- table+num_buckets,true);}
299
- const_iterator end() const { return const_iterator(this, table + num_buckets,
300
- table+num_buckets,true);}
301
-
302
- // These come from tr1 unordered_map. They iterate over 'bucket' n.
303
- // For sparsehashtable, we could consider each 'group' to be a bucket,
304
- // I guess, but I don't really see the point. We'll just consider
305
- // bucket n to be the n-th element of the sparsetable, if it's occupied,
306
- // or some empty element, otherwise.
307
- local_iterator begin(size_type i) {
308
- return local_iterator(this, table + i, table + i+1, false);
309
- }
310
- local_iterator end(size_type i) {
311
- local_iterator it = begin(i);
312
- if (!test_empty(i) && !test_deleted(i))
313
- ++it;
314
- return it;
315
- }
316
- const_local_iterator begin(size_type i) const {
317
- return const_local_iterator(this, table + i, table + i+1, false);
318
- }
319
- const_local_iterator end(size_type i) const {
320
- const_local_iterator it = begin(i);
321
- if (!test_empty(i) && !test_deleted(i))
322
- ++it;
323
- return it;
324
- }
325
-
326
- // ACCESSOR FUNCTIONS for the things we templatize on, basically
327
- hasher hash_funct() const { return hash; }
328
- key_equal key_eq() const { return equals; }
329
-
330
- private:
331
- // Annoyingly, we can't copy values around, because they might have
332
- // const components (they're probably pair<const X, Y>). We use
333
- // explicit destructor invocation and placement new to get around
334
- // this. Arg.
335
- void set_value(value_type* dst, const value_type& src) {
336
- dst->~value_type();
337
- new(dst) value_type(src);
338
- }
339
-
340
- void destroy_buckets(size_type first, size_type last) {
341
- for ( ; first != last; ++first)
342
- table[first].~value_type();
343
- }
344
-
345
- // DELETE HELPER FUNCTIONS
346
- // This lets the user describe a key that will indicate deleted
347
- // table entries. This key should be an "impossible" entry --
348
- // if you try to insert it for real, you won't be able to retrieve it!
349
- // (NB: while you pass in an entire value, only the key part is looked
350
- // at. This is just because I don't know how to assign just a key.)
351
- private:
352
- void squash_deleted() { // gets rid of any deleted entries we have
353
- if ( num_deleted ) { // get rid of deleted before writing
354
- dense_hashtable tmp(*this); // copying will get rid of deleted
355
- swap(tmp); // now we are tmp
356
- }
357
- assert(num_deleted == 0);
358
- }
359
-
360
- public:
361
- void set_deleted_key(const key_type &key) {
362
- // the empty indicator (if specified) and the deleted indicator
363
- // must be different
364
- assert(!use_empty || !equals(key, get_key(emptyval)));
365
- // It's only safe to change what "deleted" means if we purge deleted guys
366
- squash_deleted();
367
- use_deleted = true;
368
- delkey = key;
369
- }
370
- void clear_deleted_key() {
371
- squash_deleted();
372
- use_deleted = false;
373
- }
374
-
375
- // These are public so the iterators can use them
376
- // True if the item at position bucknum is "deleted" marker
377
- bool test_deleted(size_type bucknum) const {
378
- // The num_deleted test is crucial for read(): after read(), the ht values
379
- // are garbage, and we don't want to think some of them are deleted.
380
- return (use_deleted && num_deleted > 0 &&
381
- equals(delkey, get_key(table[bucknum])));
382
- }
383
- bool test_deleted(const iterator &it) const {
384
- return (use_deleted && num_deleted > 0 &&
385
- equals(delkey, get_key(*it)));
386
- }
387
- bool test_deleted(const const_iterator &it) const {
388
- return (use_deleted && num_deleted > 0 &&
389
- equals(delkey, get_key(*it)));
390
- }
391
- // Set it so test_deleted is true. true if object didn't used to be deleted
392
- // See below (at erase()) to explain why we allow const_iterators
393
- bool set_deleted(const_iterator &it) {
394
- assert(use_deleted); // bad if set_deleted_key() wasn't called
395
- bool retval = !test_deleted(it);
396
- // &* converts from iterator to value-type
397
- set_key(const_cast<value_type*>(&(*it)), delkey);
398
- return retval;
399
- }
400
- // Set it so test_deleted is false. true if object used to be deleted
401
- bool clear_deleted(const_iterator &it) {
402
- assert(use_deleted); // bad if set_deleted_key() wasn't called
403
- // happens automatically when we assign something else in its place
404
- return test_deleted(it);
405
- }
406
-
407
- // EMPTY HELPER FUNCTIONS
408
- // This lets the user describe a key that will indicate empty (unused)
409
- // table entries. This key should be an "impossible" entry --
410
- // if you try to insert it for real, you won't be able to retrieve it!
411
- // (NB: while you pass in an entire value, only the key part is looked
412
- // at. This is just because I don't know how to assign just a key.)
413
- public:
414
- // These are public so the iterators can use them
415
- // True if the item at position bucknum is "empty" marker
416
- bool test_empty(size_type bucknum) const {
417
- assert(use_empty); // we always need to know what's empty!
418
- return equals(get_key(emptyval), get_key(table[bucknum]));
419
- }
420
- bool test_empty(const iterator &it) const {
421
- assert(use_empty); // we always need to know what's empty!
422
- return equals(get_key(emptyval), get_key(*it));
423
- }
424
- bool test_empty(const const_iterator &it) const {
425
- assert(use_empty); // we always need to know what's empty!
426
- return equals(get_key(emptyval), get_key(*it));
427
- }
428
-
429
- private:
430
- // You can either set a range empty or an individual element
431
- void set_empty(size_type bucknum) {
432
- assert(use_empty);
433
- set_value(&table[bucknum], emptyval);
434
- }
435
- void fill_range_with_empty(value_type* table_start, value_type* table_end) {
436
- // Like set_empty(range), but doesn't destroy previous contents
437
- STL_NAMESPACE::uninitialized_fill(table_start, table_end, emptyval);
438
- }
439
- void set_empty(size_type buckstart, size_type buckend) {
440
- assert(use_empty);
441
- destroy_buckets(buckstart, buckend);
442
- fill_range_with_empty(table + buckstart, table + buckend);
443
- }
444
-
445
- public:
446
- // TODO(csilvers): change all callers of this to pass in a key instead,
447
- // and take a const key_type instead of const value_type.
448
- void set_empty_key(const value_type &val) {
449
- // Once you set the empty key, you can't change it
450
- assert(!use_empty);
451
- // The deleted indicator (if specified) and the empty indicator
452
- // must be different.
453
- assert(!use_deleted || !equals(get_key(val), delkey));
454
- use_empty = true;
455
- set_value(&emptyval, val);
456
-
457
- assert(!table); // must set before first use
458
- // num_buckets was set in constructor even though table was NULL
459
- table = (value_type *) malloc(num_buckets * sizeof(*table));
460
- assert(table);
461
- fill_range_with_empty(table, table + num_buckets);
462
- }
463
-
464
- // FUNCTIONS CONCERNING SIZE
465
- public:
466
- size_type size() const { return num_elements - num_deleted; }
467
- // Buckets are always a power of 2
468
- size_type max_size() const { return (size_type(-1) >> 1U) + 1; }
469
- bool empty() const { return size() == 0; }
470
- size_type bucket_count() const { return num_buckets; }
471
- size_type max_bucket_count() const { return max_size(); }
472
- size_type nonempty_bucket_count() const { return num_elements; }
473
- // These are tr1 methods. Their idea of 'bucket' doesn't map well to
474
- // what we do. We just say every bucket has 0 or 1 items in it.
475
- size_type bucket_size(size_type i) const {
476
- return begin(i) == end(i) ? 0 : 1;
477
- }
478
-
479
-
480
-
481
- private:
482
- // Because of the above, size_type(-1) is never legal; use it for errors
483
- static const size_type ILLEGAL_BUCKET = size_type(-1);
484
-
485
- private:
486
- // This is the smallest size a hashtable can be without being too crowded
487
- // If you like, you can give a min #buckets as well as a min #elts
488
- size_type min_size(size_type num_elts, size_type min_buckets_wanted) {
489
- size_type sz = HT_MIN_BUCKETS; // min buckets allowed
490
- while ( sz < min_buckets_wanted || num_elts >= sz * enlarge_resize_percent )
491
- sz *= 2;
492
- return sz;
493
- }
494
-
495
- // Used after a string of deletes
496
- void maybe_shrink() {
497
- assert(num_elements >= num_deleted);
498
- assert((bucket_count() & (bucket_count()-1)) == 0); // is a power of two
499
- assert(bucket_count() >= HT_MIN_BUCKETS);
500
-
501
- // If you construct a hashtable with < HT_DEFAULT_STARTING_BUCKETS,
502
- // we'll never shrink until you get relatively big, and we'll never
503
- // shrink below HT_DEFAULT_STARTING_BUCKETS. Otherwise, something
504
- // like "dense_hash_set<int> x; x.insert(4); x.erase(4);" will
505
- // shrink us down to HT_MIN_BUCKETS buckets, which is too small.
506
- if (shrink_threshold > 0 &&
507
- (num_elements-num_deleted) < shrink_threshold &&
508
- bucket_count() > HT_DEFAULT_STARTING_BUCKETS ) {
509
- size_type sz = bucket_count() / 2; // find how much we should shrink
510
- while ( sz > HT_DEFAULT_STARTING_BUCKETS &&
511
- (num_elements - num_deleted) < sz * shrink_resize_percent )
512
- sz /= 2; // stay a power of 2
513
- dense_hashtable tmp(*this, sz); // Do the actual resizing
514
- swap(tmp); // now we are tmp
515
- }
516
- consider_shrink = false; // because we just considered it
517
- }
518
-
519
- // We'll let you resize a hashtable -- though this makes us copy all!
520
- // When you resize, you say, "make it big enough for this many more elements"
521
- void resize_delta(size_type delta) {
522
- if ( consider_shrink ) // see if lots of deletes happened
523
- maybe_shrink();
524
- if ( bucket_count() > HT_MIN_BUCKETS &&
525
- (num_elements + delta) <= enlarge_threshold )
526
- return; // we're ok as we are
527
-
528
- // Sometimes, we need to resize just to get rid of all the
529
- // "deleted" buckets that are clogging up the hashtable. So when
530
- // deciding whether to resize, count the deleted buckets (which
531
- // are currently taking up room). But later, when we decide what
532
- // size to resize to, *don't* count deleted buckets, since they
533
- // get discarded during the resize.
534
- const size_type needed_size = min_size(num_elements + delta, 0);
535
- if ( needed_size > bucket_count() ) { // we don't have enough buckets
536
- const size_type resize_to = min_size(num_elements - num_deleted + delta,
537
- 0);
538
- dense_hashtable tmp(*this, resize_to);
539
- swap(tmp); // now we are tmp
540
- }
541
- }
542
-
543
- // Increase number of buckets, assuming value_type has trivial copy
544
- // constructor and destructor. (Really, we want it to have "trivial
545
- // move", because that's what realloc does. But there's no way to
546
- // capture that using type_traits, so we pretend that move(x, y) is
547
- // equivalent to "x.~T(); new(x) T(y);" which is pretty much
548
- // correct, if a bit conservative.)
549
- void expand_array(size_t resize_to, true_type) {
550
- table = (value_type *) realloc(table, resize_to * sizeof(value_type));
551
- assert(table);
552
- fill_range_with_empty(table + num_buckets, table + resize_to);
553
- }
554
-
555
- // Increase number of buckets, without special assumptions about value_type.
556
- // TODO(austern): make this exception safe. Handle exceptions from
557
- // value_type's copy constructor.
558
- void expand_array(size_t resize_to, false_type) {
559
- value_type* new_table =
560
- (value_type *) malloc(resize_to * sizeof(value_type));
561
- assert(new_table);
562
- STL_NAMESPACE::uninitialized_copy(table, table + num_buckets, new_table);
563
- fill_range_with_empty(new_table + num_buckets, new_table + resize_to);
564
- destroy_buckets(0, num_buckets);
565
- free(table);
566
- table = new_table;
567
- }
568
-
569
- // Used to actually do the rehashing when we grow/shrink a hashtable
570
- void copy_from(const dense_hashtable &ht, size_type min_buckets_wanted) {
571
- clear(); // clear table, set num_deleted to 0
572
-
573
- // If we need to change the size of our table, do it now
574
- const size_type resize_to = min_size(ht.size(), min_buckets_wanted);
575
- if ( resize_to > bucket_count() ) { // we don't have enough buckets
576
- typedef integral_constant<bool,
577
- (has_trivial_copy<value_type>::value &&
578
- has_trivial_destructor<value_type>::value)>
579
- realloc_ok; // we pretend mv(x,y) == "x.~T(); new(x) T(y)"
580
- expand_array(resize_to, realloc_ok());
581
- num_buckets = resize_to;
582
- reset_thresholds();
583
- }
584
-
585
- // We use a normal iterator to get non-deleted bcks from ht
586
- // We could use insert() here, but since we know there are
587
- // no duplicates and no deleted items, we can be more efficient
588
- assert((bucket_count() & (bucket_count()-1)) == 0); // a power of two
589
- for ( const_iterator it = ht.begin(); it != ht.end(); ++it ) {
590
- size_type num_probes = 0; // how many times we've probed
591
- size_type bucknum;
592
- const size_type bucket_count_minus_one = bucket_count() - 1;
593
- for (bucknum = hash(get_key(*it)) & bucket_count_minus_one;
594
- !test_empty(bucknum); // not empty
595
- bucknum = (bucknum + JUMP_(key, num_probes)) & bucket_count_minus_one) {
596
- ++num_probes;
597
- assert(num_probes < bucket_count()); // or else the hashtable is full
598
- }
599
- set_value(&table[bucknum], *it); // copies the value to here
600
- num_elements++;
601
- }
602
- }
603
-
604
- // Required by the spec for hashed associative container
605
- public:
606
- // Though the docs say this should be num_buckets, I think it's much
607
- // more useful as req_elements. As a special feature, calling with
608
- // req_elements==0 will cause us to shrink if we can, saving space.
609
- void resize(size_type req_elements) { // resize to this or larger
610
- if ( consider_shrink || req_elements == 0 )
611
- maybe_shrink();
612
- if ( req_elements > num_elements )
613
- return resize_delta(req_elements - num_elements);
614
- }
615
-
616
- // Get and change the value of shrink_resize_percent and
617
- // enlarge_resize_percent. The description at the beginning of this
618
- // file explains how to choose the values. Setting the shrink
619
- // parameter to 0.0 ensures that the table never shrinks.
620
- void get_resizing_parameters(float* shrink, float* grow) const {
621
- *shrink = shrink_resize_percent;
622
- *grow = enlarge_resize_percent;
623
- }
624
- void set_resizing_parameters(float shrink, float grow) {
625
- assert(shrink >= 0.0);
626
- assert(grow <= 1.0);
627
- if (shrink > grow/2.0f)
628
- shrink = grow / 2.0f; // otherwise we thrash hashtable size
629
- shrink_resize_percent = shrink;
630
- enlarge_resize_percent = grow;
631
- reset_thresholds();
632
- }
633
-
634
- // CONSTRUCTORS -- as required by the specs, we take a size,
635
- // but also let you specify a hashfunction, key comparator,
636
- // and key extractor. We also define a copy constructor and =.
637
- // DESTRUCTOR -- needs to free the table
638
- explicit dense_hashtable(size_type expected_max_items_in_table = 0,
639
- const HashFcn& hf = HashFcn(),
640
- const EqualKey& eql = EqualKey(),
641
- const ExtractKey& ext = ExtractKey(),
642
- const SetKey& set = SetKey())
643
- : hash(hf), equals(eql), get_key(ext), set_key(set), num_deleted(0),
644
- use_deleted(false), use_empty(false),
645
- delkey(), emptyval(), enlarge_resize_percent(HT_OCCUPANCY_FLT),
646
- shrink_resize_percent(HT_EMPTY_FLT), table(NULL),
647
- num_buckets(expected_max_items_in_table == 0
648
- ? HT_DEFAULT_STARTING_BUCKETS
649
- : min_size(expected_max_items_in_table, 0)),
650
- num_elements(0) {
651
- // table is NULL until emptyval is set. However, we set num_buckets
652
- // here so we know how much space to allocate once emptyval is set
653
- reset_thresholds();
654
- }
655
-
656
- // As a convenience for resize(), we allow an optional second argument
657
- // which lets you make this new hashtable a different size than ht
658
- dense_hashtable(const dense_hashtable& ht,
659
- size_type min_buckets_wanted = HT_DEFAULT_STARTING_BUCKETS)
660
- : hash(ht.hash), equals(ht.equals),
661
- get_key(ht.get_key), set_key(ht.set_key), num_deleted(0),
662
- use_deleted(ht.use_deleted), use_empty(ht.use_empty),
663
- delkey(ht.delkey), emptyval(ht.emptyval),
664
- enlarge_resize_percent(ht.enlarge_resize_percent),
665
- shrink_resize_percent(ht.shrink_resize_percent), table(NULL),
666
- num_buckets(0), num_elements(0) {
667
- reset_thresholds();
668
- copy_from(ht, min_buckets_wanted); // copy_from() ignores deleted entries
669
- }
670
-
671
- dense_hashtable& operator= (const dense_hashtable& ht) {
672
- if (&ht == this) return *this; // don't copy onto ourselves
673
- clear();
674
- hash = ht.hash;
675
- equals = ht.equals;
676
- get_key = ht.get_key;
677
- set_key = ht.set_key;
678
- use_deleted = ht.use_deleted;
679
- use_empty = ht.use_empty;
680
- delkey = ht.delkey;
681
- set_value(&emptyval, ht.emptyval);
682
- enlarge_resize_percent = ht.enlarge_resize_percent;
683
- shrink_resize_percent = ht.shrink_resize_percent;
684
- copy_from(ht, HT_MIN_BUCKETS); // sets num_deleted to 0 too
685
- return *this;
686
- }
687
-
688
- ~dense_hashtable() {
689
- if (table) {
690
- destroy_buckets(0, num_buckets);
691
- free(table);
692
- }
693
- }
694
-
695
- // Many STL algorithms use swap instead of copy constructors
696
- void swap(dense_hashtable& ht) {
697
- STL_NAMESPACE::swap(hash, ht.hash);
698
- STL_NAMESPACE::swap(equals, ht.equals);
699
- STL_NAMESPACE::swap(get_key, ht.get_key);
700
- STL_NAMESPACE::swap(set_key, ht.set_key);
701
- STL_NAMESPACE::swap(num_deleted, ht.num_deleted);
702
- STL_NAMESPACE::swap(use_deleted, ht.use_deleted);
703
- STL_NAMESPACE::swap(use_empty, ht.use_empty);
704
- STL_NAMESPACE::swap(enlarge_resize_percent, ht.enlarge_resize_percent);
705
- STL_NAMESPACE::swap(shrink_resize_percent, ht.shrink_resize_percent);
706
- STL_NAMESPACE::swap(delkey, ht.delkey);
707
- { value_type tmp; // for annoying reasons, swap() doesn't work
708
- set_value(&tmp, emptyval);
709
- set_value(&emptyval, ht.emptyval);
710
- set_value(&ht.emptyval, tmp);
711
- }
712
- STL_NAMESPACE::swap(table, ht.table);
713
- STL_NAMESPACE::swap(num_buckets, ht.num_buckets);
714
- STL_NAMESPACE::swap(num_elements, ht.num_elements);
715
- reset_thresholds();
716
- ht.reset_thresholds();
717
- }
718
-
719
- // It's always nice to be able to clear a table without deallocating it
720
- void clear() {
721
- if (table)
722
- destroy_buckets(0, num_buckets);
723
- num_buckets = min_size(0,0); // our new size
724
- reset_thresholds();
725
- table = (value_type *) realloc(table, num_buckets * sizeof(*table));
726
- assert(table);
727
- fill_range_with_empty(table, table + num_buckets);
728
- num_elements = 0;
729
- num_deleted = 0;
730
- }
731
-
732
- // Clear the table without resizing it.
733
- // Mimicks the stl_hashtable's behaviour when clear()-ing in that it
734
- // does not modify the bucket count
735
- void clear_no_resize() {
736
- if (table) {
737
- set_empty(0, num_buckets);
738
- }
739
- // don't consider to shrink before another erase()
740
- reset_thresholds();
741
- num_elements = 0;
742
- num_deleted = 0;
743
- }
744
-
745
- // LOOKUP ROUTINES
746
- private:
747
- // Returns a pair of positions: 1st where the object is, 2nd where
748
- // it would go if you wanted to insert it. 1st is ILLEGAL_BUCKET
749
- // if object is not found; 2nd is ILLEGAL_BUCKET if it is.
750
- // Note: because of deletions where-to-insert is not trivial: it's the
751
- // first deleted bucket we see, as long as we don't find the key later
752
- pair<size_type, size_type> find_position(const key_type &key) const {
753
- size_type num_probes = 0; // how many times we've probed
754
- const size_type bucket_count_minus_one = bucket_count() - 1;
755
- size_type bucknum = hash(key) & bucket_count_minus_one;
756
- size_type insert_pos = ILLEGAL_BUCKET; // where we would insert
757
- while ( 1 ) { // probe until something happens
758
- if ( test_empty(bucknum) ) { // bucket is empty
759
- if ( insert_pos == ILLEGAL_BUCKET ) // found no prior place to insert
760
- return pair<size_type,size_type>(ILLEGAL_BUCKET, bucknum);
761
- else
762
- return pair<size_type,size_type>(ILLEGAL_BUCKET, insert_pos);
763
-
764
- } else if ( test_deleted(bucknum) ) {// keep searching, but mark to insert
765
- if ( insert_pos == ILLEGAL_BUCKET )
766
- insert_pos = bucknum;
767
-
768
- } else if ( equals(key, get_key(table[bucknum])) ) {
769
- return pair<size_type,size_type>(bucknum, ILLEGAL_BUCKET);
770
- }
771
- ++num_probes; // we're doing another probe
772
- bucknum = (bucknum + JUMP_(key, num_probes)) & bucket_count_minus_one;
773
- assert(num_probes < bucket_count()); // don't probe too many times!
774
- }
775
- }
776
-
777
- public:
778
- iterator find(const key_type& key) {
779
- if ( size() == 0 ) return end();
780
- pair<size_type, size_type> pos = find_position(key);
781
- if ( pos.first == ILLEGAL_BUCKET ) // alas, not there
782
- return end();
783
- else
784
- return iterator(this, table + pos.first, table + num_buckets, false);
785
- }
786
-
787
- const_iterator find(const key_type& key) const {
788
- if ( size() == 0 ) return end();
789
- pair<size_type, size_type> pos = find_position(key);
790
- if ( pos.first == ILLEGAL_BUCKET ) // alas, not there
791
- return end();
792
- else
793
- return const_iterator(this, table + pos.first, table+num_buckets, false);
794
- }
795
-
796
- // This is a tr1 method: the bucket a given key is in, or what bucket
797
- // it would be put in, if it were to be inserted. Shrug.
798
- size_type bucket(const key_type& key) const {
799
- pair<size_type, size_type> pos = find_position(key);
800
- return pos.first == ILLEGAL_BUCKET ? pos.second : pos.first;
801
- }
802
-
803
- // Counts how many elements have key key. For maps, it's either 0 or 1.
804
- size_type count(const key_type &key) const {
805
- pair<size_type, size_type> pos = find_position(key);
806
- return pos.first == ILLEGAL_BUCKET ? 0 : 1;
807
- }
808
-
809
- // Likewise, equal_range doesn't really make sense for us. Oh well.
810
- pair<iterator,iterator> equal_range(const key_type& key) {
811
- iterator pos = find(key); // either an iterator or end
812
- if (pos == end()) {
813
- return pair<iterator,iterator>(pos, pos);
814
- } else {
815
- const iterator startpos = pos++;
816
- return pair<iterator,iterator>(startpos, pos);
817
- }
818
- }
819
- pair<const_iterator,const_iterator> equal_range(const key_type& key) const {
820
- const_iterator pos = find(key); // either an iterator or end
821
- if (pos == end()) {
822
- return pair<const_iterator,const_iterator>(pos, pos);
823
- } else {
824
- const const_iterator startpos = pos++;
825
- return pair<const_iterator,const_iterator>(startpos, pos);
826
- }
827
- }
828
-
829
-
830
- // INSERTION ROUTINES
831
- private:
832
- // If you know *this is big enough to hold obj, use this routine
833
- pair<iterator, bool> insert_noresize(const value_type& obj) {
834
- // First, double-check we're not inserting delkey or emptyval
835
- assert(!use_empty || !equals(get_key(obj), get_key(emptyval)));
836
- assert(!use_deleted || !equals(get_key(obj), delkey));
837
- const pair<size_type,size_type> pos = find_position(get_key(obj));
838
- if ( pos.first != ILLEGAL_BUCKET) { // object was already there
839
- return pair<iterator,bool>(iterator(this, table + pos.first,
840
- table + num_buckets, false),
841
- false); // false: we didn't insert
842
- } else { // pos.second says where to put it
843
- if ( test_deleted(pos.second) ) { // just replace if it's been del.
844
- const_iterator delpos(this, table + pos.second, // shrug:
845
- table + num_buckets, false);// shouldn't need const
846
- clear_deleted(delpos);
847
- assert( num_deleted > 0);
848
- --num_deleted; // used to be, now it isn't
849
- } else {
850
- ++num_elements; // replacing an empty bucket
851
- }
852
- set_value(&table[pos.second], obj);
853
- return pair<iterator,bool>(iterator(this, table + pos.second,
854
- table + num_buckets, false),
855
- true); // true: we did insert
856
- }
857
- }
858
-
859
- public:
860
- // This is the normal insert routine, used by the outside world
861
- pair<iterator, bool> insert(const value_type& obj) {
862
- resize_delta(1); // adding an object, grow if need be
863
- return insert_noresize(obj);
864
- }
865
-
866
- // When inserting a lot at a time, we specialize on the type of iterator
867
- template <class InputIterator>
868
- void insert(InputIterator f, InputIterator l) {
869
- // specializes on iterator type
870
- insert(f, l, typename STL_NAMESPACE::iterator_traits<InputIterator>::iterator_category());
871
- }
872
-
873
- // Iterator supports operator-, resize before inserting
874
- template <class ForwardIterator>
875
- void insert(ForwardIterator f, ForwardIterator l,
876
- STL_NAMESPACE::forward_iterator_tag) {
877
- size_type n = STL_NAMESPACE::distance(f, l); // TODO(csilvers): standard?
878
- resize_delta(n);
879
- for ( ; n > 0; --n, ++f)
880
- insert_noresize(*f);
881
- }
882
-
883
- // Arbitrary iterator, can't tell how much to resize
884
- template <class InputIterator>
885
- void insert(InputIterator f, InputIterator l,
886
- STL_NAMESPACE::input_iterator_tag) {
887
- for ( ; f != l; ++f)
888
- insert(*f);
889
- }
890
-
891
-
892
- // DELETION ROUTINES
893
- size_type erase(const key_type& key) {
894
- // First, double-check we're not trying to erase delkey or emptyval
895
- assert(!use_empty || !equals(key, get_key(emptyval)));
896
- assert(!use_deleted || !equals(key, delkey));
897
- const_iterator pos = find(key); // shrug: shouldn't need to be const
898
- if ( pos != end() ) {
899
- assert(!test_deleted(pos)); // or find() shouldn't have returned it
900
- set_deleted(pos);
901
- ++num_deleted;
902
- consider_shrink = true; // will think about shrink after next insert
903
- return 1; // because we deleted one thing
904
- } else {
905
- return 0; // because we deleted nothing
906
- }
907
- }
908
-
909
- // This is really evil: really it should be iterator, not const_iterator.
910
- // But...the only reason keys are const is to allow lookup.
911
- // Since that's a moot issue for deleted keys, we allow const_iterators
912
- void erase(const_iterator pos) {
913
- if ( pos == end() ) return; // sanity check
914
- if ( set_deleted(pos) ) { // true if object has been newly deleted
915
- ++num_deleted;
916
- consider_shrink = true; // will think about shrink after next insert
917
- }
918
- }
919
-
920
- void erase(const_iterator f, const_iterator l) {
921
- for ( ; f != l; ++f) {
922
- if ( set_deleted(f) ) // should always be true
923
- ++num_deleted;
924
- }
925
- consider_shrink = true; // will think about shrink after next insert
926
- }
927
-
928
-
929
- // COMPARISON
930
- bool operator==(const dense_hashtable& ht) const {
931
- if (size() != ht.size()) {
932
- return false;
933
- } else if (this == &ht) {
934
- return true;
935
- } else {
936
- // Iterate through the elements in "this" and see if the
937
- // corresponding element is in ht
938
- for ( const_iterator it = begin(); it != end(); ++it ) {
939
- const_iterator it2 = ht.find(get_key(*it));
940
- if ((it2 == ht.end()) || (*it != *it2)) {
941
- return false;
942
- }
943
- }
944
- return true;
945
- }
946
- }
947
- bool operator!=(const dense_hashtable& ht) const {
948
- return !(*this == ht);
949
- }
950
-
951
-
952
- // I/O
953
- // We support reading and writing hashtables to disk. Alas, since
954
- // I don't know how to write a hasher or key_equal, you have to make
955
- // sure everything but the table is the same. We compact before writing
956
- //
957
- // NOTE: These functions are currently TODO. They've not been implemented.
958
- bool write_metadata(FILE *fp) {
959
- squash_deleted(); // so we don't have to worry about delkey
960
- return false; // TODO
961
- }
962
-
963
- bool read_metadata(FILE *fp) {
964
- num_deleted = 0; // since we got rid before writing
965
- assert(use_empty); // have to set this before calling us
966
- if (table) free(table); // we'll make our own
967
- // TODO: read magic number
968
- // TODO: read num_buckets
969
- reset_thresholds();
970
- table = (value_type *) malloc(num_buckets * sizeof(*table));
971
- assert(table);
972
- fill_range_with_empty(table, table + num_buckets);
973
- // TODO: read num_elements
974
- for ( size_type i = 0; i < num_elements; ++i ) {
975
- // TODO: read bucket_num
976
- // TODO: set with non-empty, non-deleted value
977
- }
978
- return false; // TODO
979
- }
980
-
981
- // If your keys and values are simple enough, we can write them to
982
- // disk for you. "simple enough" means value_type is a POD type
983
- // that contains no pointers. However, we don't try to normalize
984
- // endianness
985
- bool write_nopointer_data(FILE *fp) const {
986
- for ( const_iterator it = begin(); it != end(); ++it ) {
987
- // TODO: skip empty/deleted values
988
- if ( !fwrite(&*it, sizeof(*it), 1, fp) ) return false;
989
- }
990
- return false;
991
- }
992
-
993
- // When reading, we have to override the potential const-ness of *it
994
- bool read_nopointer_data(FILE *fp) {
995
- for ( iterator it = begin(); it != end(); ++it ) {
996
- // TODO: skip empty/deleted values
997
- if ( !fread(reinterpret_cast<void*>(&(*it)), sizeof(*it), 1, fp) )
998
- return false;
999
- }
1000
- return false;
1001
- }
1002
-
1003
- private:
1004
- // The actual data
1005
- hasher hash; // required by hashed_associative_container
1006
- key_equal equals;
1007
- ExtractKey get_key;
1008
- SetKey set_key;
1009
- size_type num_deleted; // how many occupied buckets are marked deleted
1010
- bool use_deleted; // false until delkey has been set
1011
- bool use_empty; // you must do this before you start
1012
- // TODO(csilvers): make a pointer, and get rid of use_deleted (benchmark!)
1013
- key_type delkey; // which key marks deleted entries
1014
- value_type emptyval; // which key marks unused entries
1015
- float enlarge_resize_percent; // how full before resize
1016
- float shrink_resize_percent; // how empty before resize
1017
- size_type shrink_threshold; // num_buckets * shrink_resize_percent
1018
- size_type enlarge_threshold; // num_buckets * enlarge_resize_percent
1019
- value_type *table;
1020
- size_type num_buckets;
1021
- size_type num_elements;
1022
- bool consider_shrink; // true if we should try to shrink before next insert
1023
-
1024
- void reset_thresholds() {
1025
- enlarge_threshold = static_cast<size_type>(num_buckets
1026
- * enlarge_resize_percent);
1027
- shrink_threshold = static_cast<size_type>(num_buckets
1028
- * shrink_resize_percent);
1029
- consider_shrink = false; // whatever caused us to reset already considered
1030
- }
1031
- };
1032
-
1033
- // We need a global swap as well
1034
- template <class V, class K, class HF, class ExK, class SetK, class EqK, class A>
1035
- inline void swap(dense_hashtable<V,K,HF,ExK,SetK,EqK,A> &x,
1036
- dense_hashtable<V,K,HF,ExK,SetK,EqK,A> &y) {
1037
- x.swap(y);
1038
- }
1039
-
1040
- #undef JUMP_
1041
-
1042
- template <class V, class K, class HF, class ExK, class SetK, class EqK, class A>
1043
- const typename dense_hashtable<V,K,HF,ExK,SetK,EqK,A>::size_type
1044
- dense_hashtable<V,K,HF,ExK,SetK,EqK,A>::ILLEGAL_BUCKET;
1045
-
1046
- // How full we let the table get before we resize. Knuth says .8 is
1047
- // good -- higher causes us to probe too much, though saves memory.
1048
- // However, we go with .5, getting better performance at the cost of
1049
- // more space (a trade-off densehashtable explicitly chooses to make).
1050
- // Feel free to play around with different values, though.
1051
- template <class V, class K, class HF, class ExK, class SetK, class EqK, class A>
1052
- const float dense_hashtable<V,K,HF,ExK,SetK,EqK,A>::HT_OCCUPANCY_FLT = 0.5f;
1053
-
1054
- // How empty we let the table get before we resize lower.
1055
- // It should be less than OCCUPANCY_FLT / 2 or we thrash resizing
1056
- template <class V, class K, class HF, class ExK, class SetK, class EqK, class A>
1057
- const float dense_hashtable<V,K,HF,ExK,SetK,EqK,A>::HT_EMPTY_FLT
1058
- = 0.4f * dense_hashtable<V,K,HF,ExK,SetK,EqK,A>::HT_OCCUPANCY_FLT;
1059
-
1060
- _END_GOOGLE_NAMESPACE_
1061
-
1062
- #endif /* _DENSEHASHTABLE_H_ */