passenger 2.2.15 → 3.0.0.pre1
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.
- data/DEVELOPERS.TXT +21 -12
- data/LICENSE +1 -1
- data/NEWS +8 -1
- data/PACKAGING.TXT +25 -0
- data/Rakefile +28 -891
- data/bin/passenger +32 -0
- data/bin/passenger-config +5 -5
- data/bin/passenger-install-apache2-module +37 -24
- data/bin/passenger-install-nginx-module +48 -46
- data/bin/passenger-make-enterprisey +8 -9
- data/bin/passenger-memory-stats +20 -150
- data/bin/passenger-status +130 -44
- data/bin/passenger-stress-test +5 -4
- data/build/agents.rb +73 -0
- data/build/apache2.rb +165 -0
- data/build/basics.rb +81 -0
- data/build/common_library.rb +198 -0
- data/build/config.rb +35 -0
- data/{misc/rake/cplusplus.rb → build/cplusplus_support.rb} +1 -1
- data/build/cxx_tests.rb +205 -0
- data/build/documentation.rb +77 -0
- data/{misc/rake → build}/gempackagetask.rb +1 -1
- data/build/integration_tests.rb +57 -0
- data/build/misc.rb +146 -0
- data/build/nginx.rb +64 -0
- data/build/oxt_tests.rb +52 -0
- data/{misc/rake → build}/packagetask.rb +0 -0
- data/build/packaging.rb +189 -0
- data/{misc/rake/extensions.rb → build/rake_extensions.rb} +1 -1
- data/{misc/rake → build}/rdoctask.rb +0 -0
- data/build/ruby_extension.rb +46 -0
- data/build/ruby_tests.rb +42 -0
- data/build/test_basics.rb +31 -0
- data/doc/ApplicationPool algorithm.txt +447 -234
- data/doc/Architectural overview.html +47 -56
- data/doc/Doxyfile +1 -1
- data/doc/Security of user switching support.html +46 -57
- data/doc/Users guide Apache.html +1033 -306
- data/doc/Users guide Apache.txt +419 -99
- data/doc/Users guide Nginx.html +1252 -253
- data/doc/Users guide Nginx.txt +711 -87
- data/doc/Users guide Standalone.html +603 -0
- data/doc/Users guide Standalone.txt +40 -0
- data/doc/cxxapi/AbstractSpawnManager_8h_source.html +141 -0
- data/doc/cxxapi/Account_8h_source.html +206 -0
- data/doc/cxxapi/AccountsDatabase_8h_source.html +161 -0
- data/doc/cxxapi/AgentBase_8h_source.html +70 -0
- data/doc/cxxapi/AgentsStarter_8h_source.html +112 -0
- data/doc/cxxapi/BCrypt_8h_source.html +104 -0
- data/doc/cxxapi/Blowfish_8h_source.html +134 -0
- data/doc/cxxapi/Bucket_8h_source.html +4 -3
- data/doc/cxxapi/Constants_8h_source.html +79 -0
- data/doc/cxxapi/ContentHandler_8h_source.html +95 -0
- data/doc/cxxapi/DirectoryMapper_8h_source.html +9 -8
- data/doc/cxxapi/EventedClient_8h_source.html +629 -0
- data/doc/cxxapi/EventedMessageServer_8h_source.html +358 -0
- data/doc/cxxapi/EventedServer_8h_source.html +326 -0
- data/doc/cxxapi/Exceptions_8h_source.html +366 -0
- data/doc/cxxapi/FileDescriptor_8h_source.html +260 -0
- data/doc/cxxapi/Hooks_8h_source.html +2 -1
- data/doc/cxxapi/HttpStatusExtractor_8h_source.html +382 -0
- data/doc/cxxapi/Logging_8h_source.html +726 -0
- data/doc/cxxapi/MessageChannel_8h_source.html +852 -0
- data/doc/cxxapi/MessageClient_8h_source.html +328 -0
- data/doc/cxxapi/MessageReadersWriters_8h_source.html +539 -0
- data/doc/cxxapi/MessageServer_8h_source.html +606 -0
- data/doc/cxxapi/PoolOptions_8h_source.html +548 -0
- data/doc/cxxapi/Process_8h_source.html +286 -0
- data/doc/cxxapi/RandomGenerator_8h_source.html +191 -0
- data/doc/cxxapi/ResourceLocator_8h_source.html +115 -0
- data/doc/cxxapi/ScgiRequestParser_8h_source.html +406 -0
- data/doc/cxxapi/ServerInstanceDir_8h_source.html +374 -0
- data/doc/cxxapi/Session_8h_source.html +501 -0
- data/doc/cxxapi/SpawnManager_8h_source.html +647 -0
- data/doc/cxxapi/StaticContentHandler_8h_source.html +68 -0
- data/doc/cxxapi/StaticString_8h_source.html +254 -0
- data/doc/cxxapi/StringListCreator_8h_source.html +114 -0
- data/doc/cxxapi/Utils_8h_source.html +442 -0
- data/doc/cxxapi/annotated.html +46 -0
- data/doc/cxxapi/apache2_2Configuration_8h_source.html +82 -0
- data/doc/cxxapi/classAgentWatcher-members.html +30 -26
- data/doc/cxxapi/classAgentWatcher.html +168 -194
- data/doc/cxxapi/classClient-members.html +14 -11
- data/doc/cxxapi/classClient.html +35 -35
- data/doc/cxxapi/classHooks-members.html +2 -0
- data/doc/cxxapi/classHooks.html +2 -0
- data/doc/cxxapi/classPassenger_1_1AbstractSpawnManager-members.html +16 -13
- data/doc/cxxapi/classPassenger_1_1AbstractSpawnManager.html +78 -82
- data/doc/cxxapi/classPassenger_1_1ArgumentException-members.html +12 -9
- data/doc/cxxapi/classPassenger_1_1ArgumentException.html +26 -22
- data/doc/cxxapi/classPassenger_1_1ArrayMessage-members.html +37 -0
- data/doc/cxxapi/classPassenger_1_1ArrayMessage.html +113 -0
- data/doc/cxxapi/classPassenger_1_1BufferedUpload-members.html +14 -11
- data/doc/cxxapi/classPassenger_1_1BufferedUpload.html +41 -42
- data/doc/cxxapi/classPassenger_1_1BusyException-members.html +12 -9
- data/doc/cxxapi/classPassenger_1_1BusyException.html +24 -20
- data/doc/cxxapi/classPassenger_1_1ConfigurationException-members.html +12 -9
- data/doc/cxxapi/classPassenger_1_1ConfigurationException.html +23 -19
- data/doc/cxxapi/classPassenger_1_1DirectoryMapper-members.html +2 -0
- data/doc/cxxapi/classPassenger_1_1DirectoryMapper.html +8 -6
- data/doc/cxxapi/classPassenger_1_1EOFException-members.html +12 -9
- data/doc/cxxapi/classPassenger_1_1EOFException.html +27 -23
- data/doc/cxxapi/classPassenger_1_1EventFd-members.html +12 -9
- data/doc/cxxapi/classPassenger_1_1EventFd.html +24 -21
- data/doc/cxxapi/classPassenger_1_1EventedClient-members.html +54 -0
- data/doc/cxxapi/classPassenger_1_1EventedClient.html +436 -0
- data/doc/cxxapi/classPassenger_1_1EventedMessageServer-members.html +37 -0
- data/doc/cxxapi/classPassenger_1_1EventedMessageServer.html +59 -0
- data/doc/cxxapi/classPassenger_1_1EventedMessageServer__inherit__graph.map +3 -0
- data/doc/cxxapi/classPassenger_1_1EventedMessageServer__inherit__graph.md5 +1 -0
- data/doc/cxxapi/classPassenger_1_1EventedMessageServer__inherit__graph.png +0 -0
- data/doc/cxxapi/classPassenger_1_1EventedServer-members.html +37 -0
- data/doc/cxxapi/classPassenger_1_1EventedServer.html +93 -0
- data/doc/cxxapi/classPassenger_1_1EventedServer__inherit__graph.map +3 -0
- data/doc/cxxapi/classPassenger_1_1EventedServer__inherit__graph.md5 +1 -0
- data/doc/cxxapi/classPassenger_1_1EventedServer__inherit__graph.png +0 -0
- data/doc/cxxapi/classPassenger_1_1FileDescriptor-members.html +16 -13
- data/doc/cxxapi/classPassenger_1_1FileDescriptor.html +63 -70
- data/doc/cxxapi/classPassenger_1_1FileNotFoundException-members.html +12 -9
- data/doc/cxxapi/classPassenger_1_1FileNotFoundException.html +26 -22
- data/doc/cxxapi/classPassenger_1_1FileSystemException-members.html +17 -14
- data/doc/cxxapi/classPassenger_1_1FileSystemException.html +32 -30
- data/doc/cxxapi/classPassenger_1_1HttpStatusExtractor-members.html +15 -12
- data/doc/cxxapi/classPassenger_1_1HttpStatusExtractor.html +59 -59
- data/doc/cxxapi/classPassenger_1_1IOException-members.html +12 -9
- data/doc/cxxapi/classPassenger_1_1IOException.html +27 -23
- data/doc/cxxapi/classPassenger_1_1MessageChannel-members.html +36 -33
- data/doc/cxxapi/classPassenger_1_1MessageChannel.html +326 -344
- data/doc/cxxapi/classPassenger_1_1MessageServer-members.html +25 -22
- data/doc/cxxapi/classPassenger_1_1MessageServer.html +160 -191
- data/doc/cxxapi/classPassenger_1_1MessageServer_1_1ClientContext-members.html +12 -9
- data/doc/cxxapi/classPassenger_1_1MessageServer_1_1ClientContext.html +29 -27
- data/doc/cxxapi/classPassenger_1_1MessageServer_1_1ClientContext__inherit__graph.map +3 -1
- data/doc/cxxapi/classPassenger_1_1MessageServer_1_1ClientContext__inherit__graph.md5 +1 -1
- data/doc/cxxapi/classPassenger_1_1MessageServer_1_1ClientContext__inherit__graph.png +0 -0
- data/doc/cxxapi/classPassenger_1_1MessageServer_1_1CommonClientContext-members.html +17 -14
- data/doc/cxxapi/classPassenger_1_1MessageServer_1_1CommonClientContext.html +69 -79
- data/doc/cxxapi/classPassenger_1_1MessageServer_1_1CommonClientContext__inherit__graph.map +3 -1
- data/doc/cxxapi/classPassenger_1_1MessageServer_1_1CommonClientContext__inherit__graph.md5 +1 -1
- data/doc/cxxapi/classPassenger_1_1MessageServer_1_1CommonClientContext__inherit__graph.png +0 -0
- data/doc/cxxapi/classPassenger_1_1MessageServer_1_1Handler-members.html +15 -12
- data/doc/cxxapi/classPassenger_1_1MessageServer_1_1Handler.html +60 -63
- data/doc/cxxapi/classPassenger_1_1Process-members.html +20 -17
- data/doc/cxxapi/classPassenger_1_1Process.html +88 -95
- data/doc/cxxapi/classPassenger_1_1RandomGenerator-members.html +13 -10
- data/doc/cxxapi/classPassenger_1_1RandomGenerator.html +36 -35
- data/doc/cxxapi/classPassenger_1_1RuntimeException-members.html +12 -9
- data/doc/cxxapi/classPassenger_1_1RuntimeException.html +24 -20
- data/doc/cxxapi/classPassenger_1_1ScalarMessage-members.html +37 -0
- data/doc/cxxapi/classPassenger_1_1ScalarMessage.html +76 -0
- data/doc/cxxapi/classPassenger_1_1ScgiRequestParser-members.html +26 -23
- data/doc/cxxapi/classPassenger_1_1ScgiRequestParser.html +121 -138
- data/doc/cxxapi/classPassenger_1_1SecurityException-members.html +12 -9
- data/doc/cxxapi/classPassenger_1_1SecurityException.html +26 -22
- data/doc/cxxapi/classPassenger_1_1Session-members.html +29 -26
- data/doc/cxxapi/classPassenger_1_1Session.html +219 -240
- data/doc/cxxapi/classPassenger_1_1SpawnException-members.html +14 -11
- data/doc/cxxapi/classPassenger_1_1SpawnException.html +36 -37
- data/doc/cxxapi/classPassenger_1_1SpawnManager-members.html +18 -15
- data/doc/cxxapi/classPassenger_1_1SpawnManager.html +115 -110
- data/doc/cxxapi/classPassenger_1_1StandardSession-members.html +30 -27
- data/doc/cxxapi/classPassenger_1_1StandardSession.html +163 -184
- data/doc/cxxapi/classPassenger_1_1StaticString-members.html +12 -9
- data/doc/cxxapi/classPassenger_1_1StaticString.html +27 -25
- data/doc/cxxapi/classPassenger_1_1SystemException-members.html +16 -13
- data/doc/cxxapi/classPassenger_1_1SystemException.html +65 -67
- data/doc/cxxapi/classPassenger_1_1TimeRetrievalException-members.html +16 -13
- data/doc/cxxapi/classPassenger_1_1TimeRetrievalException.html +27 -23
- data/doc/cxxapi/classPassenger_1_1TimeoutException-members.html +12 -9
- data/doc/cxxapi/classPassenger_1_1TimeoutException.html +24 -20
- data/doc/cxxapi/classPassenger_1_1Uint16Message-members.html +36 -0
- data/doc/cxxapi/classPassenger_1_1Uint16Message.html +51 -0
- data/doc/cxxapi/classPassenger_1_1Uint32Message-members.html +36 -0
- data/doc/cxxapi/classPassenger_1_1Uint32Message.html +51 -0
- data/doc/cxxapi/classServer-members.html +12 -9
- data/doc/cxxapi/classServer.html +23 -20
- data/doc/cxxapi/classServerInstanceDirToucher-members.html +12 -9
- data/doc/cxxapi/classServerInstanceDirToucher.html +21 -17
- data/doc/cxxapi/classes.html +18 -4
- data/doc/cxxapi/definitions_8h_source.html +1 -0
- data/doc/cxxapi/files.html +36 -1
- data/doc/cxxapi/functions.html +53 -21
- data/doc/cxxapi/functions_0x62.html +82 -0
- data/doc/cxxapi/functions_0x63.html +99 -0
- data/doc/cxxapi/functions_0x64.html +95 -0
- data/doc/cxxapi/functions_0x65.html +88 -0
- data/doc/cxxapi/functions_0x66.html +100 -0
- data/doc/cxxapi/functions_0x67.html +170 -0
- data/doc/cxxapi/functions_0x68.html +88 -0
- data/doc/cxxapi/functions_0x69.html +93 -0
- data/doc/cxxapi/functions_0x6b.html +80 -0
- data/doc/cxxapi/functions_0x6c.html +88 -0
- data/doc/cxxapi/functions_0x6d.html +88 -0
- data/doc/cxxapi/functions_0x6e.html +86 -0
- data/doc/cxxapi/functions_0x6f.html +94 -0
- data/doc/cxxapi/functions_0x70.html +94 -0
- data/doc/cxxapi/functions_0x72.html +110 -0
- data/doc/cxxapi/functions_0x73.html +171 -0
- data/doc/cxxapi/functions_0x74.html +85 -0
- data/doc/cxxapi/functions_0x75.html +85 -0
- data/doc/cxxapi/functions_0x77.html +92 -0
- data/doc/cxxapi/functions_0x7e.html +79 -0
- data/doc/cxxapi/functions_enum.html +14 -12
- data/doc/cxxapi/functions_eval.html +22 -16
- data/doc/cxxapi/functions_func.html +460 -1
- data/doc/cxxapi/functions_vars.html +163 -63
- data/doc/cxxapi/graph_legend.html +1 -0
- data/doc/cxxapi/graph_legend.png +0 -0
- data/doc/cxxapi/group__Core.html +2 -2
- data/doc/cxxapi/group__Core.map +1 -2
- data/doc/cxxapi/group__Core.png +0 -0
- data/doc/cxxapi/group__Exceptions.html +32 -40
- data/doc/cxxapi/group__Hooks.html +2 -1
- data/doc/cxxapi/group__Hooks.map +1 -1
- data/doc/cxxapi/group__Hooks.png +0 -0
- data/doc/cxxapi/group__Support.html +509 -0
- data/doc/cxxapi/hierarchy.html +66 -62
- data/doc/cxxapi/inherit__graph__10.map +3 -1
- data/doc/cxxapi/inherit__graph__10.md5 +1 -1
- data/doc/cxxapi/inherit__graph__10.png +0 -0
- data/doc/cxxapi/inherit__graph__11.map +4 -1
- data/doc/cxxapi/inherit__graph__11.md5 +1 -1
- data/doc/cxxapi/inherit__graph__11.png +0 -0
- data/doc/cxxapi/inherit__graph__12.map +3 -1
- data/doc/cxxapi/inherit__graph__12.md5 +1 -1
- data/doc/cxxapi/inherit__graph__12.png +0 -0
- data/doc/cxxapi/inherit__graph__13.map +3 -1
- data/doc/cxxapi/inherit__graph__13.md5 +1 -1
- data/doc/cxxapi/inherit__graph__13.png +0 -0
- data/doc/cxxapi/inherit__graph__14.map +3 -1
- data/doc/cxxapi/inherit__graph__14.md5 +1 -1
- data/doc/cxxapi/inherit__graph__14.png +0 -0
- data/doc/cxxapi/inherit__graph__15.map +5 -1
- data/doc/cxxapi/inherit__graph__15.md5 +1 -1
- data/doc/cxxapi/inherit__graph__15.png +0 -0
- data/doc/cxxapi/inherit__graph__16.map +3 -3
- data/doc/cxxapi/inherit__graph__16.md5 +1 -1
- data/doc/cxxapi/inherit__graph__16.png +0 -0
- data/doc/cxxapi/inherit__graph__17.map +3 -1
- data/doc/cxxapi/inherit__graph__17.md5 +1 -1
- data/doc/cxxapi/inherit__graph__17.png +0 -0
- data/doc/cxxapi/inherit__graph__18.map +4 -1
- data/doc/cxxapi/inherit__graph__18.md5 +1 -1
- data/doc/cxxapi/inherit__graph__18.png +0 -0
- data/doc/cxxapi/inherit__graph__19.map +3 -1
- data/doc/cxxapi/inherit__graph__19.md5 +1 -1
- data/doc/cxxapi/inherit__graph__19.png +0 -0
- data/doc/cxxapi/inherit__graph__20.map +3 -2
- data/doc/cxxapi/inherit__graph__20.md5 +1 -1
- data/doc/cxxapi/inherit__graph__20.png +0 -0
- data/doc/cxxapi/inherit__graph__21.map +3 -1
- data/doc/cxxapi/inherit__graph__21.md5 +1 -1
- data/doc/cxxapi/inherit__graph__21.png +0 -0
- data/doc/cxxapi/inherit__graph__22.map +3 -1
- data/doc/cxxapi/inherit__graph__22.md5 +1 -1
- data/doc/cxxapi/inherit__graph__22.png +0 -0
- data/doc/cxxapi/inherit__graph__23.map +3 -1
- data/doc/cxxapi/inherit__graph__23.md5 +1 -1
- data/doc/cxxapi/inherit__graph__23.png +0 -0
- data/doc/cxxapi/inherit__graph__24.map +3 -1
- data/doc/cxxapi/inherit__graph__24.md5 +1 -1
- data/doc/cxxapi/inherit__graph__24.png +0 -0
- data/doc/cxxapi/inherit__graph__25.map +3 -1
- data/doc/cxxapi/inherit__graph__25.md5 +1 -1
- data/doc/cxxapi/inherit__graph__25.png +0 -0
- data/doc/cxxapi/inherit__graph__26.map +3 -1
- data/doc/cxxapi/inherit__graph__26.md5 +1 -1
- data/doc/cxxapi/inherit__graph__26.png +0 -0
- data/doc/cxxapi/inherit__graph__27.map +3 -1
- data/doc/cxxapi/inherit__graph__27.md5 +1 -1
- data/doc/cxxapi/inherit__graph__27.png +0 -0
- data/doc/cxxapi/inherit__graph__28.map +4 -1
- data/doc/cxxapi/inherit__graph__28.md5 +1 -1
- data/doc/cxxapi/inherit__graph__28.png +0 -0
- data/doc/cxxapi/inherit__graph__29.map +3 -1
- data/doc/cxxapi/inherit__graph__29.md5 +1 -1
- data/doc/cxxapi/inherit__graph__29.png +0 -0
- data/doc/cxxapi/inherit__graph__30.map +3 -2
- data/doc/cxxapi/inherit__graph__30.md5 +1 -1
- data/doc/cxxapi/inherit__graph__30.png +0 -0
- data/doc/cxxapi/inherit__graph__31.map +3 -1
- data/doc/cxxapi/inherit__graph__31.md5 +1 -1
- data/doc/cxxapi/inherit__graph__31.png +0 -0
- data/doc/cxxapi/inherit__graph__32.map +5 -1
- data/doc/cxxapi/inherit__graph__32.md5 +1 -1
- data/doc/cxxapi/inherit__graph__32.png +0 -0
- data/doc/cxxapi/inherit__graph__33.map +3 -1
- data/doc/cxxapi/inherit__graph__33.md5 +1 -1
- data/doc/cxxapi/inherit__graph__33.png +0 -0
- data/doc/cxxapi/inherit__graph__34.map +3 -3
- data/doc/cxxapi/inherit__graph__34.md5 +1 -1
- data/doc/cxxapi/inherit__graph__34.png +0 -0
- data/doc/cxxapi/inherit__graph__35.map +3 -1
- data/doc/cxxapi/inherit__graph__35.md5 +1 -1
- data/doc/cxxapi/inherit__graph__35.png +0 -0
- data/doc/cxxapi/inherit__graph__36.map +3 -1
- data/doc/cxxapi/inherit__graph__36.md5 +1 -1
- data/doc/cxxapi/inherit__graph__36.png +0 -0
- data/doc/cxxapi/inherit__graph__37.map +3 -1
- data/doc/cxxapi/inherit__graph__37.md5 +1 -1
- data/doc/cxxapi/inherit__graph__37.png +0 -0
- data/doc/cxxapi/inherit__graph__4.map +3 -1
- data/doc/cxxapi/inherit__graph__4.md5 +1 -1
- data/doc/cxxapi/inherit__graph__4.png +0 -0
- data/doc/cxxapi/inherit__graph__5.map +3 -1
- data/doc/cxxapi/inherit__graph__5.md5 +1 -1
- data/doc/cxxapi/inherit__graph__5.png +0 -0
- data/doc/cxxapi/inherit__graph__6.map +3 -1
- data/doc/cxxapi/inherit__graph__6.md5 +1 -1
- data/doc/cxxapi/inherit__graph__6.png +0 -0
- data/doc/cxxapi/inherit__graph__7.map +3 -1
- data/doc/cxxapi/inherit__graph__7.md5 +1 -1
- data/doc/cxxapi/inherit__graph__7.png +0 -0
- data/doc/cxxapi/inherit__graph__8.map +3 -1
- data/doc/cxxapi/inherit__graph__8.md5 +1 -1
- data/doc/cxxapi/inherit__graph__8.png +0 -0
- data/doc/cxxapi/inherit__graph__9.map +3 -1
- data/doc/cxxapi/inherit__graph__9.md5 +1 -1
- data/doc/cxxapi/inherit__graph__9.png +0 -0
- data/doc/cxxapi/inherits.html +123 -126
- data/doc/cxxapi/main.html +1 -0
- data/doc/cxxapi/modules.html +2 -1
- data/doc/cxxapi/namespacePassenger.html +263 -492
- data/doc/cxxapi/namespacemembers.html +68 -96
- data/doc/cxxapi/namespacemembers_enum.html +14 -12
- data/doc/cxxapi/namespacemembers_eval.html +20 -15
- data/doc/cxxapi/namespacemembers_func.html +52 -88
- data/doc/cxxapi/namespacemembers_type.html +18 -14
- data/doc/cxxapi/namespaces.html +12 -9
- data/doc/cxxapi/nginx_2Configuration_8h_source.html +125 -0
- data/doc/cxxapi/ngx__http__passenger__module_8h_source.html +94 -0
- data/doc/cxxapi/structPassenger_1_1MessageServer_1_1DisconnectEventBroadcastGuard-members.html +12 -9
- data/doc/cxxapi/structPassenger_1_1MessageServer_1_1DisconnectEventBroadcastGuard.html +24 -22
- data/doc/cxxapi/structPassenger_1_1PoolOptions-members.html +43 -38
- data/doc/cxxapi/structPassenger_1_1PoolOptions.html +275 -325
- data/doc/cxxapi/structPassenger_1_1StaticString_1_1Hash-members.html +12 -9
- data/doc/cxxapi/structPassenger_1_1StaticString_1_1Hash.html +24 -22
- data/doc/cxxapi/tree.html +152 -7
- data/doc/users_guide_snippets/{analysis_and_system_maintenance_tools.txt → analysis_and_system_maintenance.txt} +58 -1
- data/doc/users_guide_snippets/appendix_c_spawning_methods.txt +1 -2
- data/doc/users_guide_snippets/global_queueing_explained.txt +1 -5
- data/doc/users_guide_snippets/{rails_spawn_method.txt → passenger_spawn_method.txt} +9 -8
- data/doc/users_guide_snippets/tips.txt +12 -6
- data/doc/users_guide_snippets/under_the_hood/page_caching_support.txt +22 -0
- data/ext/apache2/Bucket.cpp +4 -4
- data/ext/apache2/Bucket.h +3 -3
- data/ext/apache2/Configuration.cpp +278 -381
- data/ext/apache2/Configuration.h +3 -357
- data/ext/apache2/Configuration.hpp +461 -0
- data/ext/apache2/DirectoryMapper.h +3 -3
- data/ext/apache2/HelperAgent.cpp +359 -0
- data/ext/apache2/Hooks.cpp +339 -226
- data/ext/apache2/Hooks.h +1 -1
- data/ext/apache2/mod_passenger.c +10 -4
- data/ext/boost/algorithm/string/case_conv.hpp +4 -4
- data/ext/boost/algorithm/string/concept.hpp +2 -2
- data/ext/boost/algorithm/string/detail/case_conv.hpp +18 -9
- data/ext/boost/algorithm/string/detail/find_format.hpp +44 -43
- data/ext/boost/algorithm/string/detail/find_format_all.hpp +56 -56
- data/ext/boost/algorithm/string/detail/find_format_store.hpp +7 -0
- data/ext/boost/algorithm/string/detail/finder.hpp +14 -14
- data/ext/boost/algorithm/string/detail/formatter.hpp +2 -2
- data/ext/boost/algorithm/string/detail/replace_storage.hpp +3 -3
- data/ext/boost/algorithm/string/detail/sequence.hpp +3 -3
- data/ext/boost/algorithm/string/erase.hpp +98 -98
- data/ext/boost/algorithm/string/find_format.hpp +56 -38
- data/ext/boost/algorithm/string/finder.hpp +6 -6
- data/ext/boost/algorithm/string/formatter.hpp +1 -1
- data/ext/boost/algorithm/string/replace.hpp +99 -99
- data/ext/boost/bind.hpp +5 -1670
- data/ext/boost/bind/bind.hpp +1751 -0
- data/ext/boost/bind/bind_mf2_cc.hpp +228 -0
- data/ext/boost/bind/mem_fn.hpp +389 -0
- data/ext/boost/bind/mem_fn_template.hpp +54 -27
- data/ext/boost/bind/placeholders.hpp +3 -2
- data/ext/boost/concept_check.hpp +10 -0
- data/ext/boost/config/abi/msvc_prefix.hpp +15 -1
- data/ext/boost/config/abi_prefix.hpp +1 -1
- data/ext/boost/config/abi_suffix.hpp +3 -2
- data/ext/boost/config/auto_link.hpp +6 -1
- data/ext/boost/config/compiler/borland.hpp +75 -17
- data/ext/boost/config/compiler/codegear.hpp +163 -0
- data/ext/boost/config/compiler/common_edg.hpp +35 -0
- data/ext/boost/config/compiler/digitalmars.hpp +26 -0
- data/ext/boost/config/compiler/gcc.hpp +69 -14
- data/ext/boost/config/compiler/hp_acc.hpp +32 -0
- data/ext/boost/config/compiler/intel.hpp +13 -2
- data/ext/boost/config/compiler/kai.hpp +0 -2
- data/ext/boost/config/compiler/metrowerks.hpp +29 -1
- data/ext/boost/config/compiler/mpw.hpp +30 -0
- data/ext/boost/config/compiler/pgi.hpp +37 -0
- data/ext/boost/config/compiler/sgi_mipspro.hpp +1 -0
- data/ext/boost/config/compiler/sunpro_cc.hpp +39 -7
- data/ext/boost/config/compiler/vacpp.hpp +31 -3
- data/ext/boost/config/compiler/visualc.hpp +72 -5
- data/ext/boost/config/no_tr1/cmath.hpp +28 -0
- data/ext/boost/config/platform/bsd.hpp +16 -3
- data/ext/boost/config/platform/hpux.hpp +3 -0
- data/ext/boost/config/platform/macos.hpp +8 -0
- data/ext/boost/config/platform/solaris.hpp +7 -0
- data/ext/boost/config/platform/vxworks.hpp +31 -0
- data/ext/boost/config/select_compiler_config.hpp +4 -0
- data/ext/boost/config/select_platform_config.hpp +6 -2
- data/ext/boost/config/select_stdlib_config.hpp +17 -8
- data/ext/boost/config/stdlib/dinkumware.hpp +34 -2
- data/ext/boost/config/stdlib/libcomo.hpp +25 -0
- data/ext/boost/config/stdlib/libstdcpp3.hpp +56 -2
- data/ext/boost/config/stdlib/modena.hpp +25 -0
- data/ext/boost/config/stdlib/msl.hpp +24 -0
- data/ext/boost/config/stdlib/roguewave.hpp +26 -0
- data/ext/boost/config/stdlib/sgi.hpp +25 -0
- data/ext/boost/config/stdlib/stlport.hpp +36 -1
- data/ext/boost/config/stdlib/vacpp.hpp +25 -0
- data/ext/boost/config/suffix.hpp +67 -32
- data/ext/boost/config/warning_disable.hpp +47 -0
- data/ext/boost/cstdint.hpp +62 -36
- data/ext/boost/date_time/c_time.hpp +28 -12
- data/ext/boost/date_time/compiler_config.hpp +27 -5
- data/ext/boost/date_time/constrained_value.hpp +36 -13
- data/ext/boost/date_time/date.hpp +44 -33
- data/ext/boost/date_time/date_duration.hpp +13 -14
- data/ext/boost/date_time/date_facet.hpp +215 -226
- data/ext/boost/date_time/date_generator_formatter.hpp +22 -20
- data/ext/boost/date_time/date_generator_parser.hpp +52 -51
- data/ext/boost/date_time/date_generators.hpp +16 -16
- data/ext/boost/date_time/date_parsing.hpp +115 -98
- data/ext/boost/date_time/filetime_functions.hpp +133 -41
- data/ext/boost/date_time/format_date_parser.hpp +22 -10
- data/ext/boost/date_time/gregorian/conversion.hpp +32 -39
- data/ext/boost/date_time/gregorian/greg_calendar.hpp +15 -14
- data/ext/boost/date_time/gregorian/greg_date.hpp +19 -18
- data/ext/boost/date_time/gregorian/greg_duration.hpp +106 -10
- data/ext/boost/date_time/gregorian/greg_duration_types.hpp +16 -7
- data/ext/boost/date_time/gregorian/greg_weekday.hpp +2 -2
- data/ext/boost/date_time/gregorian/gregorian_io.hpp +11 -4
- data/ext/boost/date_time/gregorian_calendar.hpp +8 -8
- data/ext/boost/date_time/gregorian_calendar.ipp +30 -30
- data/ext/boost/date_time/int_adapter.hpp +4 -2
- data/ext/boost/date_time/microsec_time_clock.hpp +39 -117
- data/ext/boost/date_time/period_parser.hpp +17 -15
- data/ext/boost/date_time/posix_time/conversion.hpp +28 -29
- data/ext/boost/date_time/posix_time/posix_time_config.hpp +19 -19
- data/ext/boost/date_time/posix_time/posix_time_io.hpp +31 -38
- data/ext/boost/date_time/posix_time/time_formatters.hpp +32 -32
- data/ext/boost/date_time/string_parse_tree.hpp +46 -46
- data/ext/boost/date_time/strings_from_facet.hpp +7 -5
- data/ext/boost/date_time/time.hpp +7 -6
- data/ext/boost/date_time/time_defs.hpp +12 -2
- data/ext/boost/date_time/time_duration.hpp +27 -26
- data/ext/boost/date_time/time_facet.hpp +386 -321
- data/ext/boost/date_time/time_formatting_streams.hpp +8 -5
- data/ext/boost/date_time/time_resolution_traits.hpp +29 -25
- data/ext/boost/date_time/time_system_split.hpp +7 -13
- data/ext/boost/date_time/wrapping_int.hpp +21 -15
- data/ext/boost/detail/call_traits.hpp +1 -1
- data/ext/boost/detail/endian.hpp +4 -4
- data/ext/boost/detail/no_exceptions_support.hpp +87 -0
- data/ext/boost/detail/sp_typeinfo.hpp +50 -4
- data/ext/boost/detail/workaround.hpp +63 -3
- data/ext/boost/enable_shared_from_this.hpp +4 -59
- data/ext/boost/exception/current_exception_cast.hpp +43 -0
- data/ext/boost/exception/detail/attribute_noreturn.hpp +17 -0
- data/ext/boost/exception/detail/error_info_impl.hpp +75 -0
- data/ext/boost/exception/detail/exception_ptr.hpp +490 -0
- data/ext/boost/exception/detail/is_output_streamable.hpp +47 -0
- data/ext/boost/exception/detail/object_hex_dump.hpp +50 -0
- data/ext/boost/exception/detail/type_info.hpp +79 -0
- data/ext/boost/exception/diagnostic_information.hpp +182 -0
- data/ext/boost/exception/exception.hpp +422 -0
- data/ext/boost/exception/get_error_info.hpp +130 -0
- data/ext/boost/exception/info.hpp +167 -0
- data/ext/boost/exception/to_string.hpp +83 -0
- data/ext/boost/exception/to_string_stub.hpp +109 -0
- data/ext/boost/exception_ptr.hpp +11 -0
- data/ext/boost/function/detail/prologue.hpp +2 -1
- data/ext/boost/function/function_base.hpp +270 -128
- data/ext/boost/function/function_fwd.hpp +70 -0
- data/ext/boost/function/function_template.hpp +319 -130
- data/ext/boost/get_pointer.hpp +5 -1
- data/ext/boost/integer.hpp +253 -0
- data/ext/boost/integer_fwd.hpp +174 -0
- data/ext/boost/integer_traits.hpp +26 -1
- data/ext/boost/io/ios_state.hpp +8 -0
- data/ext/boost/iterator/detail/config_def.hpp +4 -2
- data/ext/boost/iterator/iterator_adaptor.hpp +7 -2
- data/ext/boost/iterator/iterator_facade.hpp +1 -2
- data/ext/boost/lexical_cast.hpp +113 -105
- data/ext/boost/limits.hpp +1 -1
- data/ext/boost/mem_fn.hpp +5 -370
- data/ext/boost/memory_order.hpp +53 -0
- data/ext/boost/mpl/always.hpp +3 -3
- data/ext/boost/mpl/and.hpp +3 -3
- data/ext/boost/mpl/apply.hpp +3 -3
- data/ext/boost/mpl/apply_fwd.hpp +3 -3
- data/ext/boost/mpl/apply_wrap.hpp +37 -6
- data/ext/boost/mpl/arg.hpp +3 -3
- data/ext/boost/mpl/arg_fwd.hpp +3 -3
- data/ext/boost/mpl/assert.hpp +6 -6
- data/ext/boost/mpl/aux_/adl_barrier.hpp +3 -3
- data/ext/boost/mpl/aux_/arg_typedef.hpp +3 -3
- data/ext/boost/mpl/aux_/arity.hpp +3 -3
- data/ext/boost/mpl/aux_/arity_spec.hpp +3 -3
- data/ext/boost/mpl/aux_/common_name_wknd.hpp +3 -3
- data/ext/boost/mpl/aux_/config/adl.hpp +4 -4
- data/ext/boost/mpl/aux_/config/arrays.hpp +4 -4
- data/ext/boost/mpl/aux_/config/bcc.hpp +28 -0
- data/ext/boost/mpl/aux_/config/bind.hpp +4 -4
- data/ext/boost/mpl/aux_/config/compiler.hpp +8 -6
- data/ext/boost/mpl/aux_/config/ctps.hpp +3 -3
- data/ext/boost/mpl/aux_/config/dtp.hpp +5 -5
- data/ext/boost/mpl/aux_/config/eti.hpp +3 -3
- data/ext/boost/mpl/aux_/config/gcc.hpp +3 -3
- data/ext/boost/mpl/aux_/config/has_apply.hpp +3 -3
- data/ext/boost/mpl/aux_/config/has_xxx.hpp +3 -3
- data/ext/boost/mpl/aux_/config/integral.hpp +4 -4
- data/ext/boost/mpl/aux_/config/intel.hpp +3 -3
- data/ext/boost/mpl/aux_/config/lambda.hpp +3 -3
- data/ext/boost/mpl/aux_/config/msvc.hpp +3 -3
- data/ext/boost/mpl/aux_/config/msvc_typename.hpp +3 -3
- data/ext/boost/mpl/aux_/config/nttp.hpp +3 -3
- data/ext/boost/mpl/aux_/config/overload_resolution.hpp +3 -3
- data/ext/boost/mpl/aux_/config/pp_counter.hpp +3 -3
- data/ext/boost/mpl/aux_/config/preprocessor.hpp +4 -4
- data/ext/boost/mpl/aux_/config/static_constant.hpp +3 -3
- data/ext/boost/mpl/aux_/config/ttp.hpp +4 -4
- data/ext/boost/mpl/aux_/config/use_preprocessed.hpp +3 -3
- data/ext/boost/mpl/aux_/config/workaround.hpp +3 -3
- data/ext/boost/mpl/aux_/full_lambda.hpp +3 -3
- data/ext/boost/mpl/aux_/has_apply.hpp +3 -3
- data/ext/boost/mpl/aux_/has_type.hpp +3 -3
- data/ext/boost/mpl/aux_/include_preprocessed.hpp +3 -3
- data/ext/boost/mpl/aux_/integral_wrapper.hpp +3 -3
- data/ext/boost/mpl/aux_/lambda_arity_param.hpp +3 -3
- data/ext/boost/mpl/aux_/lambda_support.hpp +4 -4
- data/ext/boost/mpl/aux_/msvc_never_true.hpp +3 -3
- data/ext/boost/mpl/aux_/na.hpp +3 -3
- data/ext/boost/mpl/aux_/na_assert.hpp +3 -3
- data/ext/boost/mpl/aux_/na_fwd.hpp +3 -3
- data/ext/boost/mpl/aux_/na_spec.hpp +3 -3
- data/ext/boost/mpl/aux_/nested_type_wknd.hpp +3 -3
- data/ext/boost/mpl/aux_/nttp_decl.hpp +3 -3
- data/ext/boost/mpl/aux_/preprocessor/def_params_tail.hpp +3 -3
- data/ext/boost/mpl/aux_/preprocessor/enum.hpp +3 -3
- data/ext/boost/mpl/aux_/preprocessor/filter_params.hpp +3 -3
- data/ext/boost/mpl/aux_/preprocessor/params.hpp +3 -3
- data/ext/boost/mpl/aux_/preprocessor/sub.hpp +3 -3
- data/ext/boost/mpl/aux_/static_cast.hpp +3 -3
- data/ext/boost/mpl/aux_/template_arity.hpp +3 -3
- data/ext/boost/mpl/aux_/template_arity_fwd.hpp +3 -3
- data/ext/boost/mpl/aux_/type_wrapper.hpp +3 -3
- data/ext/boost/mpl/aux_/value_wknd.hpp +3 -3
- data/ext/boost/mpl/aux_/yes_no.hpp +3 -3
- data/ext/boost/mpl/bind.hpp +3 -3
- data/ext/boost/mpl/bind_fwd.hpp +3 -3
- data/ext/boost/mpl/bool.hpp +3 -3
- data/ext/boost/mpl/bool_fwd.hpp +3 -3
- data/ext/boost/mpl/eval_if.hpp +3 -3
- data/ext/boost/mpl/has_xxx.hpp +10 -8
- data/ext/boost/mpl/identity.hpp +3 -3
- data/ext/boost/mpl/if.hpp +3 -3
- data/ext/boost/mpl/int.hpp +3 -3
- data/ext/boost/mpl/int_fwd.hpp +3 -3
- data/ext/boost/mpl/integral_c.hpp +3 -3
- data/ext/boost/mpl/integral_c_fwd.hpp +3 -3
- data/ext/boost/mpl/integral_c_tag.hpp +3 -3
- data/ext/boost/mpl/lambda.hpp +3 -3
- data/ext/boost/mpl/lambda_fwd.hpp +3 -3
- data/ext/boost/mpl/limits/arity.hpp +3 -3
- data/ext/boost/mpl/logical.hpp +3 -3
- data/ext/boost/mpl/next.hpp +3 -3
- data/ext/boost/mpl/next_prior.hpp +3 -3
- data/ext/boost/mpl/not.hpp +3 -3
- data/ext/boost/mpl/or.hpp +3 -3
- data/ext/boost/mpl/placeholders.hpp +3 -3
- data/ext/boost/mpl/protect.hpp +3 -3
- data/ext/boost/mpl/quote.hpp +18 -7
- data/ext/boost/mpl/size_t.hpp +3 -3
- data/ext/boost/mpl/size_t_fwd.hpp +3 -3
- data/ext/boost/mpl/void.hpp +3 -3
- data/ext/boost/mpl/void_fwd.hpp +3 -3
- data/ext/boost/non_type.hpp +27 -27
- data/ext/boost/operators.hpp +51 -18
- data/ext/boost/preprocessor/arithmetic/detail/div_base.hpp +61 -0
- data/ext/boost/preprocessor/arithmetic/mod.hpp +39 -0
- data/ext/boost/preprocessor/comparison/less_equal.hpp +39 -0
- data/ext/boost/preprocessor/control/deduce_d.hpp +22 -0
- data/ext/boost/preprocessor/logical/not.hpp +30 -0
- data/ext/boost/preprocessor/seq/cat.hpp +48 -0
- data/ext/boost/preprocessor/seq/fold_left.hpp +1070 -0
- data/ext/boost/preprocessor/seq/transform.hpp +48 -0
- data/ext/boost/range/as_literal.hpp +10 -14
- data/ext/boost/range/begin.hpp +4 -4
- data/ext/boost/range/detail/implementation_help.hpp +4 -0
- data/ext/boost/range/end.hpp +4 -4
- data/ext/boost/range/iterator_range.hpp +31 -15
- data/ext/boost/ref.hpp +12 -1
- data/ext/boost/scoped_array.hpp +16 -0
- data/ext/boost/scoped_ptr.hpp +16 -0
- data/ext/boost/shared_ptr.hpp +2 -602
- data/ext/boost/{detail → smart_ptr}/bad_weak_ptr.hpp +4 -4
- data/ext/boost/{detail → smart_ptr/detail}/atomic_count.hpp +14 -19
- data/ext/boost/{detail → smart_ptr/detail}/atomic_count_gcc.hpp +13 -9
- data/ext/boost/{detail → smart_ptr/detail}/atomic_count_gcc_x86.hpp +5 -12
- data/ext/boost/{detail → smart_ptr/detail}/atomic_count_pthreads.hpp +5 -5
- data/ext/boost/{detail → smart_ptr/detail}/atomic_count_solaris.hpp +3 -3
- data/ext/boost/{detail → smart_ptr/detail}/atomic_count_sync.hpp +9 -5
- data/ext/boost/{detail → smart_ptr/detail}/atomic_count_win32.hpp +3 -3
- data/ext/boost/smart_ptr/detail/operator_bool.hpp +56 -0
- data/ext/boost/{detail → smart_ptr/detail}/shared_count.hpp +86 -17
- data/ext/boost/smart_ptr/detail/sp_convertible.hpp +76 -0
- data/ext/boost/smart_ptr/detail/sp_counted_base.hpp +70 -0
- data/ext/boost/{detail → smart_ptr/detail}/sp_counted_base_acc_ia64.hpp +4 -4
- data/ext/boost/{detail → smart_ptr/detail}/sp_counted_base_cw_ppc.hpp +4 -4
- data/ext/boost/{detail → smart_ptr/detail}/sp_counted_base_cw_x86.hpp +4 -4
- data/ext/boost/{detail → smart_ptr/detail}/sp_counted_base_gcc_ia64.hpp +4 -4
- data/ext/boost/smart_ptr/detail/sp_counted_base_gcc_mips.hpp +172 -0
- data/ext/boost/{detail → smart_ptr/detail}/sp_counted_base_gcc_ppc.hpp +4 -4
- data/ext/boost/{detail → smart_ptr/detail}/sp_counted_base_gcc_sparc.hpp +7 -7
- data/ext/boost/{detail → smart_ptr/detail}/sp_counted_base_gcc_x86.hpp +4 -4
- data/ext/boost/{detail → smart_ptr/detail}/sp_counted_base_nt.hpp +4 -4
- data/ext/boost/{detail → smart_ptr/detail}/sp_counted_base_pt.hpp +4 -4
- data/ext/boost/{detail → smart_ptr/detail}/sp_counted_base_solaris.hpp +4 -4
- data/ext/boost/smart_ptr/detail/sp_counted_base_spin.hpp +131 -0
- data/ext/boost/{detail → smart_ptr/detail}/sp_counted_base_sync.hpp +8 -4
- data/ext/boost/{detail → smart_ptr/detail}/sp_counted_base_w32.hpp +4 -4
- data/ext/boost/{detail → smart_ptr/detail}/sp_counted_impl.hpp +5 -5
- data/ext/boost/smart_ptr/detail/sp_has_sync.hpp +49 -0
- data/ext/boost/smart_ptr/detail/spinlock.hpp +53 -0
- data/ext/boost/smart_ptr/detail/spinlock_gcc_arm.hpp +85 -0
- data/ext/boost/smart_ptr/detail/spinlock_nt.hpp +89 -0
- data/ext/boost/smart_ptr/detail/spinlock_pool.hpp +87 -0
- data/ext/boost/smart_ptr/detail/spinlock_pt.hpp +79 -0
- data/ext/boost/smart_ptr/detail/spinlock_sync.hpp +87 -0
- data/ext/boost/smart_ptr/detail/yield_k.hpp +149 -0
- data/ext/boost/smart_ptr/enable_shared_from_this.hpp +79 -0
- data/ext/boost/smart_ptr/scoped_array.hpp +107 -0
- data/ext/boost/smart_ptr/scoped_ptr.hpp +131 -0
- data/ext/boost/smart_ptr/shared_ptr.hpp +701 -0
- data/ext/boost/smart_ptr/weak_ptr.hpp +230 -0
- data/ext/boost/src/pthread/thread.cpp +115 -203
- data/ext/boost/src/tss_null.cpp +1 -1
- data/ext/boost/static_assert.hpp +14 -4
- data/ext/boost/thread.hpp +7 -2
- data/ext/boost/thread/barrier.hpp +63 -0
- data/ext/boost/thread/detail/force_cast.hpp +39 -0
- data/ext/boost/thread/detail/move.hpp +29 -2
- data/ext/boost/thread/detail/platform.hpp +3 -3
- data/ext/boost/thread/detail/singleton.hpp +59 -0
- data/ext/boost/thread/detail/thread.hpp +496 -0
- data/ext/boost/thread/detail/thread_group.hpp +105 -0
- data/ext/boost/thread/detail/thread_heap_alloc.hpp +23 -0
- data/ext/boost/thread/detail/thread_interruption.hpp +35 -0
- data/ext/boost/thread/detail/tss_hooks.hpp +82 -0
- data/ext/boost/thread/exceptions.hpp +174 -60
- data/ext/boost/thread/future.hpp +1364 -0
- data/ext/boost/thread/locks.hpp +899 -32
- data/ext/boost/thread/once.hpp +4 -0
- data/ext/boost/thread/pthread/condition_variable.hpp +16 -21
- data/ext/boost/thread/pthread/condition_variable_fwd.hpp +37 -3
- data/ext/boost/thread/pthread/mutex.hpp +20 -7
- data/ext/boost/thread/pthread/once.hpp +7 -2
- data/ext/boost/thread/pthread/pthread_mutex_scoped_lock.hpp +5 -1
- data/ext/boost/thread/pthread/recursive_mutex.hpp +22 -5
- data/ext/boost/thread/pthread/shared_mutex.hpp +303 -0
- data/ext/boost/thread/pthread/thread_data.hpp +37 -10
- data/ext/boost/thread/pthread/thread_heap_alloc.hpp +242 -0
- data/ext/boost/thread/pthread/timespec.hpp +11 -3
- data/ext/boost/thread/shared_mutex.hpp +21 -0
- data/ext/boost/thread/thread.hpp +8 -3
- data/ext/boost/thread/thread_time.hpp +4 -0
- data/ext/boost/thread/tss.hpp +106 -13
- data/ext/boost/thread/xtime.hpp +6 -2
- data/ext/boost/throw_exception.hpp +36 -7
- data/ext/boost/token_functions.hpp +1 -1
- data/ext/boost/tokenizer.hpp +1 -1
- data/ext/boost/type_traits/add_pointer.hpp +1 -1
- data/ext/boost/type_traits/add_volatile.hpp +47 -0
- data/ext/boost/type_traits/alignment_of.hpp +29 -1
- data/ext/boost/type_traits/config.hpp +1 -1
- data/ext/boost/type_traits/conversion_traits.hpp +1 -1
- data/ext/boost/type_traits/has_trivial_destructor.hpp +42 -0
- data/ext/boost/type_traits/intrinsics.hpp +88 -1
- data/ext/boost/type_traits/is_abstract.hpp +14 -5
- data/ext/boost/type_traits/is_arithmetic.hpp +8 -0
- data/ext/boost/type_traits/is_array.hpp +3 -2
- data/ext/boost/type_traits/is_base_and_derived.hpp +254 -0
- data/ext/boost/type_traits/is_base_of.hpp +51 -0
- data/ext/boost/type_traits/is_class.hpp +12 -0
- data/ext/boost/type_traits/is_const.hpp +6 -2
- data/ext/boost/type_traits/is_convertible.hpp +14 -2
- data/ext/boost/type_traits/is_enum.hpp +10 -1
- data/ext/boost/type_traits/is_function.hpp +11 -3
- data/ext/boost/type_traits/is_fundamental.hpp +45 -0
- data/ext/boost/type_traits/is_integral.hpp +5 -0
- data/ext/boost/type_traits/is_member_function_pointer.hpp +5 -3
- data/ext/boost/type_traits/is_member_pointer.hpp +4 -2
- data/ext/boost/type_traits/is_pointer.hpp +3 -1
- data/ext/boost/type_traits/is_reference.hpp +4 -2
- data/ext/boost/type_traits/is_signed.hpp +135 -0
- data/ext/boost/type_traits/is_unsigned.hpp +130 -0
- data/ext/boost/type_traits/is_void.hpp +5 -0
- data/ext/boost/type_traits/is_volatile.hpp +4 -2
- data/ext/boost/type_traits/make_unsigned.hpp +137 -0
- data/ext/boost/type_traits/remove_reference.hpp +1 -1
- data/ext/boost/type_traits/type_with_alignment.hpp +106 -1
- data/ext/boost/utility.hpp +2 -1
- data/ext/boost/utility/addressof.hpp +61 -17
- data/ext/boost/utility/binary.hpp +708 -0
- data/ext/boost/utility/enable_if.hpp +2 -2
- data/ext/boost/weak_ptr.hpp +4 -174
- data/ext/common/AbstractSpawnManager.h +110 -0
- data/ext/common/Account.h +175 -0
- data/ext/common/AccountsDatabase.cpp +81 -0
- data/ext/common/AccountsDatabase.h +130 -0
- data/ext/common/AgentBase.cpp +323 -0
- data/ext/common/{Version.h → AgentBase.h} +14 -6
- data/ext/common/AgentsStarter.cpp +154 -0
- data/ext/common/AgentsStarter.h +81 -0
- data/ext/common/AgentsStarter.hpp +619 -0
- data/ext/common/ApplicationPool/Client.h +796 -0
- data/ext/common/{ApplicationPool.h → ApplicationPool/Interface.h} +108 -18
- data/ext/common/ApplicationPool/Pool.h +1315 -0
- data/ext/common/ApplicationPool/Server.h +475 -0
- data/ext/common/BCrypt.cpp +343 -0
- data/ext/common/BCrypt.h +73 -0
- data/ext/common/Blowfish.c +685 -0
- data/ext/common/Blowfish.h +103 -0
- data/ext/common/Constants.h +48 -0
- data/ext/common/EventedClient.h +598 -0
- data/ext/common/EventedMessageServer.h +327 -0
- data/ext/common/EventedServer.h +295 -0
- data/ext/common/Exceptions.h +78 -1
- data/ext/common/FileDescriptor.h +229 -0
- data/ext/common/HelperAgent/BacktracesServer.h +59 -0
- data/ext/common/Logging.cpp +8 -9
- data/ext/common/Logging.h +593 -21
- data/ext/common/LoggingAgent/ChangeNotifier.h +63 -0
- data/ext/common/LoggingAgent/DataStoreId.h +177 -0
- data/ext/common/LoggingAgent/LoggingServer.h +1343 -0
- data/ext/common/LoggingAgent/Main.cpp +278 -0
- data/ext/common/LoggingAgent/RemoteSender.h +457 -0
- data/ext/common/MessageChannel.h +196 -34
- data/ext/common/MessageClient.h +297 -0
- data/ext/common/MessageReadersWriters.h +508 -0
- data/ext/common/MessageServer.h +575 -0
- data/ext/common/PoolOptions.h +279 -117
- data/ext/common/Process.h +255 -0
- data/ext/common/RandomGenerator.h +160 -0
- data/ext/common/ResourceLocator.h +84 -0
- data/ext/common/ServerInstanceDir.h +343 -0
- data/ext/common/Session.h +470 -0
- data/ext/common/SpawnManager.h +256 -201
- data/ext/common/StaticString.h +79 -4
- data/ext/common/StringListCreator.h +2 -2
- data/ext/common/Utils.cpp +385 -397
- data/ext/common/Utils.h +79 -165
- data/ext/common/{Base64.cpp → Utils/Base64.cpp} +0 -0
- data/ext/common/{Base64.h → Utils/Base64.h} +27 -1
- data/ext/common/Utils/BlockingQueue.h +136 -0
- data/ext/common/Utils/BlockingScalar.h +50 -0
- data/ext/common/{CachedFileStat.cpp → Utils/CachedFileStat.cpp} +1 -1
- data/ext/common/{CachedFileStat.h → Utils/CachedFileStat.h} +1 -1
- data/ext/common/{CachedFileStat.hpp → Utils/CachedFileStat.hpp} +1 -1
- data/ext/common/{FileChangeChecker.h → Utils/FileChangeChecker.h} +1 -1
- data/ext/common/Utils/FileHandleGuard.h +81 -0
- data/ext/common/Utils/IOUtils.cpp +754 -0
- data/ext/common/Utils/IOUtils.h +253 -0
- data/ext/common/Utils/MD5.cpp +406 -0
- data/ext/common/Utils/MD5.h +98 -0
- data/ext/common/Utils/MemZeroGuard.h +103 -0
- data/ext/common/Utils/ProcessMetricsCollector.h +462 -0
- data/ext/common/Utils/ScopeGuard.h +72 -0
- data/ext/common/Utils/StrIntUtils.cpp +329 -0
- data/ext/common/Utils/StrIntUtils.h +228 -0
- data/ext/common/{SystemTime.cpp → Utils/SystemTime.cpp} +5 -1
- data/ext/common/Utils/SystemTime.h +201 -0
- data/ext/common/{Timer.h → Utils/Timer.h} +58 -18
- data/ext/common/Utils/VariantMap.h +363 -0
- data/ext/common/Utils/foo.cpp +10 -0
- data/ext/common/Watchdog.cpp +1034 -0
- data/ext/google/COPYING +28 -0
- data/ext/google/ChangeLog +167 -0
- data/ext/google/dense_hash_map +310 -0
- data/ext/google/dense_hash_set +287 -0
- data/ext/google/sparse_hash_map +294 -0
- data/ext/google/sparse_hash_set +275 -0
- data/ext/google/sparsehash/densehashtable.h +1062 -0
- data/ext/google/sparsehash/sparseconfig.h +55 -0
- data/ext/google/sparsehash/sparsehashtable.h +1015 -0
- data/ext/google/sparsetable +1468 -0
- data/ext/google/type_traits.h +250 -0
- data/ext/libev/Changes +302 -0
- data/ext/libev/LICENSE +36 -0
- data/ext/libev/Makefile.am +18 -0
- data/ext/libev/Makefile.in +685 -0
- data/ext/libev/README +58 -0
- data/ext/libev/aclocal.m4 +7549 -0
- data/ext/libev/autogen.sh +6 -0
- data/ext/libev/config.guess +1526 -0
- data/ext/libev/config.h +122 -0
- data/ext/libev/config.h.in +121 -0
- data/ext/libev/config.sub +1658 -0
- data/ext/libev/configure +22156 -0
- data/ext/libev/configure.ac +18 -0
- data/ext/libev/ev++.h +800 -0
- data/ext/libev/ev.c +3694 -0
- data/ext/libev/ev.h +705 -0
- data/ext/libev/ev_epoll.c +228 -0
- data/ext/libev/ev_kqueue.c +196 -0
- data/ext/libev/ev_poll.c +144 -0
- data/ext/libev/ev_port.c +165 -0
- data/ext/libev/ev_select.c +308 -0
- data/ext/libev/ev_vars.h +187 -0
- data/ext/libev/ev_win32.c +153 -0
- data/ext/libev/ev_wrap.h +178 -0
- data/ext/libev/event.c +401 -0
- data/ext/libev/event.h +158 -0
- data/ext/libev/install-sh +294 -0
- data/ext/libev/libev.m4 +38 -0
- data/ext/libev/ltmain.sh +6871 -0
- data/ext/libev/missing +336 -0
- data/ext/libev/mkinstalldirs +111 -0
- data/ext/nginx/Configuration.c +532 -182
- data/ext/nginx/Configuration.h +33 -10
- data/ext/nginx/ContentHandler.c +188 -53
- data/ext/nginx/ContentHandler.h +1 -1
- data/ext/nginx/{HelperServer.cpp → HelperAgent.cpp} +433 -299
- data/ext/nginx/HttpStatusExtractor.h +1 -1
- data/ext/nginx/ScgiRequestParser.h +68 -11
- data/ext/nginx/StaticContentHandler.c +4 -1
- data/ext/nginx/StaticContentHandler.h +1 -1
- data/ext/nginx/config +5 -5
- data/ext/nginx/ngx_http_passenger_module.c +315 -469
- data/ext/nginx/ngx_http_passenger_module.h +8 -17
- data/ext/oxt/backtrace.cpp +49 -41
- data/ext/oxt/backtrace.hpp +1 -1
- data/ext/oxt/detail/backtrace_disabled.hpp +1 -1
- data/ext/oxt/detail/backtrace_enabled.hpp +16 -15
- data/ext/oxt/detail/spin_lock_darwin.hpp +69 -0
- data/ext/oxt/detail/spin_lock_gcc_x86.hpp +3 -4
- data/ext/oxt/detail/spin_lock_portable.hpp +1 -1
- data/ext/oxt/detail/spin_lock_pthreads.hpp +1 -1
- data/ext/oxt/detail/tracable_exception_disabled.hpp +1 -1
- data/ext/oxt/detail/tracable_exception_enabled.hpp +1 -1
- data/ext/oxt/dynamic_thread_group.hpp +195 -0
- data/ext/oxt/macros.hpp +1 -1
- data/ext/oxt/spin_lock.hpp +4 -2
- data/ext/oxt/system_calls.cpp +129 -13
- data/ext/oxt/system_calls.hpp +16 -2
- data/ext/oxt/thread.cpp +1 -1
- data/ext/oxt/thread.hpp +49 -14
- data/ext/oxt/tracable_exception.cpp +5 -5
- data/ext/oxt/tracable_exception.hpp +1 -1
- data/ext/phusion_passenger/extconf.rb +7 -2
- data/ext/phusion_passenger/native_support.c +733 -33
- data/{bin → helper-scripts}/passenger-spawn-server +50 -12
- data/helper-scripts/prespawn +63 -0
- data/lib/phusion_passenger.rb +113 -0
- data/lib/phusion_passenger/abstract_installer.rb +50 -12
- data/lib/phusion_passenger/abstract_request_handler.rb +432 -171
- data/lib/phusion_passenger/abstract_server.rb +125 -122
- data/lib/phusion_passenger/abstract_server_collection.rb +51 -22
- data/lib/phusion_passenger/admin_tools.rb +1 -1
- data/lib/phusion_passenger/admin_tools/memory_stats.rb +299 -0
- data/lib/phusion_passenger/admin_tools/server_instance.rb +334 -0
- data/lib/phusion_passenger/analytics_logger.rb +342 -0
- data/lib/phusion_passenger/{application.rb → app_process.rb} +73 -24
- data/lib/phusion_passenger/classic_rails/application_spawner.rb +344 -0
- data/lib/phusion_passenger/{railz → classic_rails}/cgi_fixed.rb +2 -2
- data/lib/phusion_passenger/{railz → classic_rails}/framework_spawner.rb +75 -98
- data/lib/phusion_passenger/{railz → classic_rails}/request_handler.rb +8 -6
- data/lib/phusion_passenger/classic_rails_extensions/analytics_logging/ac_base_extension.rb +65 -0
- data/lib/phusion_passenger/classic_rails_extensions/analytics_logging/ac_benchmarking_extension.rb +48 -0
- data/lib/phusion_passenger/classic_rails_extensions/analytics_logging/ac_rescue_extension.rb +59 -0
- data/lib/phusion_passenger/classic_rails_extensions/analytics_logging/ar_abstract_adapter_extension.rb +54 -0
- data/lib/phusion_passenger/classic_rails_extensions/analytics_logging/as_cache_extension.rb +130 -0
- data/lib/phusion_passenger/classic_rails_extensions/analytics_logging/av_benchmark_helper_extension.rb +47 -0
- data/lib/phusion_passenger/classic_rails_extensions/init.rb +123 -0
- data/lib/phusion_passenger/console_text_template.rb +1 -1
- data/lib/phusion_passenger/constants.rb +9 -5
- data/lib/phusion_passenger/debug_logging.rb +104 -0
- data/lib/phusion_passenger/dependencies.rb +187 -4
- data/lib/phusion_passenger/exceptions.rb +4 -4
- data/lib/phusion_passenger/html_template.rb +6 -8
- data/lib/phusion_passenger/message_channel.rb +137 -21
- data/lib/phusion_passenger/message_client.rb +173 -0
- data/lib/phusion_passenger/native_support.rb +108 -0
- data/lib/phusion_passenger/packaging.rb +82 -13
- data/lib/phusion_passenger/platform_info.rb +84 -475
- data/lib/phusion_passenger/platform_info/apache.rb +329 -0
- data/lib/phusion_passenger/platform_info/binary_compatibility.rb +187 -0
- data/lib/phusion_passenger/platform_info/compiler.rb +154 -0
- data/lib/phusion_passenger/{events.rb → platform_info/curl.rb} +26 -23
- data/lib/phusion_passenger/platform_info/documentation_tools.rb +35 -0
- data/lib/phusion_passenger/platform_info/linux.rb +77 -0
- data/lib/phusion_passenger/platform_info/operating_system.rb +51 -0
- data/lib/phusion_passenger/platform_info/ruby.rb +198 -0
- data/lib/phusion_passenger/platform_info/zlib.rb +38 -0
- data/lib/phusion_passenger/plugin.rb +96 -0
- data/lib/phusion_passenger/public_api.rb +112 -0
- data/lib/phusion_passenger/rack/application_spawner.rb +146 -71
- data/lib/phusion_passenger/rack/request_handler.rb +36 -13
- data/lib/phusion_passenger/rails3_extensions/init.rb +204 -0
- data/lib/phusion_passenger/simple_benchmarking.rb +1 -1
- data/lib/phusion_passenger/spawn_manager.rb +137 -141
- data/lib/phusion_passenger/standalone/app_finder.rb +153 -0
- data/lib/phusion_passenger/standalone/command.rb +237 -0
- data/lib/phusion_passenger/standalone/config_file.rb +119 -0
- data/lib/phusion_passenger/standalone/help_command.rb +57 -0
- data/lib/phusion_passenger/standalone/main.rb +101 -0
- data/lib/phusion_passenger/standalone/package_runtime_command.rb +92 -0
- data/lib/phusion_passenger/standalone/runtime_installer.rb +466 -0
- data/lib/phusion_passenger/standalone/start_command.rb +510 -0
- data/lib/phusion_passenger/standalone/status_command.rb +62 -0
- data/lib/phusion_passenger/standalone/stop_command.rb +74 -0
- data/lib/phusion_passenger/standalone/utils.rb +42 -0
- data/lib/phusion_passenger/standalone/version_command.rb +42 -0
- data/lib/phusion_passenger/templates/framework_init_error.html.erb +1 -1
- data/lib/phusion_passenger/templates/standalone/cannot_write_to_dir.txt.erb +11 -0
- data/lib/phusion_passenger/templates/standalone/config.erb +69 -0
- data/lib/phusion_passenger/templates/standalone/possible_solutions_for_download_and_extraction_problems.txt.erb +17 -0
- data/lib/phusion_passenger/templates/standalone/run_installer_as_root.txt.erb +8 -0
- data/lib/phusion_passenger/templates/standalone/welcome.txt.erb +8 -0
- data/lib/phusion_passenger/templates/standalone_default_root/index.html +1 -0
- data/lib/phusion_passenger/templates/version_not_found.html.erb +2 -2
- data/lib/phusion_passenger/utils.rb +476 -125
- data/lib/phusion_passenger/utils/file_system_watcher.rb +186 -0
- data/lib/phusion_passenger/utils/hosts_file_parser.rb +130 -0
- data/lib/phusion_passenger/utils/tmpdir.rb +70 -0
- data/lib/phusion_passenger/utils/unseekable_socket.rb +196 -0
- data/lib/phusion_passenger/wsgi/application_spawner.rb +24 -20
- data/lib/phusion_passenger/wsgi/request_handler.py +1 -1
- data/misc/copy_boost_headers.rb +36 -9
- data/misc/find_owner_pipe_leaks.rb +1 -1
- data/misc/render_error_pages.rb +1 -1
- data/misc/union_station_gateway.crt +32 -0
- data/test/config.yml.example +24 -13
- data/test/cxx/ApplicationPool_PoolTest.cpp +33 -0
- data/test/cxx/ApplicationPool_PoolTestCases.cpp +1029 -0
- data/test/cxx/ApplicationPool_ServerTest.cpp +308 -0
- data/test/cxx/ApplicationPool_Server_PoolTest.cpp +80 -0
- data/test/{Base64Test.cpp → cxx/Base64Test.cpp} +4 -2
- data/test/{CachedFileStatTest.cpp → cxx/CachedFileStatTest.cpp} +3 -3
- data/test/{CxxTestMain.cpp → cxx/CxxTestMain.cpp} +6 -27
- data/test/cxx/EventedClientTest.cpp +386 -0
- data/test/{FileChangeCheckerTest.cpp → cxx/FileChangeCheckerTest.cpp} +3 -5
- data/test/cxx/FileDescriptorTest.cpp +69 -0
- data/test/{HttpStatusExtractorTest.cpp → cxx/HttpStatusExtractorTest.cpp} +1 -1
- data/test/cxx/IOUtilsTest.cpp +398 -0
- data/test/cxx/LoggingTest.cpp +914 -0
- data/test/cxx/MessageChannelTest.cpp +672 -0
- data/test/cxx/MessageReadersWritersTest.cpp +574 -0
- data/test/cxx/MessageServerTest.cpp +383 -0
- data/test/{PoolOptionsTest.cpp → cxx/PoolOptionsTest.cpp} +2 -3
- data/test/{ScgiRequestParserTest.cpp → cxx/ScgiRequestParserTest.cpp} +53 -1
- data/test/cxx/ServerInstanceDirTest.cpp +186 -0
- data/test/cxx/SpawnManagerTest.cpp +161 -0
- data/test/cxx/StaticStringTest.cpp +86 -0
- data/test/{SystemTimeTest.cpp → cxx/SystemTimeTest.cpp} +2 -2
- data/test/cxx/TestSupport.cpp +166 -0
- data/test/cxx/TestSupport.h +254 -0
- data/test/cxx/UtilsTest.cpp +521 -0
- data/test/cxx/VariantMapTest.cpp +179 -0
- data/test/integration_tests/apache2_tests.rb +198 -127
- data/test/integration_tests/cgi_environment_spec.rb +26 -0
- data/test/integration_tests/mycook_spec.rb +2 -28
- data/test/integration_tests/nginx_tests.rb +125 -16
- data/test/integration_tests/spec_helper.rb +19 -0
- data/test/oxt/backtrace_test.cpp +19 -59
- data/test/oxt/counter.hpp +55 -0
- data/test/oxt/dynamic_thread_group_test.cpp +131 -0
- data/test/oxt/oxt_test_main.cpp +2 -2
- data/test/oxt/spin_lock_test.cpp +59 -0
- data/test/oxt/syscall_interruption_test.cpp +1 -1
- data/test/ruby/abstract_request_handler_spec.rb +346 -25
- data/test/ruby/abstract_server_collection_spec.rb +4 -3
- data/test/ruby/abstract_server_spec.rb +37 -27
- data/test/ruby/admin_tools_spec.rb +362 -0
- data/test/ruby/analytics_logger_spec.rb +253 -0
- data/test/ruby/{application_spec.rb → app_process_spec.rb} +14 -14
- data/test/ruby/classic_rails/application_spawner_spec.rb +89 -0
- data/test/ruby/classic_rails/framework_spawner_spec.rb +92 -0
- data/test/ruby/debug_logging_spec.rb +141 -0
- data/test/ruby/message_channel_spec.rb +51 -25
- data/test/ruby/rack/application_spawner_spec.rb +99 -82
- data/test/ruby/shared/abstract_server_spec.rb +23 -0
- data/test/ruby/shared/rails/analytics_logging_extensions_spec.rb +375 -0
- data/test/ruby/shared/spawners/classic_rails/framework_spawner_spec.rb +38 -0
- data/test/ruby/shared/spawners/classic_rails/lack_of_rails_gem_version_spec.rb +19 -0
- data/test/ruby/shared/spawners/classic_rails/spawner_spec.rb +15 -0
- data/test/ruby/shared/spawners/non_preloading_spawner_spec.rb +27 -0
- data/test/ruby/shared/spawners/preloading_spawner_spec.rb +29 -0
- data/test/ruby/shared/spawners/reload_all_spec.rb +36 -0
- data/test/ruby/shared/spawners/reload_single_spec.rb +52 -0
- data/test/ruby/shared/spawners/spawn_server_spec.rb +28 -0
- data/test/ruby/shared/spawners/spawner_spec.rb +273 -0
- data/test/ruby/shared/utils/pseudo_io_spec.rb +60 -0
- data/test/ruby/spawn_manager_spec.rb +104 -175
- data/test/ruby/spec_helper.rb +104 -0
- data/test/ruby/utils/file_system_watcher_spec.rb +221 -0
- data/test/ruby/utils/hosts_file_parser.rb +258 -0
- data/test/ruby/utils/unseekable_socket_spec.rb +66 -0
- data/test/ruby/utils_spec.rb +410 -59
- data/test/ruby/wsgi/application_spawner_spec.rb +16 -20
- data/test/stub/apache2/httpd.conf.erb +11 -6
- data/test/stub/message_channel.rb +3 -1
- data/test/stub/message_channel_2.rb +3 -1
- data/test/stub/message_channel_3.rb +5 -3
- data/test/stub/nginx/nginx.conf.erb +3 -2
- data/test/stub/rails_apps/1.2/empty/Rakefile +10 -0
- data/test/stub/rails_apps/1.2/empty/app/controllers/application.rb +7 -0
- data/test/stub/rails_apps/{foobar → 1.2/empty}/app/helpers/application_helper.rb +0 -0
- data/test/stub/rails_apps/{mycook → 1.2/empty}/config/boot.rb +3 -3
- data/test/stub/rails_apps/1.2/empty/config/database.yml +31 -0
- data/test/stub/rails_apps/1.2/empty/config/environment.rb +66 -0
- data/test/stub/rails_apps/1.2/empty/config/environments/development.rb +21 -0
- data/test/stub/rails_apps/{foobar → 1.2/empty}/config/environments/production.rb +0 -0
- data/test/stub/rails_apps/1.2/empty/config/environments/staging.rb +18 -0
- data/test/stub/rails_apps/1.2/empty/config/environments/test.rb +19 -0
- data/test/stub/rails_apps/1.2/empty/config/routes.rb +23 -0
- data/test/stub/rails_apps/1.2/empty/doc/README_FOR_APP +2 -0
- data/test/stub/rails_apps/{mycook → 1.2/empty}/public/404.html +0 -0
- data/test/stub/rails_apps/1.2/empty/public/500.html +30 -0
- data/test/stub/rails_apps/1.2/empty/public/dispatch.cgi +10 -0
- data/test/stub/rails_apps/1.2/empty/public/dispatch.fcgi +24 -0
- data/test/stub/rails_apps/1.2/empty/public/dispatch.rb +10 -0
- data/test/stub/rails_apps/{mycook → 1.2/empty}/public/favicon.ico +0 -0
- data/test/stub/rails_apps/{mycook → 1.2/empty}/public/images/rails.png +0 -0
- data/test/stub/rails_apps/1.2/empty/public/robots.txt +1 -0
- data/test/stub/rails_apps/1.2/empty/script/about +3 -0
- data/test/stub/rails_apps/1.2/empty/script/breakpointer +3 -0
- data/test/stub/rails_apps/1.2/empty/script/console +3 -0
- data/test/stub/rails_apps/1.2/empty/script/destroy +3 -0
- data/test/stub/rails_apps/1.2/empty/script/generate +3 -0
- data/test/stub/rails_apps/1.2/empty/script/performance/benchmarker +3 -0
- data/test/stub/rails_apps/1.2/empty/script/performance/profiler +3 -0
- data/test/stub/rails_apps/1.2/empty/script/plugin +3 -0
- data/test/stub/rails_apps/1.2/empty/script/process/inspector +3 -0
- data/test/stub/rails_apps/1.2/empty/script/process/reaper +3 -0
- data/test/stub/rails_apps/1.2/empty/script/process/spawner +3 -0
- data/test/stub/rails_apps/1.2/empty/script/runner +3 -0
- data/test/stub/rails_apps/1.2/empty/script/server +3 -0
- data/test/stub/rails_apps/1.2/empty/test/test_helper.rb +28 -0
- data/test/stub/rails_apps/2.0/empty/Rakefile +10 -0
- data/test/stub/rails_apps/2.0/empty/app/controllers/application.rb +10 -0
- data/test/stub/rails_apps/{mycook → 2.0/empty}/app/helpers/application_helper.rb +0 -0
- data/test/stub/rails_apps/{foobar → 2.0/empty}/config/boot.rb +3 -3
- data/test/stub/rails_apps/2.0/empty/config/database.yml +31 -0
- data/test/stub/rails_apps/2.0/empty/config/environment.rb +59 -0
- data/test/stub/rails_apps/{mycook → 2.0/empty}/config/environments/development.rb +1 -1
- data/test/stub/rails_apps/2.0/empty/config/environments/production.rb +18 -0
- data/test/stub/rails_apps/2.0/empty/config/environments/staging.rb +18 -0
- data/test/stub/rails_apps/2.0/empty/config/environments/test.rb +22 -0
- data/test/stub/rails_apps/{foobar → 2.0/empty}/config/initializers/inflections.rb +0 -0
- data/test/stub/rails_apps/{foobar → 2.0/empty}/config/initializers/mime_types.rb +0 -0
- data/test/stub/rails_apps/{foobar → 2.0/empty}/config/routes.rb +0 -0
- data/test/stub/rails_apps/2.0/empty/doc/README_FOR_APP +2 -0
- data/test/stub/rails_apps/2.0/empty/public/404.html +30 -0
- data/test/stub/rails_apps/{mycook → 2.0/empty}/public/422.html +0 -0
- data/test/stub/rails_apps/{mycook → 2.0/empty}/public/500.html +0 -0
- data/test/stub/rails_apps/2.0/empty/public/dispatch.cgi +10 -0
- data/test/stub/rails_apps/2.0/empty/public/dispatch.fcgi +24 -0
- data/test/stub/rails_apps/2.0/empty/public/dispatch.rb +10 -0
- data/test/stub/rails_apps/2.0/empty/public/favicon.ico +0 -0
- data/test/stub/rails_apps/2.0/empty/public/images/rails.png +0 -0
- data/test/stub/rails_apps/{mycook → 2.0/empty}/public/robots.txt +0 -0
- data/test/stub/rails_apps/2.0/empty/script/about +3 -0
- data/test/stub/rails_apps/2.0/empty/script/console +3 -0
- data/test/stub/rails_apps/2.0/empty/script/destroy +3 -0
- data/test/stub/rails_apps/2.0/empty/script/generate +3 -0
- data/test/stub/rails_apps/2.0/empty/script/performance/benchmarker +3 -0
- data/test/stub/rails_apps/2.0/empty/script/performance/profiler +3 -0
- data/test/stub/rails_apps/2.0/empty/script/performance/request +3 -0
- data/test/stub/rails_apps/2.0/empty/script/plugin +3 -0
- data/test/stub/rails_apps/2.0/empty/script/process/inspector +3 -0
- data/test/stub/rails_apps/2.0/empty/script/process/reaper +3 -0
- data/test/stub/rails_apps/2.0/empty/script/process/spawner +3 -0
- data/test/stub/rails_apps/2.0/empty/script/runner +3 -0
- data/test/stub/rails_apps/2.0/empty/script/server +3 -0
- data/test/stub/rails_apps/2.0/empty/test/test_helper.rb +38 -0
- data/test/stub/rails_apps/2.2/empty/Rakefile +10 -0
- data/test/stub/rails_apps/2.2/empty/app/controllers/application.rb +15 -0
- data/test/stub/rails_apps/2.2/empty/app/helpers/application_helper.rb +3 -0
- data/test/stub/rails_apps/2.2/empty/config/boot.rb +109 -0
- data/test/stub/rails_apps/2.2/empty/config/database.yml +31 -0
- data/test/stub/rails_apps/2.2/empty/config/environment.rb +75 -0
- data/test/stub/rails_apps/{foobar → 2.2/empty}/config/environments/development.rb +0 -0
- data/test/stub/rails_apps/2.2/empty/config/environments/production.rb +24 -0
- data/test/stub/rails_apps/2.2/empty/config/environments/staging.rb +24 -0
- data/test/stub/rails_apps/2.2/empty/config/environments/test.rb +22 -0
- data/test/stub/rails_apps/2.2/empty/config/initializers/inflections.rb +10 -0
- data/test/stub/rails_apps/{mycook → 2.2/empty}/config/initializers/mime_types.rb +0 -0
- data/test/stub/rails_apps/2.2/empty/config/initializers/new_rails_defaults.rb +17 -0
- data/test/stub/rails_apps/2.2/empty/config/locales/en.yml +5 -0
- data/test/stub/rails_apps/2.2/empty/config/routes.rb +43 -0
- data/test/stub/rails_apps/2.2/empty/doc/README_FOR_APP +5 -0
- data/test/stub/rails_apps/2.2/empty/public/404.html +30 -0
- data/test/stub/rails_apps/2.2/empty/public/422.html +30 -0
- data/test/stub/rails_apps/2.2/empty/public/500.html +33 -0
- data/test/stub/rails_apps/2.2/empty/public/dispatch.cgi +10 -0
- data/test/stub/rails_apps/2.2/empty/public/dispatch.fcgi +24 -0
- data/test/stub/rails_apps/2.2/empty/public/dispatch.rb +10 -0
- data/test/stub/rails_apps/2.2/empty/public/favicon.ico +0 -0
- data/test/stub/rails_apps/2.2/empty/public/images/rails.png +0 -0
- data/test/stub/rails_apps/2.2/empty/public/robots.txt +5 -0
- data/test/stub/rails_apps/2.2/empty/script/about +4 -0
- data/test/stub/rails_apps/2.2/empty/script/console +3 -0
- data/test/stub/rails_apps/2.2/empty/script/dbconsole +3 -0
- data/test/stub/rails_apps/2.2/empty/script/destroy +3 -0
- data/test/stub/rails_apps/2.2/empty/script/generate +3 -0
- data/test/stub/rails_apps/2.2/empty/script/performance/benchmarker +3 -0
- data/test/stub/rails_apps/2.2/empty/script/performance/profiler +3 -0
- data/test/stub/rails_apps/2.2/empty/script/performance/request +3 -0
- data/test/stub/rails_apps/2.2/empty/script/plugin +3 -0
- data/test/stub/rails_apps/2.2/empty/script/process/inspector +3 -0
- data/test/stub/rails_apps/2.2/empty/script/process/reaper +3 -0
- data/test/stub/rails_apps/2.2/empty/script/process/spawner +3 -0
- data/test/stub/rails_apps/2.2/empty/script/runner +3 -0
- data/test/stub/rails_apps/2.2/empty/script/server +3 -0
- data/test/stub/rails_apps/2.2/empty/test/performance/browsing_test.rb +9 -0
- data/test/stub/rails_apps/2.2/empty/test/test_helper.rb +38 -0
- data/test/stub/rails_apps/2.3/empty/Rakefile +10 -0
- data/test/stub/rails_apps/2.3/empty/app/controllers/application_controller.rb +10 -0
- data/test/stub/rails_apps/2.3/empty/app/helpers/application_helper.rb +3 -0
- data/test/stub/rails_apps/2.3/empty/config/boot.rb +110 -0
- data/test/stub/rails_apps/2.3/empty/config/database.yml +31 -0
- data/test/stub/rails_apps/2.3/empty/config/environment.rb +41 -0
- data/test/stub/rails_apps/2.3/empty/config/environments/development.rb +17 -0
- data/test/stub/rails_apps/2.3/empty/config/environments/production.rb +28 -0
- data/test/stub/rails_apps/2.3/empty/config/environments/staging.rb +28 -0
- data/test/stub/rails_apps/2.3/empty/config/environments/test.rb +28 -0
- data/test/stub/rails_apps/2.3/empty/config/initializers/backtrace_silencers.rb +7 -0
- data/test/stub/rails_apps/2.3/empty/config/initializers/inflections.rb +10 -0
- data/test/stub/rails_apps/2.3/empty/config/initializers/mime_types.rb +5 -0
- data/test/stub/rails_apps/2.3/empty/config/initializers/new_rails_defaults.rb +21 -0
- data/test/stub/rails_apps/2.3/empty/config/initializers/session_store.rb +15 -0
- data/test/stub/rails_apps/2.3/empty/config/locales/en.yml +5 -0
- data/test/stub/rails_apps/2.3/empty/config/routes.rb +43 -0
- data/test/stub/rails_apps/2.3/empty/db/seeds.rb +7 -0
- data/test/stub/rails_apps/2.3/empty/doc/README_FOR_APP +2 -0
- data/test/stub/rails_apps/2.3/empty/public/404.html +30 -0
- data/test/stub/rails_apps/2.3/empty/public/422.html +30 -0
- data/test/stub/rails_apps/2.3/empty/public/500.html +30 -0
- data/test/stub/rails_apps/2.3/empty/public/favicon.ico +0 -0
- data/test/stub/rails_apps/2.3/empty/public/images/rails.png +0 -0
- data/test/stub/rails_apps/2.3/empty/public/robots.txt +5 -0
- data/test/stub/rails_apps/2.3/empty/script/about +4 -0
- data/test/stub/rails_apps/2.3/empty/script/console +3 -0
- data/test/stub/rails_apps/2.3/empty/script/dbconsole +3 -0
- data/test/stub/rails_apps/2.3/empty/script/destroy +3 -0
- data/test/stub/rails_apps/2.3/empty/script/generate +3 -0
- data/test/stub/rails_apps/2.3/empty/script/performance/benchmarker +3 -0
- data/test/stub/rails_apps/2.3/empty/script/performance/profiler +3 -0
- data/test/stub/rails_apps/2.3/empty/script/plugin +3 -0
- data/test/stub/rails_apps/2.3/empty/script/runner +3 -0
- data/test/stub/rails_apps/2.3/empty/script/server +3 -0
- data/test/stub/rails_apps/2.3/empty/test/performance/browsing_test.rb +9 -0
- data/test/stub/rails_apps/2.3/empty/test/test_helper.rb +38 -0
- data/test/stub/rails_apps/2.3/foobar/Rakefile +10 -0
- data/test/stub/rails_apps/{foobar/app/controllers/application.rb → 2.3/foobar/app/controllers/application_controller.rb} +0 -0
- data/test/stub/rails_apps/{foobar → 2.3/foobar}/app/controllers/bar_controller_1.rb +0 -0
- data/test/stub/rails_apps/{foobar → 2.3/foobar}/app/controllers/bar_controller_2.rb +0 -0
- data/test/stub/rails_apps/{foobar → 2.3/foobar}/app/controllers/foo_controller.rb +0 -0
- data/test/stub/rails_apps/2.3/foobar/app/helpers/application_helper.rb +3 -0
- data/test/stub/rails_apps/2.3/foobar/config/boot.rb +110 -0
- data/test/stub/rails_apps/{foobar → 2.3/foobar}/config/database.yml +0 -0
- data/test/stub/rails_apps/{foobar → 2.3/foobar}/config/environment.rb +1 -1
- data/test/stub/rails_apps/2.3/foobar/config/environments/development.rb +17 -0
- data/test/stub/rails_apps/2.3/foobar/config/environments/production.rb +18 -0
- data/test/stub/rails_apps/2.3/foobar/config/environments/staging.rb +18 -0
- data/test/stub/rails_apps/{mycook → 2.3/foobar}/config/initializers/inflections.rb +0 -0
- data/test/stub/rails_apps/2.3/foobar/config/initializers/mime_types.rb +5 -0
- data/test/stub/rails_apps/2.3/foobar/config/routes.rb +35 -0
- data/test/stub/rails_apps/2.3/foobar/script/about +3 -0
- data/test/stub/rails_apps/2.3/foobar/script/console +3 -0
- data/test/stub/rails_apps/2.3/foobar/script/dbconsole +3 -0
- data/test/stub/rails_apps/2.3/foobar/script/destroy +3 -0
- data/test/stub/rails_apps/2.3/foobar/script/generate +3 -0
- data/test/stub/rails_apps/2.3/foobar/script/performance/benchmarker +3 -0
- data/test/stub/rails_apps/2.3/foobar/script/performance/profiler +3 -0
- data/test/stub/rails_apps/2.3/foobar/script/performance/request +3 -0
- data/test/stub/rails_apps/2.3/foobar/script/plugin +3 -0
- data/test/stub/rails_apps/2.3/foobar/script/process/inspector +3 -0
- data/test/stub/rails_apps/2.3/foobar/script/process/reaper +3 -0
- data/test/stub/rails_apps/2.3/foobar/script/process/spawner +3 -0
- data/test/stub/rails_apps/2.3/foobar/script/runner +3 -0
- data/test/stub/rails_apps/2.3/foobar/script/server +3 -0
- data/test/stub/rails_apps/2.3/mycook/Rakefile +10 -0
- data/test/stub/rails_apps/{mycook/app/controllers/application.rb → 2.3/mycook/app/controllers/application_controller.rb} +0 -0
- data/test/stub/rails_apps/{mycook → 2.3/mycook}/app/controllers/recipes_controller.rb +0 -0
- data/test/stub/rails_apps/{mycook → 2.3/mycook}/app/controllers/uploads_controller.rb +0 -0
- data/test/stub/rails_apps/{mycook → 2.3/mycook}/app/controllers/welcome_controller.rb +0 -0
- data/test/stub/rails_apps/2.3/mycook/app/helpers/application_helper.rb +3 -0
- data/test/stub/rails_apps/{mycook → 2.3/mycook}/app/views/layouts/default.rhtml +0 -0
- data/test/stub/rails_apps/{mycook → 2.3/mycook}/app/views/recipes/create.rhtml +0 -0
- data/test/stub/rails_apps/{mycook → 2.3/mycook}/app/views/recipes/index.rhtml +0 -0
- data/test/stub/rails_apps/{mycook → 2.3/mycook}/app/views/recipes/new.rhtml +0 -0
- data/test/stub/rails_apps/{mycook → 2.3/mycook}/app/views/uploads/index.rhtml +0 -0
- data/test/stub/rails_apps/{mycook → 2.3/mycook}/app/views/uploads/new.html.erb +0 -0
- data/test/stub/rails_apps/{mycook → 2.3/mycook}/app/views/welcome/cached.rhtml +0 -0
- data/test/stub/rails_apps/{mycook → 2.3/mycook}/app/views/welcome/index.rhtml +0 -0
- data/test/stub/rails_apps/2.3/mycook/config/boot.rb +110 -0
- data/test/stub/rails_apps/{mycook → 2.3/mycook}/config/database.yml +0 -0
- data/test/stub/rails_apps/{mycook → 2.3/mycook}/config/environment.rb +1 -1
- data/test/stub/rails_apps/2.3/mycook/config/environments/development.rb +18 -0
- data/test/stub/rails_apps/{mycook → 2.3/mycook}/config/environments/production.rb +0 -0
- data/test/stub/rails_apps/2.3/mycook/config/initializers/inflections.rb +10 -0
- data/test/stub/rails_apps/2.3/mycook/config/initializers/mime_types.rb +5 -0
- data/test/stub/rails_apps/{mycook → 2.3/mycook}/config/routes.rb +0 -0
- data/test/stub/rails_apps/{mycook → 2.3/mycook}/log/useless.txt +0 -0
- data/test/stub/rails_apps/2.3/mycook/public/404.html +30 -0
- data/test/stub/rails_apps/2.3/mycook/public/422.html +30 -0
- data/test/stub/rails_apps/2.3/mycook/public/500.html +30 -0
- data/test/stub/rails_apps/{mycook → 2.3/mycook}/public/dispatch.cgi +0 -0
- data/test/stub/rails_apps/{mycook → 2.3/mycook}/public/dispatch.fcgi +0 -0
- data/test/stub/rails_apps/{mycook → 2.3/mycook}/public/dispatch.rb +1 -1
- data/test/stub/rails_apps/2.3/mycook/public/favicon.ico +0 -0
- data/test/stub/rails_apps/{mycook → 2.3/mycook}/public/images/angrywizard.gif +0 -0
- data/test/stub/rails_apps/{mycook → 2.3/mycook}/public/images/cookbook.gif +0 -0
- data/test/stub/rails_apps/{mycook → 2.3/mycook}/public/images/header.png +0 -0
- data/test/stub/rails_apps/2.3/mycook/public/images/rails.png +0 -0
- data/test/stub/rails_apps/{mycook → 2.3/mycook}/public/javascripts/application.js +0 -0
- data/test/stub/rails_apps/{mycook → 2.3/mycook}/public/javascripts/controls.js +73 -73
- data/test/stub/rails_apps/{mycook → 2.3/mycook}/public/javascripts/dragdrop.js +166 -165
- data/test/stub/rails_apps/{mycook → 2.3/mycook}/public/javascripts/effects.js +174 -166
- data/test/stub/rails_apps/{mycook → 2.3/mycook}/public/javascripts/prototype.js +362 -267
- data/test/stub/rails_apps/2.3/mycook/public/robots.txt +5 -0
- data/test/stub/rails_apps/{mycook → 2.3/mycook}/public/uploads.html +0 -0
- data/test/stub/rails_apps/{mycook → 2.3/mycook}/public/welcome/cached.html +0 -0
- data/test/stub/rails_apps/2.3/mycook/script/about +3 -0
- data/test/stub/rails_apps/2.3/mycook/script/console +3 -0
- data/test/stub/rails_apps/2.3/mycook/script/dbconsole +3 -0
- data/test/stub/rails_apps/2.3/mycook/script/destroy +3 -0
- data/test/stub/rails_apps/2.3/mycook/script/generate +3 -0
- data/test/stub/rails_apps/2.3/mycook/script/performance/benchmarker +3 -0
- data/test/stub/rails_apps/2.3/mycook/script/performance/profiler +3 -0
- data/test/stub/rails_apps/2.3/mycook/script/performance/request +3 -0
- data/test/stub/rails_apps/2.3/mycook/script/plugin +3 -0
- data/test/stub/rails_apps/2.3/mycook/script/process/inspector +3 -0
- data/test/stub/rails_apps/2.3/mycook/script/process/reaper +3 -0
- data/test/stub/rails_apps/2.3/mycook/script/process/spawner +3 -0
- data/test/stub/rails_apps/2.3/mycook/script/runner +3 -0
- data/test/stub/rails_apps/2.3/mycook/script/server +3 -0
- data/test/stub/rails_apps/{mycook → 2.3/mycook}/sites/some.site/public/uploads.html +0 -0
- data/test/stub/rails_apps/{mycook → 2.3/mycook}/sites/some.site/public/welcome/cached.html +0 -0
- data/test/stub/rails_apps/{mycook → 2.3/mycook}/tmp/cache/useless.txt +0 -0
- data/test/stub/rails_apps/{mycook → 2.3/mycook}/tmp/pids/useless.txt +0 -0
- data/test/stub/rails_apps/{mycook → 2.3/mycook}/tmp/sessions/useless.txt +0 -0
- data/test/stub/rails_apps/{mycook → 2.3/mycook}/tmp/sockets/useless.txt +0 -0
- data/test/stub/rails_apps/3.0/empty/Gemfile +22 -0
- data/test/stub/rails_apps/3.0/empty/Rakefile +10 -0
- data/test/stub/rails_apps/3.0/empty/app/controllers/application_controller.rb +4 -0
- data/test/stub/rails_apps/3.0/empty/app/helpers/application_helper.rb +2 -0
- data/test/stub/rails_apps/3.0/empty/app/views/layouts/application.html.erb +14 -0
- data/test/stub/rails_apps/3.0/empty/config.ru +4 -0
- data/test/stub/rails_apps/3.0/empty/config/application.rb +48 -0
- data/test/stub/rails_apps/3.0/empty/config/boot.rb +13 -0
- data/test/stub/rails_apps/3.0/empty/config/database.yml +22 -0
- data/test/stub/rails_apps/3.0/empty/config/environment.rb +5 -0
- data/test/stub/rails_apps/3.0/empty/config/environments/development.rb +19 -0
- data/test/stub/rails_apps/3.0/empty/config/environments/production.rb +48 -0
- data/test/stub/rails_apps/3.0/empty/config/environments/test.rb +32 -0
- data/test/stub/rails_apps/3.0/empty/config/initializers/backtrace_silencers.rb +7 -0
- data/test/stub/rails_apps/3.0/empty/config/initializers/inflections.rb +10 -0
- data/test/stub/rails_apps/3.0/empty/config/initializers/mime_types.rb +5 -0
- data/test/stub/rails_apps/3.0/empty/config/initializers/passenger.rb +1 -0
- data/test/stub/rails_apps/3.0/empty/config/initializers/secret_token.rb +7 -0
- data/test/stub/rails_apps/3.0/empty/config/initializers/session_store.rb +8 -0
- data/test/stub/rails_apps/3.0/empty/config/locales/en.yml +5 -0
- data/test/stub/rails_apps/3.0/empty/config/routes.rb +58 -0
- data/test/stub/rails_apps/3.0/empty/db/seeds.rb +7 -0
- data/test/stub/rails_apps/3.0/empty/doc/README_FOR_APP +2 -0
- data/test/stub/rails_apps/3.0/empty/log/development.log +3 -0
- data/test/stub/rails_apps/3.0/empty/public/404.html +26 -0
- data/test/stub/rails_apps/3.0/empty/public/422.html +26 -0
- data/test/stub/rails_apps/3.0/empty/public/500.html +26 -0
- data/test/stub/rails_apps/3.0/empty/public/favicon.ico +0 -0
- data/test/stub/rails_apps/3.0/empty/public/index.html +279 -0
- data/test/stub/rails_apps/3.0/empty/public/robots.txt +5 -0
- data/test/stub/rails_apps/3.0/empty/script/rails +9 -0
- data/test/stub/rails_apps/3.0/empty/test/performance/browsing_test.rb +9 -0
- data/test/stub/rails_apps/3.0/empty/test/test_helper.rb +13 -0
- data/test/stub/spawn_server.rb +4 -2
- data/test/stub/vendor_rails/minimal/actionpack/lib/action_controller.rb +3 -0
- data/test/stub/vendor_rails/minimal/railties/lib/initializer.rb +7 -2
- data/test/support/apache2_controller.rb +10 -2
- data/test/support/nginx_controller.rb +3 -2
- data/test/support/test_helper.rb +282 -46
- data/test/{support → tut}/tut.h +6 -0
- data/test/{support → tut}/tut_reporter.h +0 -0
- metadata +824 -266
- data/benchmark/ApplicationPool.cpp +0 -52
- data/benchmark/accept_vs_socketpair_vs_named_pipes.rb +0 -126
- data/benchmark/dispatcher.rb +0 -42
- data/benchmark/overhead_of_password_checking.rb +0 -81
- data/benchmark/socket_connections_vs_persistent_pipe.rb +0 -99
- data/benchmark/unix_sockets_vs_pipes.rb +0 -83
- data/ext/boost/LICENSE.TXT +0 -23
- data/ext/boost/VERSION.TXT +0 -1
- data/ext/boost/detail/sp_counted_base.hpp +0 -81
- data/ext/boost/src/pthread/exceptions.cpp +0 -146
- data/ext/boost/src/win32/exceptions.cpp +0 -124
- data/ext/boost/src/win32/thread.cpp +0 -629
- data/ext/boost/src/win32/timeconv.inl +0 -130
- data/ext/boost/src/win32/tss_dll.cpp +0 -72
- data/ext/boost/src/win32/tss_pe.cpp +0 -269
- data/ext/boost/thread/pthread/thread.hpp +0 -339
- data/ext/boost/thread/pthread/tss.hpp +0 -103
- data/ext/common/Application.h +0 -511
- data/ext/common/ApplicationPoolServer.h +0 -794
- data/ext/common/ApplicationPoolServerExecutable.cpp +0 -743
- data/ext/common/ApplicationPoolStatusReporter.h +0 -336
- data/ext/common/DummySpawnManager.h +0 -108
- data/ext/common/StandardApplicationPool.h +0 -821
- data/ext/common/SystemTime.h +0 -88
- data/lib/phusion_passenger/admin_tools/control_process.rb +0 -150
- data/lib/phusion_passenger/railz/application_spawner.rb +0 -463
- data/lib/phusion_passenger/templates/invalid_app_root.html.erb +0 -9
- data/test/ApplicationPoolServerTest.cpp +0 -114
- data/test/ApplicationPoolServer_ApplicationPoolTest.cpp +0 -33
- data/test/ApplicationPoolTest.cpp +0 -599
- data/test/MessageChannelTest.cpp +0 -320
- data/test/SpawnManagerTest.cpp +0 -64
- data/test/StandardApplicationPoolTest.cpp +0 -27
- data/test/StaticStringTest.cpp +0 -51
- data/test/UtilsTest.cpp +0 -257
- data/test/ruby/rails/application_spawner_spec.rb +0 -159
- data/test/ruby/rails/framework_spawner_spec.rb +0 -133
- data/test/ruby/rails/minimal_spawner_spec.rb +0 -93
- data/test/ruby/rails/spawner_error_handling_spec.rb +0 -107
- data/test/ruby/rails/spawner_privilege_lowering_spec.rb +0 -97
- data/test/ruby/spawn_server_spec.rb +0 -26
- data/test/stub/MessageServer.dSYM/Contents/Info.plist +0 -25
- data/test/stub/MessageServer.dSYM/Contents/Resources/DWARF/MessageServer +0 -0
- data/test/support/Support.cpp +0 -84
- data/test/support/Support.h +0 -118
- data/test/support/config.rb +0 -38
- data/test/support/run_rspec_tests.rb +0 -10
@@ -0,0 +1,275 @@
|
|
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_ */
|
@@ -0,0 +1,1062 @@
|
|
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_ */
|