Browse Source

Merge branch 'master' into cleanup-metadata

Conflicts:
	frameworks/C/h2o/benchmark_config.json
	frameworks/Go/echo/benchmark_config.json
	frameworks/Go/fasthttp-mysql/benchmark_config.json
	frameworks/Go/fasthttp-postgresql/benchmark_config.json
	frameworks/Go/go-std-mongodb/benchmark_config.json
	frameworks/Go/go-std-postgresql/benchmark_config.json
	frameworks/Go/go-std/benchmark_config.json
	frameworks/Go/revel-jet/benchmark_config.json
	frameworks/Go/revel-qbs/benchmark_config.json
	frameworks/Go/revel/benchmark_config.json
	frameworks/Java/comsat-webactors/benchmark_config.json
	frameworks/Java/jlhttp/benchmark_config.json
	frameworks/PHP/cakephp/benchmark_config.json
	frameworks/PHP/clancats/benchmark_config.json
	frameworks/PHP/codeigniter/benchmark_config.json
	frameworks/PHP/cygnite/benchmark_config.json
	frameworks/PHP/fat-free/benchmark_config.json
	frameworks/PHP/fuel/benchmark_config.json
	frameworks/PHP/hhvm/benchmark_config.json
	frameworks/PHP/kohana/benchmark_config.json
	frameworks/PHP/laravel/benchmark_config.json
	frameworks/PHP/limonade/benchmark_config.json
	frameworks/PHP/lithium/benchmark_config.json
	frameworks/PHP/lumen/benchmark_config.json
	frameworks/PHP/micromvc/benchmark_config.json
	frameworks/PHP/phalcon-micro/benchmark_config.json
	frameworks/PHP/phalcon/benchmark_config.json
	frameworks/PHP/php/benchmark_config.json
	frameworks/PHP/phpixie/benchmark_config.json
	frameworks/PHP/phreeze/benchmark_config.json
	frameworks/PHP/pimf/benchmark_config.json
	frameworks/PHP/silex-orm/benchmark_config.json
	frameworks/PHP/silex/benchmark_config.json
	frameworks/PHP/slim/benchmark_config.json
	frameworks/PHP/symfony2-stripped/benchmark_config.json
	frameworks/PHP/symfony2/benchmark_config.json
	frameworks/PHP/yaf/benchmark_config.json
	frameworks/PHP/yii2/benchmark_config.json
	frameworks/PHP/zend/benchmark_config.json
	frameworks/PHP/zend1/benchmark_config.json
msmith-techempower 9 years ago
parent
commit
2a97b72c2d
100 changed files with 2469 additions and 477 deletions
  1. 14 12
      .travis.yml
  2. 5 2
      README.md
  3. 0 1
      benchmark.cfg.example
  4. 0 2
      config/create-postgres-database.sql
  5. 0 29
      config/create-postgres-old.sql
  6. 0 29
      config/create-postgres-upper-quote.sql
  7. 4 0
      config/create-postgres.sql
  8. 2 53
      config/create.sql
  9. 14 6
      config/php.ini
  10. 1 1
      config/travis_setup.sh
  11. 1 1
      deployment/vagrant-aws/setup_aws.py
  12. 1 1
      deployment/vagrant-common/custom_motd.sh
  13. 2 2
      deployment/vagrant-development/README.md
  14. 1 1
      deployment/vagrant-production/README.md
  15. 2 0
      frameworks/C++/cpoll_cppsp/.gitignore
  16. 29 0
      frameworks/C++/cutelyst/CMakeLists.txt
  17. 127 0
      frameworks/C++/cutelyst/benchmark_config.json
  18. 21 0
      frameworks/C++/cutelyst/config/config.ini
  19. 23 0
      frameworks/C++/cutelyst/config/config_socket.ini
  20. 48 0
      frameworks/C++/cutelyst/nginx.conf
  21. 22 0
      frameworks/C++/cutelyst/setup.sh
  22. 25 0
      frameworks/C++/cutelyst/setup_uwsgi_nginx.sh
  23. 20 0
      frameworks/C++/cutelyst/source_code
  24. 19 0
      frameworks/C++/cutelyst/src/CMakeLists.txt
  25. 78 0
      frameworks/C++/cutelyst/src/cutelyst-benchmarks.cpp
  26. 22 0
      frameworks/C++/cutelyst/src/cutelyst-benchmarks.h
  27. 74 0
      frameworks/C++/cutelyst/src/databaseupdatestest.cpp
  28. 26 0
      frameworks/C++/cutelyst/src/databaseupdatestest.h
  29. 90 0
      frameworks/C++/cutelyst/src/fortunetest.cpp
  30. 32 0
      frameworks/C++/cutelyst/src/fortunetest.h
  31. 17 0
      frameworks/C++/cutelyst/src/jsontest.cpp
  32. 19 0
      frameworks/C++/cutelyst/src/jsontest.h
  33. 60 0
      frameworks/C++/cutelyst/src/multipledatabasequeriestest.cpp
  34. 26 0
      frameworks/C++/cutelyst/src/multipledatabasequeriestest.h
  35. 13 0
      frameworks/C++/cutelyst/src/plaintexttest.cpp
  36. 19 0
      frameworks/C++/cutelyst/src/plaintexttest.h
  37. 37 0
      frameworks/C++/cutelyst/src/root.cpp
  38. 22 0
      frameworks/C++/cutelyst/src/root.h
  39. 47 0
      frameworks/C++/cutelyst/src/singledatabasequerytest.cpp
  40. 26 0
      frameworks/C++/cutelyst/src/singledatabasequerytest.h
  41. 1 0
      frameworks/C++/ffead-cpp/.gitignore
  42. 1 0
      frameworks/C++/poco/.gitignore
  43. 1 0
      frameworks/C++/silicon/.gitignore
  44. 50 4
      frameworks/C++/treefrog/benchmark_config.json
  45. 20 18
      frameworks/C++/treefrog/config/application.ini
  46. 3 3
      frameworks/C++/treefrog/config/mongodb.ini
  47. 1 1
      frameworks/C++/treefrog/controllers/controllers.pro
  48. 18 0
      frameworks/C++/treefrog/controllers/fortunecontroller.cpp
  49. 2 1
      frameworks/C++/treefrog/controllers/fortunecontroller.h
  50. 51 1
      frameworks/C++/treefrog/controllers/worldcontroller.cpp
  51. 7 0
      frameworks/C++/treefrog/controllers/worldcontroller.h
  52. 1 1
      frameworks/C++/treefrog/helpers/helpers.pro
  53. 104 0
      frameworks/C++/treefrog/models/mngfortune.cpp
  54. 51 0
      frameworks/C++/treefrog/models/mngfortune.h
  55. 105 0
      frameworks/C++/treefrog/models/mngworld.cpp
  56. 51 0
      frameworks/C++/treefrog/models/mngworld.h
  57. 9 3
      frameworks/C++/treefrog/models/models.pro
  58. 35 0
      frameworks/C++/treefrog/models/mongoobjects/mngfortuneobject.h
  59. 35 0
      frameworks/C++/treefrog/models/mongoobjects/mngworldobject.h
  60. 20 0
      frameworks/C++/treefrog/setup-mongodb.sh
  61. 20 0
      frameworks/C++/treefrog/setup-postgres.sh
  62. 5 4
      frameworks/C++/treefrog/setup-thread.sh
  63. 4 3
      frameworks/C++/treefrog/setup.sh
  64. 1 1
      frameworks/C++/treefrog/views/_src/_src.pro
  65. 1 0
      frameworks/C++/treefrog/views/fortune/.trim_mode
  66. 1 2
      frameworks/C++/treefrog/views/fortune/index.erb
  67. 22 0
      frameworks/C++/treefrog/views/fortune/mindex.erb
  68. 1 0
      frameworks/C++/treefrog/views/world/.trim_mode
  69. 3 0
      frameworks/C++/ulib/README.md
  70. 55 1
      frameworks/C++/ulib/benchmark_config.json
  71. 24 0
      frameworks/C++/ulib/setup_elasticsearch.sh
  72. 2 4
      frameworks/C++/ulib/setup_json.sh
  73. 28 0
      frameworks/C++/ulib/setup_json_extra.sh
  74. 23 0
      frameworks/C++/ulib/setup_json_large.sh
  75. 28 0
      frameworks/C++/ulib/setup_json_medium.sh
  76. 3 0
      frameworks/C++/ulib/source_code
  77. 5 5
      frameworks/C++/ulib/src/db.usp
  78. 68 0
      frameworks/C++/ulib/src/edb.usp
  79. 102 0
      frameworks/C++/ulib/src/equery.usp
  80. 108 0
      frameworks/C++/ulib/src/eupdate.usp
  81. 16 8
      frameworks/C++/ulib/src/fortune.usp
  82. 2 2
      frameworks/C++/ulib/src/json.usp
  83. 25 36
      frameworks/C++/ulib/src/mdb.usp
  84. 48 44
      frameworks/C++/ulib/src/mfortune.usp
  85. 38 41
      frameworks/C++/ulib/src/mquery.usp
  86. 17 16
      frameworks/C++/ulib/src/mupdate.usp
  87. 11 7
      frameworks/C++/ulib/src/query.usp
  88. 22 31
      frameworks/C++/ulib/src/rdb.usp
  89. 14 6
      frameworks/C++/ulib/src/rfortune.usp
  90. 36 33
      frameworks/C++/ulib/src/rquery.usp
  91. 38 35
      frameworks/C++/ulib/src/rupdate.usp
  92. 13 11
      frameworks/C++/ulib/src/update.usp
  93. 2 4
      frameworks/C++/ulib/src/world.h
  94. 2 0
      frameworks/C++/wt/.gitignore
  95. 3 1
      frameworks/C/duda/.gitignore
  96. 23 0
      frameworks/C/h2o/CMakeLists.txt
  97. 11 0
      frameworks/C/h2o/README.md
  98. 9 10
      frameworks/C/h2o/benchmark_config.json
  99. 57 0
      frameworks/C/h2o/setup.sh
  100. 23 0
      frameworks/C/h2o/source_code

+ 14 - 12
.travis.yml

@@ -20,7 +20,9 @@ env:
     - "TESTDIR=C/duda"
     - "TESTDIR=C/duda"
     - "TESTDIR=C/haywire"
     - "TESTDIR=C/haywire"
     - "TESTDIR=C/onion"
     - "TESTDIR=C/onion"
+    - "TESTDIR=C/h2o"
     - "TESTDIR=CSharp/aspnet"
     - "TESTDIR=CSharp/aspnet"
+    - "TESTDIR=CSharp/aspnetcore"
     ## - "TESTDIR=CSharp/aspnet-stripped"
     ## - "TESTDIR=CSharp/aspnet-stripped"
     - "TESTDIR=CSharp/evhttp-sharp"
     - "TESTDIR=CSharp/evhttp-sharp"
     ## - "TESTDIR=CSharp/HttpListener"
     ## - "TESTDIR=CSharp/HttpListener"
@@ -28,6 +30,7 @@ env:
     - "TESTDIR=CSharp/revenj"
     - "TESTDIR=CSharp/revenj"
     - "TESTDIR=CSharp/servicestack"
     - "TESTDIR=CSharp/servicestack"
     - "TESTDIR=C++/cpoll_cppsp"
     - "TESTDIR=C++/cpoll_cppsp"
+    - "TESTDIR=C++/cutelyst"
     - "TESTDIR=C++/silicon"
     - "TESTDIR=C++/silicon"
     - "TESTDIR=C++/treefrog"
     - "TESTDIR=C++/treefrog"
     - "TESTDIR=C++/ulib"
     - "TESTDIR=C++/ulib"
@@ -40,7 +43,6 @@ env:
     - "TESTDIR=Clojure/pedestal"
     - "TESTDIR=Clojure/pedestal"
     - "TESTDIR=Clojure/aleph"
     - "TESTDIR=Clojure/aleph"
     - "TESTDIR=Crystal/crystal-raw"
     - "TESTDIR=Crystal/crystal-raw"
-    - "TESTDIR=Crystal/moonshine"
     - "TESTDIR=Crystal/kemal"
     - "TESTDIR=Crystal/kemal"
     - "TESTDIR=D/vibed"
     - "TESTDIR=D/vibed"
     - "TESTDIR=Dart/dart-raw"
     - "TESTDIR=Dart/dart-raw"
@@ -53,24 +55,20 @@ env:
     - "TESTDIR=Erlang/cowboy"
     - "TESTDIR=Erlang/cowboy"
     - "TESTDIR=Erlang/elli"
     - "TESTDIR=Erlang/elli"
     - "TESTDIR=Erlang/mochiweb"
     - "TESTDIR=Erlang/mochiweb"
-    - "TESTDIR=Erlang/misultin"
     - "TESTDIR=Go/beego"
     - "TESTDIR=Go/beego"
+    - "TESTDIR=Go/echo"
     - "TESTDIR=Go/falcore"
     - "TESTDIR=Go/falcore"
-    - "TESTDIR=Go/fasthttp-mysql"
-    - "TESTDIR=Go/fasthttp-postgresql"
+    - "TESTDIR=Go/fasthttp"
     - "TESTDIR=Go/gin"
     - "TESTDIR=Go/gin"
     - "TESTDIR=Go/goji"
     - "TESTDIR=Go/goji"
-    - "TESTDIR=Go/go-std-mongodb"
-    - "TESTDIR=Go/go-std-mysql"
-    - "TESTDIR=Go/go-std-postgresql"
+    - "TESTDIR=Go/go-std"
     - "TESTDIR=Go/revel"
     - "TESTDIR=Go/revel"
-    - "TESTDIR=Go/revel-jet"
-    - "TESTDIR=Go/revel-qbs"
     - "TESTDIR=Go/webgo"
     - "TESTDIR=Go/webgo"
     - "TESTDIR=Groovy/grails"
     - "TESTDIR=Groovy/grails"
     - "TESTDIR=Haskell/snap"
     - "TESTDIR=Haskell/snap"
     - "TESTDIR=Haskell/wai"
     - "TESTDIR=Haskell/wai"
     - "TESTDIR=Haskell/yesod"
     - "TESTDIR=Haskell/yesod"
+    - "TESTDIR=Haskell/servant"
     - "TESTDIR=Haskell/spock"
     - "TESTDIR=Haskell/spock"
     - "TESTDIR=Java/activeweb"
     - "TESTDIR=Java/activeweb"
     - "TESTDIR=Java/baratine"
     - "TESTDIR=Java/baratine"
@@ -85,13 +83,13 @@ env:
     - "TESTDIR=Java/jawn"
     - "TESTDIR=Java/jawn"
     - "TESTDIR=Java/jetty-servlet"
     - "TESTDIR=Java/jetty-servlet"
     - "TESTDIR=Java/jetty"
     - "TESTDIR=Java/jetty"
+    - "TESTDIR=Java/jlhttp"
     - "TESTDIR=Java/jooby"
     - "TESTDIR=Java/jooby"
     - "TESTDIR=Java/netty"
     - "TESTDIR=Java/netty"
     - "TESTDIR=Java/ninja-standalone"
     - "TESTDIR=Java/ninja-standalone"
     - "TESTDIR=Java/officefloor"
     - "TESTDIR=Java/officefloor"
     - "TESTDIR=Java/permeagility"
     - "TESTDIR=Java/permeagility"
     - "TESTDIR=Java/play1"
     - "TESTDIR=Java/play1"
-    - "TESTDIR=Java/play1siena"
     - "TESTDIR=Java/play2-java"
     - "TESTDIR=Java/play2-java"
     - "TESTDIR=Java/rapidoid"
     - "TESTDIR=Java/rapidoid"
     - "TESTDIR=Java/restexpress"
     - "TESTDIR=Java/restexpress"
@@ -118,6 +116,7 @@ env:
     - "TESTDIR=JavaScript/ringojs"
     - "TESTDIR=JavaScript/ringojs"
     - "TESTDIR=JavaScript/ringojs-convenient"
     - "TESTDIR=JavaScript/ringojs-convenient"
     - "TESTDIR=JavaScript/sailsjs"
     - "TESTDIR=JavaScript/sailsjs"
+    - "TESTDIR=Kotlin/hexagon"
     - "TESTDIR=Lua/lapis"
     - "TESTDIR=Lua/lapis"
     - "TESTDIR=Lua/openresty"
     - "TESTDIR=Lua/openresty"
     - "TESTDIR=Nim/jester"
     - "TESTDIR=Nim/jester"
@@ -140,7 +139,6 @@ env:
     - "TESTDIR=PHP/limonade"
     - "TESTDIR=PHP/limonade"
     - "TESTDIR=PHP/lithium"
     - "TESTDIR=PHP/lithium"
     - "TESTDIR=PHP/lumen"
     - "TESTDIR=PHP/lumen"
-    - "TESTDIR=PHP/micromvc"
     - "TESTDIR=PHP/phalcon"
     - "TESTDIR=PHP/phalcon"
     - "TESTDIR=PHP/phalcon-micro"
     - "TESTDIR=PHP/phalcon-micro"
     - "TESTDIR=PHP/phpixie"
     - "TESTDIR=PHP/phpixie"
@@ -185,6 +183,7 @@ env:
     - "TESTDIR=Scala/akka-http"
     - "TESTDIR=Scala/akka-http"
     - "TESTDIR=Scala/colossus"
     - "TESTDIR=Scala/colossus"
     - "TESTDIR=Scala/finagle"
     - "TESTDIR=Scala/finagle"
+    - "TESTDIR=Scala/finatra"
     - "TESTDIR=Scala/fintrospect"
     - "TESTDIR=Scala/fintrospect"
     - "TESTDIR=Scala/lift-stateless"
     - "TESTDIR=Scala/lift-stateless"
     - "TESTDIR=Scala/plain"
     - "TESTDIR=Scala/plain"
@@ -192,6 +191,7 @@ env:
     - "TESTDIR=Scala/scalatra"
     - "TESTDIR=Scala/scalatra"
     - "TESTDIR=Scala/scruffy"
     - "TESTDIR=Scala/scruffy"
     - "TESTDIR=Scala/spray"
     - "TESTDIR=Scala/spray"
+    - "TESTDIR=Scala/s-server"
     - "TESTDIR=Scala/spray-es"
     - "TESTDIR=Scala/spray-es"
     - "TESTDIR=Scala/unfiltered"
     - "TESTDIR=Scala/unfiltered"
     - "TESTDIR=Scala/http4s"
     - "TESTDIR=Scala/http4s"
@@ -210,6 +210,7 @@ before_install:
 services:
 services:
   - postgresql
   - postgresql
   - redis-server
   - redis-server
+  - mongodb
 
 
 addons:
 addons:
   postgresql: "9.3"
   postgresql: "9.3"
@@ -230,4 +231,5 @@ script:
 
 
 cache:
 cache:
   directories:
   directories:
-  - /home/testrunner/.m2/repository
+    - $HOME/.m2/repository
+    - $HOME/.cache/pip

+ 5 - 2
README.md

@@ -43,9 +43,12 @@ required.
 
 
         $ vagrant ssh
         $ vagrant ssh
 
 
-5. Run a test.
+5. Move into the FrameworkBenchmarks directory in the vm.
 
 
         vagrant@TFB-all:~$ cd ~/FrameworkBenchmarks
         vagrant@TFB-all:~$ cd ~/FrameworkBenchmarks
+        
+6. Run a test.
+
         vagrant@TFB-all:~/FrameworkBenchmarks$ toolset/run-tests.py --install server --mode verify --test beego
         vagrant@TFB-all:~/FrameworkBenchmarks$ toolset/run-tests.py --install server --mode verify --test beego
 
 
 _Note: `--install server` only needs to be added the first time that a tests is run. 
 _Note: `--install server` only needs to be added the first time that a tests is run. 
@@ -74,4 +77,4 @@ can be found in the [TFB documentation](http://frameworkbenchmarks.readthedocs.o
 
 
 Join in the conversation at our 
 Join in the conversation at our 
 [Google Group](https://groups.google.com/forum/?fromgroups=#!forum/framework-benchmarks), 
 [Google Group](https://groups.google.com/forum/?fromgroups=#!forum/framework-benchmarks), 
-or chat with us on [Freenode](https://freenode.net/faq.shtml#whatwhy) at `#techempower-fwbm`. 
+or chat with us on [Freenode](https://webchat.freenode.net/) at `#techempower-fwbm`. 

+ 0 - 1
benchmark.cfg.example

@@ -20,7 +20,6 @@ concurrency_levels=[8, 16, 32, 64, 128, 256]
 query_levels=[1, 5,10,15,20]
 query_levels=[1, 5,10,15,20]
 threads=8
 threads=8
 mode=benchmark
 mode=benchmark
-name=ec2
 os=linux
 os=linux
 password_prompt=False
 password_prompt=False
 server_host=127.0.0.1
 server_host=127.0.0.1

+ 0 - 2
config/create-postgres-database.sql

@@ -2,5 +2,3 @@ CREATE USER benchmarkdbuser WITH PASSWORD 'benchmarkdbpass';
 
 
 DROP DATABASE IF EXISTS hello_world;
 DROP DATABASE IF EXISTS hello_world;
 CREATE DATABASE hello_world WITH ENCODING 'UTF8';
 CREATE DATABASE hello_world WITH ENCODING 'UTF8';
-
-GRANT ALL PRIVILEGES ON DATABASE hello_world to benchmarkdbuser;

+ 0 - 29
config/create-postgres-old.sql

@@ -1,29 +0,0 @@
-DROP TABLE IF EXISTS World;
-CREATE TABLE  "World" (
-  id integer NOT NULL,
-  randomNumber integer NOT NULL default 0,
-  PRIMARY KEY  (id)
-);
-
-INSERT INTO "World" (id, randomNumber)
-SELECT x.id, random() * 10000 + 1 FROM generate_series(1,10000) as x(id);
-
-DROP TABLE IF EXISTS Fortune;
-CREATE TABLE  "Fortune" (
-  id integer NOT NULL,
-  message varchar(2048) NOT NULL,
-  PRIMARY KEY  (id)
-);
-
-INSERT INTO fortune (id, message) VALUES (1, 'fortune: No such file or directory');
-INSERT INTO fortune (id, message) VALUES (2, 'A computer scientist is someone who fixes things that aren''t broken.');
-INSERT INTO fortune (id, message) VALUES (3, 'After enough decimal places, nobody gives a damn.');
-INSERT INTO fortune (id, message) VALUES (4, 'A bad random number generator: 1, 1, 1, 1, 1, 4.33e+67, 1, 1, 1');
-INSERT INTO fortune (id, message) VALUES (5, 'A computer program does what you tell it to do, not what you want it to do.');
-INSERT INTO fortune (id, message) VALUES (6, 'Emacs is a nice operating system, but I prefer UNIX. — Tom Christaensen');
-INSERT INTO fortune (id, message) VALUES (7, 'Any program that runs right is obsolete.');
-INSERT INTO fortune (id, message) VALUES (8, 'A list is only as strong as its weakest link. — Donald Knuth');
-INSERT INTO fortune (id, message) VALUES (9, 'Feature: A bug with seniority.');
-INSERT INTO fortune (id, message) VALUES (10, 'Computers make very fast, very accurate mistakes.');
-INSERT INTO fortune (id, message) VALUES (11, '<script>alert("This should not be displayed in a browser alert box.");</script>');
-INSERT INTO fortune (id, message) VALUES (12, 'フレームワークのベンチマーク');

+ 0 - 29
config/create-postgres-upper-quote.sql

@@ -1,29 +0,0 @@
-DROP TABLE IF EXISTS "World";
-CREATE TABLE  "World" (
-  id integer NOT NULL,
-  randomNumber integer NOT NULL default 0,
-  PRIMARY KEY  (id)
-);
-
-INSERT INTO "World" (id, randomNumber)
-SELECT x.id, random() * 10000 + 1 FROM generate_series(1,10000) as x(id);
-
-DROP TABLE IF EXISTS "Fortune";
-CREATE TABLE "Fortune" (
-  id integer NOT NULL,
-  message varchar(2048) NOT NULL,
-  PRIMARY KEY  (id)
-);
-
-INSERT INTO "Fortune" (id, message) VALUES (1, 'fortune: No such file or directory');
-INSERT INTO "Fortune" (id, message) VALUES (2, 'A computer scientist is someone who fixes things that aren''t broken.');
-INSERT INTO "Fortune" (id, message) VALUES (3, 'After enough decimal places, nobody gives a damn.');
-INSERT INTO "Fortune" (id, message) VALUES (4, 'A bad random number generator: 1, 1, 1, 1, 1, 4.33e+67, 1, 1, 1');
-INSERT INTO "Fortune" (id, message) VALUES (5, 'A computer program does what you tell it to do, not what you want it to do.');
-INSERT INTO "Fortune" (id, message) VALUES (6, 'Emacs is a nice operating system, but I prefer UNIX. — Tom Christaensen');
-INSERT INTO "Fortune" (id, message) VALUES (7, 'Any program that runs right is obsolete.');
-INSERT INTO "Fortune" (id, message) VALUES (8, 'A list is only as strong as its weakest link. — Donald Knuth');
-INSERT INTO "Fortune" (id, message) VALUES (9, 'Feature: A bug with seniority.');
-INSERT INTO "Fortune" (id, message) VALUES (10, 'Computers make very fast, very accurate mistakes.');
-INSERT INTO "Fortune" (id, message) VALUES (11, '<script>alert("This should not be displayed in a browser alert box.");</script>');
-INSERT INTO "Fortune" (id, message) VALUES (12, 'フレームワークのベンチマーク');

+ 4 - 0
config/create-postgres.sql

@@ -5,6 +5,7 @@ CREATE TABLE  World (
   randomNumber integer NOT NULL default 0,
   randomNumber integer NOT NULL default 0,
   PRIMARY KEY  (id)
   PRIMARY KEY  (id)
 );
 );
+GRANT SELECT, UPDATE ON World to benchmarkdbuser;
 
 
 INSERT INTO World (id, randomnumber)
 INSERT INTO World (id, randomnumber)
 SELECT x.id, random() * 10000 + 1 FROM generate_series(1,10000) as x(id);
 SELECT x.id, random() * 10000 + 1 FROM generate_series(1,10000) as x(id);
@@ -15,6 +16,7 @@ CREATE TABLE Fortune (
   message varchar(2048) NOT NULL,
   message varchar(2048) NOT NULL,
   PRIMARY KEY  (id)
   PRIMARY KEY  (id)
 );
 );
+GRANT SELECT ON Fortune to benchmarkdbuser;
 
 
 INSERT INTO Fortune (id, message) VALUES (1, 'fortune: No such file or directory');
 INSERT INTO Fortune (id, message) VALUES (1, 'fortune: No such file or directory');
 INSERT INTO Fortune (id, message) VALUES (2, 'A computer scientist is someone who fixes things that aren''t broken.');
 INSERT INTO Fortune (id, message) VALUES (2, 'A computer scientist is someone who fixes things that aren''t broken.');
@@ -36,6 +38,7 @@ CREATE TABLE  "World" (
   randomNumber integer NOT NULL default 0,
   randomNumber integer NOT NULL default 0,
   PRIMARY KEY  (id)
   PRIMARY KEY  (id)
 );
 );
+GRANT SELECT, UPDATE ON "World" to benchmarkdbuser;
 
 
 INSERT INTO "World" (id, randomnumber)
 INSERT INTO "World" (id, randomnumber)
 SELECT x.id, random() * 10000 + 1 FROM generate_series(1,10000) as x(id);
 SELECT x.id, random() * 10000 + 1 FROM generate_series(1,10000) as x(id);
@@ -46,6 +49,7 @@ CREATE TABLE "Fortune" (
   message varchar(2048) NOT NULL,
   message varchar(2048) NOT NULL,
   PRIMARY KEY  (id)
   PRIMARY KEY  (id)
 );
 );
+GRANT SELECT ON "Fortune" to benchmarkdbuser;
 
 
 INSERT INTO "Fortune" (id, message) VALUES (1, 'fortune: No such file or directory');
 INSERT INTO "Fortune" (id, message) VALUES (1, 'fortune: No such file or directory');
 INSERT INTO "Fortune" (id, message) VALUES (2, 'A computer scientist is someone who fixes things that aren''t broken.');
 INSERT INTO "Fortune" (id, message) VALUES (2, 'A computer scientist is someone who fixes things that aren''t broken.');

+ 2 - 53
config/create.sql

@@ -3,59 +3,6 @@ DROP DATABASE IF EXISTS hello_world;
 CREATE DATABASE hello_world;
 CREATE DATABASE hello_world;
 USE hello_world;
 USE hello_world;
 
 
-DROP TABLE IF EXISTS World;
-CREATE TABLE  World (
-  id int(10) unsigned NOT NULL auto_increment,
-  randomNumber int NOT NULL default 0,
-  PRIMARY KEY  (id)
-)
-ENGINE=INNODB;
-GRANT ALL ON hello_world.world TO 'benchmarkdbuser'@'%' IDENTIFIED BY 'benchmarkdbpass';
-GRANT ALL ON hello_world.world TO 'benchmarkdbuser'@'localhost' IDENTIFIED BY 'benchmarkdbpass';
-
-DROP PROCEDURE IF EXISTS load_data;
-
-DELIMITER #
-CREATE PROCEDURE load_data()
-BEGIN
-
-declare v_max int unsigned default 10000;
-declare v_counter int unsigned default 0;
-
-  TRUNCATE TABLE World;
-  START TRANSACTION;
-  while v_counter < v_max do
-    INSERT INTO World (randomNumber) VALUES ( floor(0 + (rand() * 10000)) );
-    SET v_counter=v_counter+1;
-  end while;
-  commit;
-END #
-
-DELIMITER ;
-
-CALL load_data();
-
-DROP TABLE IF EXISTS Fortune;
-CREATE TABLE  Fortune (
-  id int(10) unsigned NOT NULL auto_increment,
-  message varchar(2048) CHARACTER SET 'utf8' NOT NULL,
-  PRIMARY KEY  (id)
-)
-ENGINE=INNODB;
-
-INSERT INTO Fortune (message) VALUES ('fortune: No such file or directory');
-INSERT INTO Fortune (message) VALUES ('A computer scientist is someone who fixes things that aren''t broken.');
-INSERT INTO Fortune (message) VALUES ('After enough decimal places, nobody gives a damn.');
-INSERT INTO Fortune (message) VALUES ('A bad random number generator: 1, 1, 1, 1, 1, 4.33e+67, 1, 1, 1');
-INSERT INTO Fortune (message) VALUES ('A computer program does what you tell it to do, not what you want it to do.');
-INSERT INTO Fortune (message) VALUES ('Emacs is a nice operating system, but I prefer UNIX. — Tom Christaensen');
-INSERT INTO Fortune (message) VALUES ('Any program that runs right is obsolete.');
-INSERT INTO Fortune (message) VALUES ('A list is only as strong as its weakest link. — Donald Knuth');
-INSERT INTO Fortune (message) VALUES ('Feature: A bug with seniority.');
-INSERT INTO Fortune (message) VALUES ('Computers make very fast, very accurate mistakes.');
-INSERT INTO Fortune (message) VALUES ('<script>alert("This should not be displayed in a browser alert box.");</script>');
-INSERT INTO Fortune (message) VALUES ('フレームワークのベンチマーク');
-
 DROP TABLE IF EXISTS world;
 DROP TABLE IF EXISTS world;
 CREATE TABLE  world (
 CREATE TABLE  world (
   id int(10) unsigned NOT NULL auto_increment,
   id int(10) unsigned NOT NULL auto_increment,
@@ -63,6 +10,8 @@ CREATE TABLE  world (
   PRIMARY KEY  (id)
   PRIMARY KEY  (id)
 )
 )
 ENGINE=INNODB;
 ENGINE=INNODB;
+GRANT SELECT, UPDATE ON hello_world.world TO 'benchmarkdbuser'@'%' IDENTIFIED BY 'benchmarkdbpass';
+GRANT SELECT, UPDATE ON hello_world.world TO 'benchmarkdbuser'@'localhost' IDENTIFIED BY 'benchmarkdbpass';
 
 
 DROP PROCEDURE IF EXISTS load_data;
 DROP PROCEDURE IF EXISTS load_data;
 
 

+ 14 - 6
config/php.ini

@@ -372,7 +372,7 @@ zend.enable_gc = On
 ; threat in any way, but it makes it possible to determine whether you use PHP
 ; threat in any way, but it makes it possible to determine whether you use PHP
 ; on your server or not.
 ; on your server or not.
 ; http://php.net/expose-php
 ; http://php.net/expose-php
-expose_php = On
+expose_php = Off
 
 
 ;;;;;;;;;;;;;;;;;;;
 ;;;;;;;;;;;;;;;;;;;
 ; Resource Limits ;
 ; Resource Limits ;
@@ -868,9 +868,10 @@ default_socket_timeout = 60
 ;extension=apc.so
 ;extension=apc.so
 zend_extension=opcache.so
 zend_extension=opcache.so
 extension=redis.so
 extension=redis.so
-extension=phalcon.so
+;extension=phalcon.so
 ;extension=yaf.so
 ;extension=yaf.so
 extension=mongodb.so
 extension=mongodb.so
+extension=mongo.so
 ;extension=php_bz2.dll
 ;extension=php_bz2.dll
 ;extension=php_curl.dll
 ;extension=php_curl.dll
 ;extension=php_fileinfo.dll
 ;extension=php_fileinfo.dll
@@ -1865,10 +1866,17 @@ ldap.max_links = -1
 ; Local Variables:
 ; Local Variables:
 ; tab-width: 4
 ; tab-width: 4
 ; End:
 ; End:
-[apc]
-apc.stat = 0
-apc.enable_cli = 1
-apc.shm_size = 64M
+;[apc]
+;apc.stat = 0
+;apc.enable_cli = 1
+;apc.shm_size = 64M
+
+[opcache]
+opcache.validate_timestamps = 0 ; The same that apc.stat = 0
+;opcache.enable_file_override = 1 ; Faster for some frameworks
+;opcache.save_comments = 0 ; Breaks any fw using annotations comments
+;opcache.fast_shutdown = 1 ; Have problems with some big frameworks
+
 
 
 [yaf]
 [yaf]
 yaf.library =
 yaf.library =

+ 1 - 1
config/travis_setup.sh

@@ -83,7 +83,7 @@ echo "Populating Postgres database"
 psql --version
 psql --version
 sudo useradd benchmarkdbuser -p benchmarkdbpass
 sudo useradd benchmarkdbuser -p benchmarkdbpass
 sudo -u postgres psql template1 < config/create-postgres-database.sql
 sudo -u postgres psql template1 < config/create-postgres-database.sql
-sudo -u benchmarkdbuser psql hello_world < config/create-postgres.sql
+sudo -u postgres psql hello_world < config/create-postgres.sql
 sudo sed -i "s|#listen_addresses = 'localhost'|listen_addresses = '*'|g" /etc/postgresql/9.3/main/postgresql.conf
 sudo sed -i "s|#listen_addresses = 'localhost'|listen_addresses = '*'|g" /etc/postgresql/9.3/main/postgresql.conf
 sudo sed -i 's|max_connections = 255|max_connections = 500|g' /etc/postgresql/9.3/main/postgresql.conf
 sudo sed -i 's|max_connections = 255|max_connections = 500|g' /etc/postgresql/9.3/main/postgresql.conf
 sudo service postgresql stop
 sudo service postgresql stop

+ 1 - 1
deployment/vagrant-aws/setup_aws.py

@@ -80,7 +80,7 @@ def setup_vpc():
   # run_aws("authorize-security-group-egress --group-id %s --protocol -1 --cidr 0.0.0.0/0 --port all" % groupid)
   # run_aws("authorize-security-group-egress --group-id %s --protocol -1 --cidr 0.0.0.0/0 --port all" % groupid)
   run_aws("authorize-security-group-ingress --group-id %s --source-group %s --protocol -1 --port -1" % (groupid, groupid))
   run_aws("authorize-security-group-ingress --group-id %s --source-group %s --protocol -1 --port -1" % (groupid, groupid))
 
 
-  log.info("Complete."
+  log.info("Complete.")
   log.info(" Here are the environment variables you should use:")
   log.info(" Here are the environment variables you should use:")
   print "export TFB_AWS_SUBNET=%s" % pubid
   print "export TFB_AWS_SUBNET=%s" % pubid
   print "export TFB_AWS_SEC_GROUP=%s" % groupid
   print "export TFB_AWS_SEC_GROUP=%s" % groupid

+ 1 - 1
deployment/vagrant-common/custom_motd.sh

@@ -6,7 +6,7 @@ echo ""
 echo "  To get started, perhaps try this:"
 echo "  To get started, perhaps try this:"
 echo "    \$ cd FrameworkBenchmarks"
 echo "    \$ cd FrameworkBenchmarks"
 echo "    \$ toolset/run-tests.py --install server --test go"
 echo "    \$ toolset/run-tests.py --install server --test go"
-echo "    \$ cat results/ec2/latest/logs/go/out.txt"
+echo "    \$ cat results/latest/logs/go/out.txt"
 echo ""
 echo ""
 echo "  You can get lots of help:"
 echo "  You can get lots of help:"
 echo "    \$ toolset/run-tests.py --help"
 echo "    \$ toolset/run-tests.py --help"

+ 2 - 2
deployment/vagrant-development/README.md

@@ -51,7 +51,7 @@ Welcome to the FrameworkBenchmarks project!
 To get started, perhaps try this:
 To get started, perhaps try this:
    $ cd FrameworkBenchmarks
    $ cd FrameworkBenchmarks
    $ toolset/run-tests.py --install server --test go
    $ toolset/run-tests.py --install server --test go
-   $ cat results/ec2/latest/logs/go/out.txt
+   $ cat results/latest/logs/go/out.txt
 
 
 You can get lots of help:
 You can get lots of help:
    $ toolset/run-tests.py --help
    $ toolset/run-tests.py --help
@@ -71,7 +71,7 @@ usernames, or private key files, as so:
     <log for installing software needed for go test>
     <log for installing software needed for go test>
     <log for launching go framework>
     <log for launching go framework>
     <log for verifying go framework meets requirements>
     <log for verifying go framework meets requirements>
-    $ cat results/ec2/latest/logs/go/out.txt
+    $ cat results/latest/logs/go/out.txt
     <log with stdout from framework go>
     <log with stdout from framework go>
 
 
 # Using Amazon-powered Virtual Machine
 # Using Amazon-powered Virtual Machine

+ 1 - 1
deployment/vagrant-production/README.md

@@ -46,7 +46,7 @@ Welcome to the FrameworkBenchmarks project!
 To get started, perhaps try this:
 To get started, perhaps try this:
    $ cd FrameworkBenchmarks
    $ cd FrameworkBenchmarks
    $ toolset/run-tests.py --install server --test go
    $ toolset/run-tests.py --install server --test go
-   $ cat results/ec2/latest/logs/go/out.txt
+   $ cat results/latest/logs/go/out.txt
 
 
 You can get lots of help:
 You can get lots of help:
    $ toolset/run-tests.py --help
    $ toolset/run-tests.py --help

+ 2 - 0
frameworks/C++/cpoll_cppsp/.gitignore

@@ -0,0 +1,2 @@
+/www/*.so
+/www/*.txt

+ 29 - 0
frameworks/C++/cutelyst/CMakeLists.txt

@@ -0,0 +1,29 @@
+project(cutelyst_benchmarks)
+
+cmake_minimum_required(VERSION 2.8.12 FATAL_ERROR)
+if (POLICY CMP0043)
+  cmake_policy(SET CMP0043 NEW)
+endif()
+
+find_package(Qt5 COMPONENTS Core Network Sql REQUIRED)
+find_package(CutelystQt5 REQUIRED)
+
+# Auto generate moc files
+set(CMAKE_AUTOMOC ON)
+
+# As moc files are generated in the binary dir, tell CMake
+# to always look for includes there:
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+# Enable C++11 features
+add_definitions(-std=c++11)
+
+include_directories(
+    ${CMAKE_SOURCE_DIR}
+    ${CMAKE_CURRENT_BINARY_DIR}
+    ${CutelystQt5_INCLUDE_DIR}
+)
+
+file(GLOB_RECURSE TEMPLATES_SRC root/*)
+
+add_subdirectory(src)

+ 127 - 0
frameworks/C++/cutelyst/benchmark_config.json

@@ -0,0 +1,127 @@
+{
+    "framework": "cutelyst",
+    "tests": [{
+            "default": {
+                "setup_file": "setup",
+                "json_url": "/json",
+                "plaintext_url": "/plaintext",
+                "port": 8080,
+                "approach": "Realistic",
+                "classification": "Fullstack",
+                "database": "None",
+                "framework": "cutelyst",
+                "language": "C++",
+                "orm": "Raw",
+                "platform": "Qt",
+                "webserver": "None",
+                "os": "Linux",
+                "database_os": "Linux",
+                "display_name": "cutelyst-uwsgi",
+                "notes": "",
+                "versus": ""
+            },
+            "postgres-raw": {
+                "setup_file": "setup",
+                "db_url": "/db_postgres",
+                "query_url": "/query_postgres?queries=",
+                "update_url": "/updates_postgres?queries=",
+                "fortune_url": "/fortunes_raw_postgres",
+                "port": 8080,
+                "approach": "Realistic",
+                "classification": "Platform",
+                "database": "Postgres",
+                "framework": "cutelyst",
+                "language": "C++",
+                "orm": "Raw",
+                "platform": "Qt",
+                "webserver": "None",
+                "os": "Linux",
+                "database_os": "Linux",
+                "display_name": "cutelyst-uwsgi-pg-raw",
+                "notes": "",
+                "versus": ""
+            },
+            "mysql-raw": {
+                "setup_file": "setup",
+                "db_url": "/db_mysql",
+                "query_url": "/query_mysql?queries=",
+                "update_url": "/updates_mysql?queries=",
+                "fortune_url": "/fortunes_raw_mysql",
+                "port": 8080,
+                "approach": "Realistic",
+                "classification": "Platform",
+                "database": "MySQL",
+                "framework": "cutelyst",
+                "language": "C++",
+                "orm": "Raw",
+                "platform": "Qt",
+                "webserver": "None",
+                "os": "Linux",
+                "database_os": "Linux",
+                "display_name": "cutelyst-uwsgi-mysql-raw",
+                "notes": "",
+                "versus": ""
+            },
+            "nginx": {
+                "setup_file": "setup_uwsgi_nginx",
+                "json_url": "/json",
+                "plaintext_url": "/plaintext",
+                "port": 8080,
+                "approach": "Realistic",
+                "classification": "Fullstack",
+                "database": "None",
+                "framework": "cutelyst",
+                "language": "C++",
+                "orm": "Raw",
+                "platform": "Qt",
+                "webserver": "None",
+                "os": "Linux",
+                "database_os": "Linux",
+                "display_name": "cutelyst-uwsgi-nginx",
+                "notes": "",
+                "versus": ""
+            },
+            "nginx-postgres-raw": {
+                "setup_file": "setup_uwsgi_nginx",
+                "db_url": "/db_postgres",
+                "query_url": "/query_postgres?queries=",
+                "update_url": "/updates_postgres?queries=",
+                "fortune_url": "/fortunes_raw_postgres",
+                "port": 8080,
+                "approach": "Realistic",
+                "classification": "Platform",
+                "database": "Postgres",
+                "framework": "cutelyst",
+                "language": "C++",
+                "orm": "Raw",
+                "platform": "Qt",
+                "webserver": "None",
+                "os": "Linux",
+                "database_os": "Linux",
+                "display_name": "cutelyst-uwsgi-nginx-pg-raw",
+                "notes": "",
+                "versus": ""
+            },
+            "nginx-mysql-raw": {
+                "setup_file": "setup_uwsgi_nginx",
+                "db_url": "/db_mysql",
+                "query_url": "/query_mysql?queries=",
+                "update_url": "/updates_mysql?queries=",
+                "fortune_url": "/fortunes_raw_mysql",
+                "port": 8080,
+                "approach": "Realistic",
+                "classification": "Platform",
+                "database": "MySQL",
+                "framework": "cutelyst",
+                "language": "C++",
+                "orm": "Raw",
+                "platform": "Qt",
+                "webserver": "None",
+                "os": "Linux",
+                "database_os": "Linux",
+                "display_name": "cutelyst-uwsgi-nginx-mysql-raw",
+                "notes": "",
+                "versus": ""
+            }
+        }]
+}

+ 21 - 0
frameworks/C++/cutelyst/config/config.ini

@@ -0,0 +1,21 @@
+[uwsgi]
+master
+; Increase listen queue used for nginx connecting to uWSGI. This matches
+; net.ipv4.tcp_max_syn_backlog and net.core.somaxconn.
+; for performance
+disable-logging
+; use UNIX sockets instead of TCP loopback for performance
+http-socket = :8080
+; Avoid thundering herd problem http://uwsgi-docs.readthedocs.org/en/latest/articles/SerializingAccept.html .
+; This is currently disabled because when I tried it with flask, it caused a
+; 20% performance hit. The CPU cores could not be saturated with thunder-lock.
+; I'm not yet sure the full story, so this is presently disabled. Also,
+; disabling this caused bottle to get ~13% faster.
+;thunder-lock
+; used by uwsgi_stop.ini
+pidfile = /tmp/uwsgi.pid
+plugin = cutelyst
+
+[Cutelyst]
+DatabaseHostName=
+SendDate=

+ 23 - 0
frameworks/C++/cutelyst/config/config_socket.ini

@@ -0,0 +1,23 @@
+[uwsgi]
+master
+; Increase listen queue used for nginx connecting to uWSGI. This matches
+; net.ipv4.tcp_max_syn_backlog and net.core.somaxconn.
+; for performance
+disable-logging
+; use UNIX sockets instead of TCP loopback for performance
+socket = /tmp/uwsgi.sock
+; allow nginx to access the UNIX socket
+chmod-socket = 666
+; Avoid thundering herd problem http://uwsgi-docs.readthedocs.org/en/latest/articles/SerializingAccept.html .
+; This is currently disabled because when I tried it with flask, it caused a
+; 20% performance hit. The CPU cores could not be saturated with thunder-lock.
+; I'm not yet sure the full story, so this is presently disabled. Also,
+; disabling this caused bottle to get ~13% faster.
+;thunder-lock
+; used by uwsgi_stop.ini
+pidfile = /tmp/uwsgi.pid
+plugin = cutelyst
+
+[Cutelyst]
+DatabaseHostName=
+SendDate=

+ 48 - 0
frameworks/C++/cutelyst/nginx.conf

@@ -0,0 +1,48 @@
+# This file is based on /usr/local/nginx/conf/nginx.conf.default.
+
+# One worker process per core
+error_log stderr error;
+
+events {
+    # This needed to be increased because the nginx error log said so.
+    # http://nginx.org/en/docs/ngx_core_module.html#worker_connections
+    worker_connections  65535;
+    multi_accept on;
+}
+
+http {
+    default_type  application/octet-stream;
+    client_body_temp_path      /tmp;
+
+    # turn off request logging for performance
+    access_log off;
+
+    # I think these only options affect static file serving
+    sendfile        on;
+    tcp_nopush      on;
+
+    # Allow many HTTP Keep-Alive requests in a single TCP connection before
+    # closing it (the default is 100). This will minimize the total number
+    # of TCP connections opened/closed. The problem is that this may cause
+    # some worker processes to be handling too connections relative to the
+    # other workers based on an initial imbalance, so this is disabled for
+    # now.
+#    keepalive_requests 1000;
+
+    #keepalive_timeout  0;
+    keepalive_timeout  65;
+
+    server {
+        # For information on deferred, see:
+        # http://nginx.org/en/docs/http/ngx_http_core_module.html#listen
+        # http://www.techrepublic.com/article/take-advantage-of-tcp-ip-options-to-optimize-data-transmission/
+        # The backlog argument to listen() is set to match net.ipv4.tcp_max_syn_backlog and net.core.somaxconn
+        listen       8080 default_server deferred backlog=65535;
+        server_name  localhost;
+
+        location / {
+            uwsgi_pass unix:/tmp/uwsgi.sock;
+            include /usr/local/nginx/conf/uwsgi_params;
+        }
+    }
+}

+ 22 - 0
frameworks/C++/cutelyst/setup.sh

@@ -0,0 +1,22 @@
+#!/bin/bash
+
+fw_depends cutelyst
+
+sed -i 's|DatabaseHostName=.*|DatabaseHostName='"$DBHOST"'|g' config/config.ini
+sed -i 's|SendDate=.*|SendDate=true|g' config/config.ini
+
+cd $IROOT
+mkdir cutelyst-benchmarks || true
+cd cutelyst-benchmarks
+rm -rf *
+
+QT_VERSION_MM=56
+export CMAKE_PREFIX_PATH=/opt/qt${QT_VERSION_MM}:${IROOT}
+
+cmake $TROOT -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$IROOT
+
+make clean
+make -j $MAX_THREADS
+
+export LD_LIBRARY_PATH=/opt/qt${QT_VERSION_MM}/lib:${IROOT}/lib/x86_64-linux-gnu/
+uwsgi --ini ${TROOT}/config/config.ini --cutelyst-app ${IROOT}/cutelyst-benchmarks/src/libcutelyst_benchmarks.so -p $(( $MAX_THREADS * 2 )) &

+ 25 - 0
frameworks/C++/cutelyst/setup_uwsgi_nginx.sh

@@ -0,0 +1,25 @@
+#!/bin/bash
+
+fw_depends cutelyst nginx
+
+sed -i 's|DatabaseHostName=.*|DatabaseHostName='"$DBHOST"'|g' config/config_socket.ini
+sed -i 's|SendDate=.*|SendDate=false|g' config/config_socket.ini
+sed -i 's|include .*/conf/uwsgi_params;|include '"${NGINX_HOME}"'/conf/uwsgi_params;|g' nginx.conf
+
+cd $IROOT
+mkdir cutelyst-benchmarks || true
+cd cutelyst-benchmarks
+rm -rf *
+
+QT_VERSION_MM=56
+export CMAKE_PREFIX_PATH=/opt/qt${QT_VERSION_MM}:${IROOT}
+
+cmake $TROOT -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$IROOT
+
+make clean
+make -j $MAX_THREADS
+
+nginx -c $TROOT/nginx.conf
+
+export LD_LIBRARY_PATH=/opt/qt${QT_VERSION_MM}/lib:${IROOT}/lib/x86_64-linux-gnu/
+uwsgi --ini ${TROOT}/config/config_socket.ini --cutelyst-app ${IROOT}/cutelyst-benchmarks/src/libcutelyst_benchmarks.so -p $(( $MAX_THREADS * 2 )) &

+ 20 - 0
frameworks/C++/cutelyst/source_code

@@ -0,0 +1,20 @@
+cutelyst/
+cutelyst/CMakeLists.txt
+cutelyst/src
+cutelyst/src/plaintexttest.cpp
+cutelyst/src/jsontest.cpp
+cutelyst/src/fortunetest.h
+cutelyst/src/CMakeLists.txt
+cutelyst/src/plaintexttest.h
+cutelyst/src/multipledatabasequeriestest.h
+cutelyst/src/multipledatabasequeriestest.cpp
+cutelyst/src/databaseupdatestest.h
+cutelyst/src/databaseupdatestest.cpp
+cutelyst/src/jsontest.h
+cutelyst/src/singledatabasequerytest.cpp
+cutelyst/src/singledatabasequerytest.h
+cutelyst/src/cutelyst-benchmarks.cpp
+cutelyst/src/cutelyst-benchmarks.h
+cutelyst/src/root.h
+cutelyst/src/root.cpp
+cutelyst/src/fortunetest.cpp

+ 19 - 0
frameworks/C++/cutelyst/src/CMakeLists.txt

@@ -0,0 +1,19 @@
+file(GLOB_RECURSE cutelyst_benchmarks_SRCS *.cpp *.h)
+
+set(cutelyst_benchmarks_SRCS
+    ${cutelyst_benchmarks_SRCS}
+    ${TEMPLATES_SRC}
+)
+
+# Create the application
+add_library(cutelyst_benchmarks SHARED ${cutelyst_benchmarks_SRCS})
+
+# Link to Cutelyst
+target_link_libraries(cutelyst_benchmarks
+    Cutelyst::Core
+    Cutelyst::Utils::Sql
+    Qt5::Core
+    Qt5::Network
+    Qt5::Sql
+)
+

+ 78 - 0
frameworks/C++/cutelyst/src/cutelyst-benchmarks.cpp

@@ -0,0 +1,78 @@
+#include "cutelyst-benchmarks.h"
+
+#include <Cutelyst/Plugins/StaticSimple/staticsimple.h>
+
+#include <QtSql/QSqlDatabase>
+#include <QtSql/QSqlError>
+#include <QDebug>
+
+#include "root.h"
+#include "jsontest.h"
+#include "singledatabasequerytest.h"
+#include "multipledatabasequeriestest.h"
+#include "databaseupdatestest.h"
+#include "fortunetest.h"
+#include "plaintexttest.h"
+
+using namespace Cutelyst;
+
+cutelyst_benchmarks::cutelyst_benchmarks(QObject *parent) : Application(parent)
+{
+}
+
+cutelyst_benchmarks::~cutelyst_benchmarks()
+{
+}
+
+bool cutelyst_benchmarks::init()
+{
+    if (config(QLatin1String("SendDate")).value<bool>()) {
+        qDebug() << "Manually send date";
+        new Root(this);
+    }
+
+    new JsonTest(this);
+    new SingleDatabaseQueryTest(this);
+    new MultipleDatabaseQueriesTest(this);
+    new DatabaseUpdatesTest(this);
+    new FortuneTest(this);
+    new PlaintextTest(this);
+
+    defaultHeaders().setServer(QLatin1String("Cutelyst"));
+    defaultHeaders().removeHeader(QLatin1String("X-Cutelyst"));
+
+    return true;
+}
+
+bool cutelyst_benchmarks::postFork()
+{
+    QSqlDatabase db;
+    db = QSqlDatabase::addDatabase(QLatin1String("QPSQL"), QLatin1String("postgres"));
+    db.setDatabaseName(QLatin1String("hello_world"));
+    db.setUserName(QLatin1String("benchmarkdbuser"));
+    db.setPassword(QLatin1String("benchmarkdbpass"));
+    db.setHostName(config(QLatin1String("DatabaseHostName")).toString());
+    if (!db.open()) {
+        qDebug() << "Error opening db:" << db << db.lastError().databaseText();
+        return false;
+    }
+
+    db = QSqlDatabase::addDatabase(QLatin1String("QMYSQL"), QLatin1String("mysql"));
+    db.setDatabaseName(QLatin1String("hello_world"));
+    db.setUserName(QLatin1String("benchmarkdbuser"));
+    db.setPassword(QLatin1String("benchmarkdbpass"));
+    db.setHostName(config(QLatin1String("DatabaseHostName")).toString());
+    if (!db.open()) {
+        qDebug() << "Error opening db:" << db << db.lastError().databaseText();
+        return false;
+    }
+
+//    db = QSqlDatabase::addDatabase(QLatin1String("QSQLITE"), QLatin1String("sqlite"));
+//    if (!db.open()) {
+//        qDebug() << "Error opening db:" << db << db.lastError().databaseText();
+//        return false;
+//    }
+
+    return true;
+}
+

+ 22 - 0
frameworks/C++/cutelyst/src/cutelyst-benchmarks.h

@@ -0,0 +1,22 @@
+#ifndef CUTELYST_BENCHMARKS_H
+#define CUTELYST_BENCHMARKS_H
+
+#include <Cutelyst/Application>
+
+using namespace Cutelyst;
+
+class cutelyst_benchmarks : public Application
+{
+    Q_OBJECT
+    CUTELYST_APPLICATION(IID "cutelyst_benchmarks")
+public:
+    Q_INVOKABLE explicit cutelyst_benchmarks(QObject *parent = 0);
+    ~cutelyst_benchmarks();
+
+    bool init();
+
+    bool postFork();
+};
+
+#endif //CUTELYST_BENCHMARKS_H
+

+ 74 - 0
frameworks/C++/cutelyst/src/databaseupdatestest.cpp

@@ -0,0 +1,74 @@
+#include "databaseupdatestest.h"
+
+#include <Cutelyst/Plugins/Utils/Sql>
+
+#include <QtSql/QSqlQuery>
+
+#include <QtCore/QThread>
+#include <QtCore/QJsonDocument>
+#include <QtCore/QJsonObject>
+#include <QtCore/QJsonArray>
+
+DatabaseUpdatesTest::DatabaseUpdatesTest(QObject *parent) : Controller(parent)
+{
+
+}
+
+void DatabaseUpdatesTest::updates_postgres(Context *c)
+{
+    QSqlQuery query = CPreparedSqlQueryForDatabase(
+                QLatin1String("SELECT randomNumber FROM world WHERE id = :id"),
+                QSqlDatabase::database(QLatin1String("postgres")));
+    QSqlQuery updateQuery = CPreparedSqlQueryForDatabase(
+                QLatin1String("UPDATE world SET randomNumber = :randomNumber WHERE id = :id"),
+                QSqlDatabase::database(QLatin1String("postgres")));
+    processQuery(c, query, updateQuery);
+}
+
+void DatabaseUpdatesTest::updates_mysql(Context *c)
+{
+    QSqlQuery query = CPreparedSqlQueryForDatabase(
+                QLatin1String("SELECT randomNumber FROM world WHERE id = :id"),
+                QSqlDatabase::database(QLatin1String("mysql")));
+    QSqlQuery updateQuery = CPreparedSqlQueryForDatabase(
+                QLatin1String("UPDATE world SET randomNumber = :randomNumber WHERE id = :id"),
+                QSqlDatabase::database(QLatin1String("mysql")));
+    processQuery(c, query, updateQuery);
+}
+
+void DatabaseUpdatesTest::processQuery(Context *c, QSqlQuery &query, QSqlQuery &updateQuery)
+{
+    QJsonArray array;
+
+    int queries = c->request()->queryParam(QStringLiteral("queries"), QStringLiteral("1")).toInt();
+    if (queries < 1) {
+        queries = 1;
+    } else if (queries > 500) {
+        queries = 500;
+    }
+
+    for (int i = 0; i < queries; ++i) {
+        int id = (qrand() % 9999) + 1;
+
+        query.bindValue(QStringLiteral(":id"), id);
+        if (!query.exec() || !query.next()) {
+            c->res()->setStatus(Response::InternalServerError);
+            return;
+        }
+
+        int randomNumber = (qrand() % 9999) + 1;
+        updateQuery.bindValue(QStringLiteral(":id"), id);
+        updateQuery.bindValue(QStringLiteral(":randomNumber"), randomNumber);
+        if (!updateQuery.exec()) {
+            c->res()->setStatus(Response::InternalServerError);
+            return;
+        }
+
+        QJsonObject obj;
+        obj.insert(QStringLiteral("id"), query.value(0).toInt());
+        obj.insert(QStringLiteral("randomNumber"), randomNumber);
+        array.append(obj);
+    }
+
+    c->response()->setJsonBody(QJsonDocument(array));
+}

+ 26 - 0
frameworks/C++/cutelyst/src/databaseupdatestest.h

@@ -0,0 +1,26 @@
+#ifndef DATABASEUPDATESTEST_H
+#define DATABASEUPDATESTEST_H
+
+#include <Cutelyst/Controller>
+
+using namespace Cutelyst;
+
+class QSqlQuery;
+class DatabaseUpdatesTest : public Controller
+{
+    Q_OBJECT
+    C_NAMESPACE("")
+public:
+    explicit DatabaseUpdatesTest(QObject *parent = 0);
+
+    C_ATTR(updates_postgres, :Local :AutoArgs)
+    void updates_postgres(Context *c);
+
+    C_ATTR(updates_mysql, :Local :AutoArgs)
+    void updates_mysql(Context *c);
+
+private:
+    inline void processQuery(Context *c, QSqlQuery &query, QSqlQuery &updateQuery);
+};
+
+#endif // DATABASEUPDATESTEST_H

+ 90 - 0
frameworks/C++/cutelyst/src/fortunetest.cpp

@@ -0,0 +1,90 @@
+#include "fortunetest.h"
+
+#include <Cutelyst/Plugins/Utils/Sql>
+
+#include <QStringBuilder>
+
+#include <QtSql/QSqlQuery>
+
+#include <QtCore/QThread>
+#include <QtCore/QJsonDocument>
+#include <QtCore/QJsonObject>
+#include <QtCore/QJsonArray>
+
+FortuneTest::FortuneTest(QObject *parent) : Controller(parent)
+{
+
+}
+
+void FortuneTest::fortunes_raw_postgres(Context *c)
+{
+    QSqlQuery query = postgresQuery();
+    auto fortunes = processQuery(c, query);
+    renderRaw(c, fortunes);
+}
+
+void FortuneTest::fortunes_raw_mysql(Context *c)
+{
+    QSqlQuery query = mysqlQuery();
+    auto fortunes = processQuery(c, query);
+    renderRaw(c, fortunes);
+}
+
+QSqlQuery FortuneTest::postgresQuery()
+{
+    return CPreparedSqlQueryForDatabase(
+                QLatin1String("SELECT id, message FROM fortune"),
+                QSqlDatabase::database(QLatin1String("postgres")));
+}
+
+QSqlQuery FortuneTest::mysqlQuery()
+{
+    return CPreparedSqlQueryForDatabase(
+                QLatin1String("SELECT id, message FROM fortune"),
+                QSqlDatabase::database(QLatin1String("mysql")));
+}
+
+static bool caseSensitiveLessThan(const Fortune &a1, const Fortune &a2)
+{
+    return a1.second < a2.second;
+}
+
+FortuneList FortuneTest::processQuery(Context *c, QSqlQuery &query)
+{
+    FortuneList fortunes;
+
+    if (!query.exec()) {
+        c->res()->setStatus(Response::InternalServerError);
+        return fortunes;
+    }
+
+    while (query.next()) {
+        fortunes.append(qMakePair(query.value(0).toInt(), query.value(1).toString()));
+    }
+    fortunes.append(qMakePair(0, QStringLiteral("Additional fortune added at request time.")));
+
+    qSort(fortunes.begin(), fortunes.end(), caseSensitiveLessThan);
+
+    c->response()->setContentType(QStringLiteral("text/html; charset=UTF-8"));
+
+    return fortunes;
+}
+
+void FortuneTest::renderRaw(Context *c, const FortuneList &fortunes)
+{
+    QString out;
+    out.append(QStringLiteral("<!DOCTYPE html>"
+                              "<html>"
+                              "<head><title>Fortunes</title></head>"
+                              "<body>"
+                              "<table>"
+                              "<tr><th>id</th><th>message</th></tr>"));
+
+    Q_FOREACH (const Fortune &fortune, fortunes) {
+        out.append(QLatin1String("<tr><td>") % QString::number(fortune.first) % QLatin1String("</td><td>") % fortune.second.toHtmlEscaped() % QLatin1String("</td></tr>"));
+    }
+
+    out.append(QStringLiteral("</table></body></html>"));
+
+    c->response()->setBody(out);
+}

+ 32 - 0
frameworks/C++/cutelyst/src/fortunetest.h

@@ -0,0 +1,32 @@
+#ifndef FORTUNETEST_H
+#define FORTUNETEST_H
+
+#include <Cutelyst/Controller>
+
+using namespace Cutelyst;
+
+typedef QPair<int, QString> Fortune;
+typedef QList<Fortune> FortuneList;
+
+class QSqlQuery;
+class FortuneTest : public Controller
+{
+    Q_OBJECT
+    C_NAMESPACE("")
+public:
+    explicit FortuneTest(QObject *parent = 0);
+
+    C_ATTR(fortunes_raw_postgres, :Local :AutoArgs)
+    void fortunes_raw_postgres(Context *c);
+
+    C_ATTR(fortunes_raw_mysql, :Local :AutoArgs)
+    void fortunes_raw_mysql(Context *c);
+
+private:
+    inline QSqlQuery postgresQuery();
+    inline QSqlQuery mysqlQuery();
+    inline FortuneList processQuery(Context *c, QSqlQuery &query);
+    inline void renderRaw(Context *c, const FortuneList &fortunes);
+};
+
+#endif // FORTUNETEST_H

+ 17 - 0
frameworks/C++/cutelyst/src/jsontest.cpp

@@ -0,0 +1,17 @@
+#include "jsontest.h"
+
+#include <QtCore/QJsonDocument>
+#include <QtCore/QJsonObject>
+
+JsonTest::JsonTest(QObject *parent) : Controller(parent)
+{
+
+}
+
+void JsonTest::json(Context *c)
+{
+    QJsonObject obj;
+    obj.insert(QStringLiteral("message"), QStringLiteral("Hello, World!"));
+
+    c->response()->setJsonBody(QJsonDocument(obj));
+}

+ 19 - 0
frameworks/C++/cutelyst/src/jsontest.h

@@ -0,0 +1,19 @@
+#ifndef JSONTEST_H
+#define JSONTEST_H
+
+#include <Cutelyst/Controller>
+
+using namespace Cutelyst;
+
+class JsonTest : public Controller
+{
+    Q_OBJECT
+    C_NAMESPACE("")
+public:
+    explicit JsonTest(QObject *parent = 0);
+
+    C_ATTR(json, :Local :AutoArgs)
+    void json(Context *c);
+};
+
+#endif // JSONTEST_H

+ 60 - 0
frameworks/C++/cutelyst/src/multipledatabasequeriestest.cpp

@@ -0,0 +1,60 @@
+#include "multipledatabasequeriestest.h"
+
+#include <Cutelyst/Plugins/Utils/Sql>
+
+#include <QtSql/QSqlQuery>
+
+#include <QtCore/QThread>
+#include <QtCore/QJsonDocument>
+#include <QtCore/QJsonObject>
+#include <QtCore/QJsonArray>
+
+MultipleDatabaseQueriesTest::MultipleDatabaseQueriesTest(QObject *parent) : Controller(parent)
+{
+
+}
+
+void MultipleDatabaseQueriesTest::query_postgres(Context *c)
+{
+    QSqlQuery query = CPreparedSqlQueryForDatabase(
+                QLatin1String("SELECT id, randomNumber FROM world WHERE id = :id"),
+                QSqlDatabase::database(QLatin1String("postgres")));
+    processQuery(c, query);
+}
+
+void MultipleDatabaseQueriesTest::query_mysql(Context *c)
+{
+    QSqlQuery query = CPreparedSqlQueryForDatabase(
+                QLatin1String("SELECT id, randomNumber FROM world WHERE id = :id"),
+                QSqlDatabase::database(QLatin1String("mysql")));
+    processQuery(c, query);
+}
+
+void MultipleDatabaseQueriesTest::processQuery(Context *c, QSqlQuery &query)
+{
+    QJsonArray array;
+
+    int queries = c->request()->queryParam(QStringLiteral("queries"), QStringLiteral("1")).toInt();
+    if (queries < 1) {
+        queries = 1;
+    } else if (queries > 500) {
+        queries = 500;
+    }
+
+    for (int i = 0; i < queries; ++i) {
+        int id = qrand() % 9999;
+
+        query.bindValue(QStringLiteral(":id"), id + 1);
+        if (!query.exec() || !query.next()) {
+            c->res()->setStatus(Response::InternalServerError);
+            return;
+        }
+
+        QJsonObject obj;
+        obj.insert(QStringLiteral("id"), query.value(0).toInt());
+        obj.insert(QStringLiteral("randomNumber"), query.value(1).toInt());
+        array.append(obj);
+    }
+
+    c->response()->setJsonBody(QJsonDocument(array));
+}

+ 26 - 0
frameworks/C++/cutelyst/src/multipledatabasequeriestest.h

@@ -0,0 +1,26 @@
+#ifndef MULTIPLEDATABASEQUERIESTEST_H
+#define MULTIPLEDATABASEQUERIESTEST_H
+
+#include <Cutelyst/Controller>
+
+using namespace Cutelyst;
+
+class QSqlQuery;
+class MultipleDatabaseQueriesTest : public Controller
+{
+    Q_OBJECT
+    C_NAMESPACE("")
+public:
+    explicit MultipleDatabaseQueriesTest(QObject *parent = 0);
+
+    C_ATTR(query_postgres, :Local :AutoArgs)
+    void query_postgres(Context *c);
+
+    C_ATTR(query_mysql, :Local :AutoArgs)
+    void query_mysql(Context *c);
+
+private:
+    inline void processQuery(Context *c, QSqlQuery &query);
+};
+
+#endif // MULTIPLEDATABASEQUERIESTEST_H

+ 13 - 0
frameworks/C++/cutelyst/src/plaintexttest.cpp

@@ -0,0 +1,13 @@
+#include "plaintexttest.h"
+
+PlaintextTest::PlaintextTest(QObject *parent) : Controller(parent)
+{
+
+}
+
+void PlaintextTest::plaintext(Context *c)
+{
+    Response *res = c->response();
+    res->setBody(QByteArrayLiteral("Hello, World!"));
+    res->setContentType(QStringLiteral("text/plain"));
+}

+ 19 - 0
frameworks/C++/cutelyst/src/plaintexttest.h

@@ -0,0 +1,19 @@
+#ifndef PLAINTEXTTEST_H
+#define PLAINTEXTTEST_H
+
+#include <Cutelyst/Controller>
+
+using namespace Cutelyst;
+
+class PlaintextTest : public Controller
+{
+    Q_OBJECT
+    C_NAMESPACE("")
+public:
+    explicit PlaintextTest(QObject *parent = 0);
+
+    C_ATTR(plaintext, :Local :AutoArgs)
+    void plaintext(Context *c);
+};
+
+#endif // PLAINTEXTTEST_H

+ 37 - 0
frameworks/C++/cutelyst/src/root.cpp

@@ -0,0 +1,37 @@
+#include "root.h"
+
+#include <QElapsedTimer>
+
+using namespace Cutelyst;
+
+Root::Root(QObject *parent) : Controller(parent)
+{
+}
+
+Root::~Root()
+{
+}
+
+QElapsedTimer timerSetup(Context *c)
+{
+    QElapsedTimer timer;
+    timer.start();
+    return timer;
+}
+
+QString setupHeader(Context *c)
+{
+    return c->response()->headers().setDateWithDateTime(QDateTime::currentDateTimeUtc());
+}
+
+void Root::End(Context *c)
+{
+    static QString lastDate = setupHeader(c);
+    static QElapsedTimer timer = timerSetup(c);
+    if (timer.hasExpired(1000)) {
+        lastDate = setupHeader(c);
+        timer.restart();
+    } else {
+        c->response()->setHeader(QStringLiteral("date"), lastDate);
+    }
+}

+ 22 - 0
frameworks/C++/cutelyst/src/root.h

@@ -0,0 +1,22 @@
+#ifndef ROOT_H
+#define ROOT_H
+
+#include <Cutelyst/Controller>
+
+using namespace Cutelyst;
+
+class Root : public Controller
+{
+    Q_OBJECT
+    C_NAMESPACE("")
+public:
+    explicit Root(QObject *parent = 0);
+    ~Root();
+
+private:
+    C_ATTR(End, :AutoArgs)
+    void End(Context *c);
+};
+
+#endif //ROOT_H
+

+ 47 - 0
frameworks/C++/cutelyst/src/singledatabasequerytest.cpp

@@ -0,0 +1,47 @@
+#include "singledatabasequerytest.h"
+
+#include <Cutelyst/Plugins/Utils/Sql>
+
+#include <QtSql/QSqlQuery>
+
+#include <QtCore/QThread>
+#include <QtCore/QJsonDocument>
+#include <QtCore/QJsonObject>
+
+SingleDatabaseQueryTest::SingleDatabaseQueryTest(QObject *parent) : Controller(parent)
+{
+    qsrand(QDateTime::currentMSecsSinceEpoch());
+}
+
+void SingleDatabaseQueryTest::db_postgres(Context *c)
+{
+    QSqlQuery query = CPreparedSqlQueryForDatabase(
+                QLatin1String("SELECT id, randomNumber FROM world WHERE id = :id"),
+                QSqlDatabase::database(QLatin1String("postgres")));
+    processQuery(c, query);
+}
+
+void SingleDatabaseQueryTest::db_mysql(Context *c)
+{
+    QSqlQuery query = CPreparedSqlQueryForDatabase(
+                QLatin1String("SELECT id, randomNumber FROM world WHERE id = :id"),
+                QSqlDatabase::database(QLatin1String("mysql")));
+    processQuery(c, query);
+}
+
+void SingleDatabaseQueryTest::processQuery(Context *c, QSqlQuery &query)
+{
+    int id = qrand() % 9999;
+
+    query.bindValue(QStringLiteral(":id"), id + 1);
+    if (!query.exec() || !query.next()) {
+        c->res()->setStatus(Response::InternalServerError);
+        return;
+    }
+
+    QJsonObject obj;
+    obj.insert(QStringLiteral("id"), query.value(0).toInt());
+    obj.insert(QStringLiteral("randomNumber"), query.value(1).toInt());
+
+    c->response()->setJsonBody(QJsonDocument(obj));
+}

+ 26 - 0
frameworks/C++/cutelyst/src/singledatabasequerytest.h

@@ -0,0 +1,26 @@
+#ifndef SINGLEDATABASEQUERYTEST_H
+#define SINGLEDATABASEQUERYTEST_H
+
+#include <Cutelyst/Controller>
+
+using namespace Cutelyst;
+
+class QSqlQuery;
+class SingleDatabaseQueryTest : public Controller
+{
+    Q_OBJECT
+    C_NAMESPACE("")
+public:
+    explicit SingleDatabaseQueryTest(QObject *parent = 0);
+
+    C_ATTR(db_postgres, :Local :AutoArgs)
+    void db_postgres(Context *c);
+
+    C_ATTR(db_mysql, :Local :AutoArgs)
+    void db_mysql(Context *c);
+
+private:
+    inline void processQuery(Context *c, QSqlQuery &query);
+};
+
+#endif // SINGLEDATABASEQUERYTEST_H

+ 1 - 0
frameworks/C++/ffead-cpp/.gitignore

@@ -0,0 +1 @@
+/ffead-cpp-2.0/

+ 1 - 0
frameworks/C++/poco/.gitignore

@@ -0,0 +1 @@
+/poco

+ 1 - 0
frameworks/C++/silicon/.gitignore

@@ -0,0 +1 @@
+/build/

+ 50 - 4
frameworks/C++/treefrog/benchmark_config.json

@@ -2,6 +2,29 @@
   "framework": "treefrog",
   "framework": "treefrog",
   "tests": [{
   "tests": [{
     "default": {
     "default": {
+      "setup_file": "setup-thread",
+      "json_url": "/json/json",
+      "db_url": "/world/random",
+      "query_url": "/world/queries/",
+      "fortune_url": "/fortune/index",
+      "update_url": "/world/updates/",
+      "plaintext_url": "/world/plain",
+      "port": 8080,
+      "approach": "Realistic",
+      "classification": "Fullstack",
+      "database": "MySQL",
+      "framework": "treefrog",
+      "language": "C++",
+      "orm": "Micro",
+      "platform": "Treefrog",
+      "webserver": "None",
+      "os": "Linux",
+      "database_os": "Linux",
+      "display_name": "treefrog-thread",
+      "notes": "",
+      "versus": ""
+    },
+    "hybrid": {
       "setup_file": "setup",
       "setup_file": "setup",
       "json_url": "/json/json",
       "json_url": "/json/json",
       "db_url": "/world/random",
       "db_url": "/world/random",
@@ -25,8 +48,8 @@
       "notes": "",
       "notes": "",
       "versus": "treefrog"
       "versus": "treefrog"
     },
     },
-    "thread": {
-      "setup_file": "setup-thread",
+    "postgres": {
+      "setup_file": "setup-postgres",
       "json_url": "/json/json",
       "json_url": "/json/json",
       "db_url": "/world/random",
       "db_url": "/world/random",
       "query_url": "/world/queries/",
       "query_url": "/world/queries/",
@@ -36,7 +59,7 @@
       "port": 8080,
       "port": 8080,
       "approach": "Realistic",
       "approach": "Realistic",
       "classification": "Fullstack",
       "classification": "Fullstack",
-      "database": "MySQL",
+      "database": "Postgres",
       "framework": "treefrog",
       "framework": "treefrog",
       "language": "C++",
       "language": "C++",
       "flavor": "C++14",
       "flavor": "C++14",
@@ -45,7 +68,30 @@
       "webserver": "None",
       "webserver": "None",
       "os": "Linux",
       "os": "Linux",
       "database_os": "Linux",
       "database_os": "Linux",
-      "display_name": "treefrog-thread",
+      "display_name": "treefrog-postgres",
+      "notes": "",
+      "versus": ""
+    },
+    "mongodb": {
+      "setup_file": "setup-mongodb",
+      "json_url": "/json/json",
+      "db_url": "/world/mrandom",
+      "query_url": "/world/mqueries/",
+      "fortune_url": "/fortune/mindex",
+      "update_url": "/world/mupdates/",
+      "plaintext_url": "/world/plain",
+      "port": 8080,
+      "approach": "Realistic",
+      "classification": "Fullstack",
+      "database": "MongoDB",
+      "framework": "treefrog",
+      "language": "C++",
+      "orm": "Micro",
+      "platform": "Treefrog",
+      "webserver": "None",
+      "os": "Linux",
+      "database_os": "Linux",
+      "display_name": "treefrog-mongo",
       "notes": "",
       "notes": "",
       "versus": "treefrog"
       "versus": "treefrog"
     }
     }

+ 20 - 18
frameworks/C++/treefrog/config/application.ini

@@ -14,10 +14,6 @@ InternalEncoding=UTF-8
 # specified encoding. See QTextCodec class reference.
 # specified encoding. See QTextCodec class reference.
 HttpOutputEncoding=UTF-8
 HttpOutputEncoding=UTF-8
 
 
-# Sets the charset parameter of 'text/html' in the HTTP Content-Type
-# header to the specified string.
-HtmlContentCharset=UTF-8
-
 # Sets a language/country pair, such as en_US, ja_JP, etc.
 # Sets a language/country pair, such as en_US, ja_JP, etc.
 # If this value is empty, the system's locale is used.
 # If this value is empty, the system's locale is used.
 Locale=
 Locale=
@@ -33,7 +29,7 @@ UploadTemporaryDirectory=tmp
 SqlDatabaseSettingsFiles=database.ini
 SqlDatabaseSettingsFiles=database.ini
 
 
 # Specify the setting file for MongoDB.
 # Specify the setting file for MongoDB.
-MongoDbSettingsFile=
+MongoDbSettingsFile=mongodb.ini
 
 
 # Specify the directory path to store SQL query files
 # Specify the directory path to store SQL query files
 SqlQueriesStoredDirectory=sql/
 SqlQueriesStoredDirectory=sql/
@@ -64,6 +60,25 @@ LimitRequestBody=0
 # forgery never work; otherwise it's enabled.
 # forgery never work; otherwise it's enabled.
 EnableCsrfProtectionModule=false
 EnableCsrfProtectionModule=false
 
 
+# Enables HTTP method override if true. The following are priorities of
+# override.
+#  - Value of query parameter named '_method'
+#  - Value of X-HTTP-Method-Override header
+#  - Value of X-HTTP-Method header
+#  - Value of X-METHOD-OVERRIDE header
+EnableHttpMethodOverride=false
+
+# Sets the timeout in seconds during which a keep-alive HTTP connection
+# will stay open on the server side. The zero value disables keep-alive
+# client connections.
+HttpKeepAliveTimeout=10
+
+# Forces some libraries to be loaded before all others. It means to set
+# the LD_PRELOAD environment variable for the application server, Linux
+# only. The paths to shared objects, jemalloc or TCMalloc, can be
+# specified.
+LDPreload=/usr/lib/x86_64-linux-gnu/libjemalloc.so
+
 ##
 ##
 ## Session section
 ## Session section
 ##
 ##
@@ -112,19 +127,6 @@ MPM.thread.MaxAppServers=10
 # per server process.
 # per server process.
 MPM.thread.MaxThreadsPerAppServer=100
 MPM.thread.MaxThreadsPerAppServer=100
 
 
-##
-## MPM Prefork section
-##
-
-# Maximum number of server processes allowed to start
-MPM.prefork.MaxServers=20
-
-# Minimum number of server processes allowed to start
-MPM.prefork.MinServers=5
-
-# Number of server processes which are kept spare
-MPM.prefork.SpareServers=5
-
 ##
 ##
 ## MPM Hybrid section
 ## MPM Hybrid section
 ##
 ##

+ 3 - 3
frameworks/C++/treefrog/config/mongodb.ini

@@ -3,7 +3,7 @@
 #
 #
 
 
 [dev]
 [dev]
-DatabaseName=mdb
+DatabaseName=hello_world
 HostName=localhost
 HostName=localhost
 Port=
 Port=
 UserName=
 UserName=
@@ -19,8 +19,8 @@ Password=
 ConnectOptions=
 ConnectOptions=
 
 
 [product]
 [product]
-DatabaseName=
-HostName=
+DatabaseName=hello_world
+HostName=localhost
 Port=
 Port=
 UserName=
 UserName=
 Password=
 Password=

+ 1 - 1
frameworks/C++/treefrog/controllers/controllers.pro

@@ -1,7 +1,7 @@
 TARGET = controller
 TARGET = controller
 TEMPLATE = lib
 TEMPLATE = lib
 CONFIG += shared x86_64 c++11
 CONFIG += shared x86_64 c++11
-QT += network sql xml
+QT += network sql xml qml
 QT -= gui
 QT -= gui
 DEFINES += TF_DLL
 DEFINES += TF_DLL
 DESTDIR = ../lib
 DESTDIR = ../lib

+ 18 - 0
frameworks/C++/treefrog/controllers/fortunecontroller.cpp

@@ -1,11 +1,17 @@
 #include "fortunecontroller.h"
 #include "fortunecontroller.h"
 #include "fortune.h"
 #include "fortune.h"
+#include "mngfortune.h"
 
 
 static bool caseSensitiveLessThan(const Fortune &f1, const Fortune &f2)
 static bool caseSensitiveLessThan(const Fortune &f1, const Fortune &f2)
 {
 {
     return f1.message() < f2.message();
     return f1.message() < f2.message();
 }
 }
 
 
+static bool caseSensitiveMngFortuneLessThan(const MngFortune &f1, const MngFortune &f2)
+{
+    return f1.message() < f2.message();
+}
+
 FortuneController::FortuneController(const FortuneController &)
 FortuneController::FortuneController(const FortuneController &)
     : ApplicationController()
     : ApplicationController()
 { }
 { }
@@ -22,6 +28,18 @@ void FortuneController::index()
     render();
     render();
 }
 }
 
 
+void FortuneController::mindex()
+{
+    QList<MngFortune> fortuneList = MngFortune::getAll();
+    MngFortune fortune;
+    fortune.setMessage(QLatin1String("Additional fortune added at request time."));
+    fortuneList << fortune;
+    // Sort
+    qSort(fortuneList.begin(), fortuneList.end(), caseSensitiveMngFortuneLessThan);
+    texport(fortuneList);
+    render("mindex");
+}
+
 void FortuneController::show(const QString &pk)
 void FortuneController::show(const QString &pk)
 {
 {
     Fortune fortune = Fortune::get(pk.toUInt());
     Fortune fortune = Fortune::get(pk.toUInt());

+ 2 - 1
frameworks/C++/treefrog/controllers/fortunecontroller.h

@@ -14,7 +14,8 @@ public:
     bool transactionEnabled() const { return false; }
     bool transactionEnabled() const { return false; }
 
 
 public slots:
 public slots:
-    void index();
+    void index();   // SQL
+    void mindex();  // MongoDB
     void show(const QString &pk);
     void show(const QString &pk);
     void entry();
     void entry();
     void create();
     void create();

+ 51 - 1
frameworks/C++/treefrog/controllers/worldcontroller.cpp

@@ -1,5 +1,6 @@
 #include "worldcontroller.h"
 #include "worldcontroller.h"
 #include "world.h"
 #include "world.h"
+#include "mngworld.h"
 
 
 
 
 WorldController::WorldController(const WorldController &)
 WorldController::WorldController(const WorldController &)
@@ -139,7 +140,7 @@ void WorldController::updates(const QString &num)
         world = World::get(id);
         world = World::get(id);
         world.setRandomNumber( Tf::random(9999) + 1 );
         world.setRandomNumber( Tf::random(9999) + 1 );
         world.update();
         world.update();
-	worlds << world.toVariantMap();
+        worlds << world.toVariantMap();
     }
     }
     renderJson(worlds);
     renderJson(worlds);
 }
 }
@@ -156,5 +157,54 @@ void WorldController::remove(const QString &pk)
 }
 }
 
 
 
 
+
+/*
+  MongoDB
+ */
+void WorldController::mqueries()
+{
+    mqueries("1");
+}
+
+void WorldController::mqueries(const QString &num)
+{
+    QVariantList worlds;
+    int d = qMin(qMax(num.toInt(), 1), 500);
+
+    for (int i = 0; i < d; ++i) {
+        QString id = QString::number(Tf::random(9999) + 1);
+        worlds << MngWorld::get(id).toVariantMap();
+    }
+    renderJson(worlds);
+}
+
+void WorldController::mrandom()
+{
+    int id = Tf::random(9999) + 1;
+    World world = World::get(id);
+    renderJson(world.toVariantMap());
+}
+
+void WorldController::mupdates()
+{
+    mupdates("1");
+}
+
+void WorldController::mupdates(const QString &num)
+{
+    QVariantList worlds;
+    int d = qMin(qMax(num.toInt(), 1), 500);
+    MngWorld world;
+
+    for (int i = 0; i < d; ++i) {
+        QString id = QString::number(Tf::random(9999) + 1);
+        world = MngWorld::get(id);
+        world.setRandomNumber( Tf::random(9999) + 1 );
+        world.update();
+        worlds << world.toVariantMap();
+    }
+    renderJson(worlds);
+}
+
 // Don't remove below this line
 // Don't remove below this line
 T_REGISTER_CONTROLLER(worldcontroller)
 T_REGISTER_CONTROLLER(worldcontroller)

+ 7 - 0
frameworks/C++/treefrog/controllers/worldcontroller.h

@@ -28,6 +28,13 @@ public slots:
     void updates();
     void updates();
     void remove(const QString &pk);
     void remove(const QString &pk);
 
 
+    // MongoDB
+    void mqueries();
+    void mqueries(const QString &num);
+    void mrandom();
+    void mupdates(const QString &num);
+    void mupdates();
+
 private:
 private:
     void renderEntry(const QVariantMap &world = QVariantMap());
     void renderEntry(const QVariantMap &world = QVariantMap());
     void renderEdit(const QVariantMap &world = QVariantMap());
     void renderEdit(const QVariantMap &world = QVariantMap());

+ 1 - 1
frameworks/C++/treefrog/helpers/helpers.pro

@@ -2,7 +2,7 @@ TARGET = helper
 TEMPLATE = lib
 TEMPLATE = lib
 CONFIG += shared x86_64 c++11
 CONFIG += shared x86_64 c++11
 QT  -= gui
 QT  -= gui
-QT  += 
+QT  += qml
 DEFINES += TF_DLL
 DEFINES += TF_DLL
 DESTDIR = ../lib
 DESTDIR = ../lib
 DEPENDPATH +=
 DEPENDPATH +=

+ 104 - 0
frameworks/C++/treefrog/models/mngfortune.cpp

@@ -0,0 +1,104 @@
+#include <TreeFrogModel>
+#include "mngfortune.h"
+#include "mngfortuneobject.h"
+
+MngFortune::MngFortune()
+    : TAbstractModel(), d(new MngFortuneObject)
+{
+    d->id = 0;
+}
+
+MngFortune::MngFortune(const MngFortune &other)
+    : TAbstractModel(), d(new MngFortuneObject(*other.d))
+{ }
+
+MngFortune::MngFortune(const MngFortuneObject &object)
+    : TAbstractModel(), d(new MngFortuneObject(object))
+{ }
+
+MngFortune::~MngFortune()
+{
+    // If the reference count becomes 0,
+    // the shared data object 'MngFortuneObject' is deleted.
+}
+
+int MngFortune::id() const
+{
+    return d->id;
+}
+
+QString MngFortune::message() const
+{
+    return d->message;
+}
+
+void MngFortune::setMessage(const QString &message)
+{
+    d->message = message;
+}
+
+MngFortune &MngFortune::operator=(const MngFortune &other)
+{
+    d = other.d;  // increments the reference count of the data
+    return *this;
+}
+
+MngFortune MngFortune::create(const QString &message)
+{
+    MngFortuneObject obj;
+    obj.message = message;
+    if (!obj.create()) {
+        return MngFortune();
+    }
+    return MngFortune(obj);
+}
+
+MngFortune MngFortune::create(const QVariantMap &values)
+{
+    MngFortune model;
+    model.setProperties(values);
+    if (!model.d->create()) {
+        model.d->clear();
+    }
+    return model;
+}
+
+MngFortune MngFortune::get(const QString &id)
+{
+    TMongoODMapper<MngFortuneObject> mapper;
+    return MngFortune(mapper.findByObjectId(id));
+}
+
+int MngFortune::count()
+{
+    TMongoODMapper<MngFortuneObject> mapper;
+    return mapper.findCount();
+}
+
+QList<MngFortune> MngFortune::getAll()
+{
+    return tfGetModelListByMongoCriteria<MngFortune, MngFortuneObject>(TCriteria());
+}
+
+QJsonArray MngFortune::getAllJson()
+{
+    QJsonArray array;
+    TMongoODMapper<MngFortuneObject> mapper;
+
+    if (mapper.find()) {
+        while (mapper.next()) {
+            array.append(QJsonValue(QJsonObject::fromVariantMap(MngFortune(mapper.value()).toVariantMap())));
+        }
+    }
+    return array;
+}
+
+TModelObject *MngFortune::modelData()
+{
+    return d.data();
+}
+
+const TModelObject *MngFortune::modelData() const
+{
+    return d.data();
+}

+ 51 - 0
frameworks/C++/treefrog/models/mngfortune.h

@@ -0,0 +1,51 @@
+#ifndef MNGFORTUNE_H
+#define MNGFORTUNE_H
+
+#include <QStringList>
+#include <QDateTime>
+#include <QVariant>
+#include <QSharedDataPointer>
+#include <TGlobal>
+#include <TAbstractModel>
+
+class TModelObject;
+class MngFortuneObject;
+class QJsonArray;
+
+
+class T_MODEL_EXPORT MngFortune : public TAbstractModel
+{
+public:
+    MngFortune();
+    MngFortune(const MngFortune &other);
+    MngFortune(const MngFortuneObject &object);
+    ~MngFortune();
+
+    int id() const;
+    QString message() const;
+    void setMessage(const QString &message);
+    MngFortune &operator=(const MngFortune &other);
+
+    bool create() { return TAbstractModel::create(); }
+    bool update() { return TAbstractModel::update(); }
+    bool save()   { return TAbstractModel::save(); }
+    bool remove() { return TAbstractModel::remove(); }
+
+    static MngFortune create(const QString &message);
+    static MngFortune create(const QVariantMap &values);
+    static MngFortune get(const QString &id);
+    static int count();
+    static QList<MngFortune> getAll();
+    static QJsonArray getAllJson();
+
+private:
+    QSharedDataPointer<MngFortuneObject> d;
+
+    TModelObject *modelData();
+    const TModelObject *modelData() const;
+};
+
+Q_DECLARE_METATYPE(MngFortune)
+Q_DECLARE_METATYPE(QList<MngFortune>)
+
+#endif // MNGFORTUNE_H

+ 105 - 0
frameworks/C++/treefrog/models/mngworld.cpp

@@ -0,0 +1,105 @@
+#include <TreeFrogModel>
+#include "mngworld.h"
+#include "mngworldobject.h"
+
+MngWorld::MngWorld()
+    : TAbstractModel(), d(new MngWorldObject)
+{
+    d->id = 0;
+    d->randomNumber = 0;
+}
+
+MngWorld::MngWorld(const MngWorld &other)
+    : TAbstractModel(), d(new MngWorldObject(*other.d))
+{ }
+
+MngWorld::MngWorld(const MngWorldObject &object)
+    : TAbstractModel(), d(new MngWorldObject(object))
+{ }
+
+MngWorld::~MngWorld()
+{
+    // If the reference count becomes 0,
+    // the shared data object 'MngWorldObject' is deleted.
+}
+
+int MngWorld::id() const
+{
+    return d->id;
+}
+
+int MngWorld::randomNumber() const
+{
+    return d->randomNumber;
+}
+
+void MngWorld::setRandomNumber(int randomNumber)
+{
+    d->randomNumber = randomNumber;
+}
+
+MngWorld &MngWorld::operator=(const MngWorld &other)
+{
+    d = other.d;  // increments the reference count of the data
+    return *this;
+}
+
+MngWorld MngWorld::create(int randomNumber)
+{
+    MngWorldObject obj;
+    obj.randomNumber = randomNumber;
+    if (!obj.create()) {
+        return MngWorld();
+    }
+    return MngWorld(obj);
+}
+
+MngWorld MngWorld::create(const QVariantMap &values)
+{
+    MngWorld model;
+    model.setProperties(values);
+    if (!model.d->create()) {
+        model.d->clear();
+    }
+    return model;
+}
+
+MngWorld MngWorld::get(const QString &id)
+{
+    TMongoODMapper<MngWorldObject> mapper;
+    return MngWorld(mapper.findByObjectId(id));
+}
+
+int MngWorld::count()
+{
+    TMongoODMapper<MngWorldObject> mapper;
+    return mapper.findCount();
+}
+
+QList<MngWorld> MngWorld::getAll()
+{
+    return tfGetModelListByMongoCriteria<MngWorld, MngWorldObject>(TCriteria());
+}
+
+QJsonArray MngWorld::getAllJson()
+{
+    QJsonArray array;
+    TMongoODMapper<MngWorldObject> mapper;
+
+    if (mapper.find()) {
+        while (mapper.next()) {
+            array.append(QJsonValue(QJsonObject::fromVariantMap(MngWorld(mapper.value()).toVariantMap())));
+        }
+    }
+    return array;
+}
+
+TModelObject *MngWorld::modelData()
+{
+    return d.data();
+}
+
+const TModelObject *MngWorld::modelData() const
+{
+    return d.data();
+}

+ 51 - 0
frameworks/C++/treefrog/models/mngworld.h

@@ -0,0 +1,51 @@
+#ifndef MNGWORLD_H
+#define MNGWORLD_H
+
+#include <QStringList>
+#include <QDateTime>
+#include <QVariant>
+#include <QSharedDataPointer>
+#include <TGlobal>
+#include <TAbstractModel>
+
+class TModelObject;
+class MngWorldObject;
+class QJsonArray;
+
+
+class T_MODEL_EXPORT MngWorld : public TAbstractModel
+{
+public:
+    MngWorld();
+    MngWorld(const MngWorld &other);
+    MngWorld(const MngWorldObject &object);
+    ~MngWorld();
+
+    int id() const;
+    int randomNumber() const;
+    void setRandomNumber(int randomNumber);
+    MngWorld &operator=(const MngWorld &other);
+
+    bool create() { return TAbstractModel::create(); }
+    bool update() { return TAbstractModel::update(); }
+    bool save()   { return TAbstractModel::save(); }
+    bool remove() { return TAbstractModel::remove(); }
+
+    static MngWorld create(int randomNumber);
+    static MngWorld create(const QVariantMap &values);
+    static MngWorld get(const QString &id);
+    static int count();
+    static QList<MngWorld> getAll();
+    static QJsonArray getAllJson();
+
+private:
+    QSharedDataPointer<MngWorldObject> d;
+
+    TModelObject *modelData();
+    const TModelObject *modelData() const;
+};
+
+Q_DECLARE_METATYPE(MngWorld)
+Q_DECLARE_METATYPE(QList<MngWorld>)
+
+#endif // MNGWORLD_H

+ 9 - 3
frameworks/C++/treefrog/models/models.pro

@@ -1,12 +1,12 @@
 TARGET = model
 TARGET = model
 TEMPLATE = lib
 TEMPLATE = lib
 CONFIG += shared x86_64 c++11
 CONFIG += shared x86_64 c++11
-QT += sql
+QT += sql qml
 QT -= gui
 QT -= gui
 DEFINES += TF_DLL
 DEFINES += TF_DLL
 DESTDIR = ../lib
 DESTDIR = ../lib
-INCLUDEPATH += ../helpers sqlobjects
-DEPENDPATH  += ../helpers sqlobjects
+INCLUDEPATH += ../helpers sqlobjects mongoobjects
+DEPENDPATH  += ../helpers sqlobjects mongoobjects
 LIBS += -L../lib -lhelper
 LIBS += -L../lib -lhelper
 
 
 include(../appbase.pri)
 include(../appbase.pri)
@@ -17,3 +17,9 @@ SOURCES += fortune.cpp
 HEADERS += sqlobjects/worldobject.h
 HEADERS += sqlobjects/worldobject.h
 HEADERS += world.h
 HEADERS += world.h
 SOURCES += world.cpp
 SOURCES += world.cpp
+HEADERS += mongoobjects/mngworldobject.h
+HEADERS += mngworld.h
+SOURCES += mngworld.cpp
+HEADERS += mongoobjects/mngfortuneobject.h
+HEADERS += mngfortune.h
+SOURCES += mngfortune.cpp

+ 35 - 0
frameworks/C++/treefrog/models/mongoobjects/mngfortuneobject.h

@@ -0,0 +1,35 @@
+#ifndef MNGFORTUNEOBJECT_H
+#define MNGFORTUNEOBJECT_H
+
+#include <TMongoObject>
+#include <QSharedData>
+
+
+class T_MODEL_EXPORT MngFortuneObject : public TMongoObject, public QSharedData
+{
+public:
+    QString _id;
+    int id;
+    QString message;
+
+    enum PropertyIndex {
+        _Id = 0,
+        Id,
+        Message,
+    };
+
+    virtual QString collectionName() const { return "fortune"; }
+    virtual QString objectId() const { return _id; }
+    virtual QString &objectId() { return _id; }
+
+private:
+    Q_OBJECT
+    Q_PROPERTY(QString _id READ get_id WRITE set_id)
+    T_DEFINE_PROPERTY(QString, _id)
+    Q_PROPERTY(int id READ getid WRITE setid)
+    T_DEFINE_PROPERTY(int, id)
+    Q_PROPERTY(QString message READ getmessage WRITE setmessage)
+    T_DEFINE_PROPERTY(QString, message)
+};
+
+#endif // MNGFORTUNEOBJECT_H

+ 35 - 0
frameworks/C++/treefrog/models/mongoobjects/mngworldobject.h

@@ -0,0 +1,35 @@
+#ifndef MNGWORLDOBJECT_H
+#define MNGWORLDOBJECT_H
+
+#include <TMongoObject>
+#include <QSharedData>
+
+
+class T_MODEL_EXPORT MngWorldObject : public TMongoObject, public QSharedData
+{
+public:
+    QString _id;
+    int id;
+    int randomNumber;
+
+    enum PropertyIndex {
+        _Id = 0,
+        Id,
+        RandomNumber,
+    };
+
+    virtual QString collectionName() const { return "world"; }
+    virtual QString objectId() const { return _id; }
+    virtual QString &objectId() { return _id; }
+
+private:
+    Q_OBJECT
+    Q_PROPERTY(QString _id READ get_id WRITE set_id)
+    T_DEFINE_PROPERTY(QString, _id)
+    Q_PROPERTY(int id READ getid WRITE setid)
+    T_DEFINE_PROPERTY(int, id)
+    Q_PROPERTY(int randomNumber READ getrandomNumber WRITE setrandomNumber)
+    T_DEFINE_PROPERTY(int, randomNumber)
+};
+
+#endif // MNGWORLDOBJECT_H

+ 20 - 0
frameworks/C++/treefrog/setup-mongodb.sh

@@ -0,0 +1,20 @@
+#!/bin/bash
+
+sed -i 's|HostName=.*|HostName='"$DBHOST"'|g' config/database.ini
+sed -i 's|HostName=.*|HostName='"$DBHOST"'|g' config/mongodb.ini
+sed -i 's|DriverType=.*|DriverType=QMYSQL|g' config/database.ini
+sed -i 's|MultiProcessingModule=.*|MultiProcessingModule=thread|g' config/application.ini
+
+fw_depends treefrog
+
+# 1. Generate Makefile
+qmake -r CONFIG+=release
+
+# 2. Compile applicaton
+make
+
+# 3. Clean log files
+rm -f log/*.log
+
+# 4. Start TreeFrog
+treefrog -d $TROOT

+ 20 - 0
frameworks/C++/treefrog/setup-postgres.sh

@@ -0,0 +1,20 @@
+#!/bin/bash
+
+sed -i 's|HostName=.*|HostName='"$DBHOST"'|g' config/database.ini
+sed -i 's|HostName=.*|HostName='"$DBHOST"'|g' config/mongodb.ini
+sed -i 's|DriverType=.*|DriverType=QPSQL|g' config/database.ini
+sed -i 's|MultiProcessingModule=.*|MultiProcessingModule=thread|g' config/application.ini
+
+fw_depends treefrog
+
+# 1. Generate Makefile
+qmake -r CONFIG+=release
+
+# 2. Compile applicaton
+make
+
+# 3. Clean log files
+rm -f log/*.log
+
+# 4. Start TreeFrog
+treefrog -d $TROOT

+ 5 - 4
frameworks/C++/treefrog/setup-thread.sh

@@ -1,7 +1,9 @@
 #!/bin/bash
 #!/bin/bash
 
 
 sed -i 's|HostName=.*|HostName='"$DBHOST"'|g' config/database.ini
 sed -i 's|HostName=.*|HostName='"$DBHOST"'|g' config/database.ini
-sed -i "s|MultiProcessingModule=.*|MultiProcessingModule=thread|g" config/application.ini
+sed -i 's|HostName=.*|HostName='"$DBHOST"'|g' config/mongodb.ini
+sed -i 's|DriverType=.*|DriverType=QMYSQL|g' config/database.ini
+sed -i 's|MultiProcessingModule=.*|MultiProcessingModule=thread|g' config/application.ini
 
 
 fw_depends treefrog
 fw_depends treefrog
 
 
@@ -9,11 +11,10 @@ fw_depends treefrog
 qmake -r CONFIG+=release
 qmake -r CONFIG+=release
 
 
 # 2. Compile applicaton
 # 2. Compile applicaton
-make clean
-make -j8
+make
 
 
 # 3. Clean log files
 # 3. Clean log files
 rm -f log/*.log
 rm -f log/*.log
 
 
 # 4. Start TreeFrog
 # 4. Start TreeFrog
-treefrog -d $TROOT &
+treefrog -d $TROOT

+ 4 - 3
frameworks/C++/treefrog/setup.sh

@@ -1,7 +1,9 @@
 #!/bin/bash
 #!/bin/bash
 
 
 sed -i 's|HostName=.*|HostName='"$DBHOST"'|g' config/database.ini
 sed -i 's|HostName=.*|HostName='"$DBHOST"'|g' config/database.ini
-sed -i "s|MultiProcessingModule=.*|MultiProcessingModule=hybrid|g" config/application.ini
+sed -i 's|HostName=.*|HostName='"$DBHOST"'|g' config/mongodb.ini
+sed -i 's|DriverType=.*|DriverType=QMYSQL|g' config/database.ini
+sed -i 's|MultiProcessingModule=.*|MultiProcessingModule=hybrid|g' config/application.ini
 
 
 fw_depends treefrog
 fw_depends treefrog
 
 
@@ -9,8 +11,7 @@ fw_depends treefrog
 qmake -r CONFIG+=release
 qmake -r CONFIG+=release
 
 
 # 2. Compile applicaton
 # 2. Compile applicaton
-make clean
-make -j8
+make
 
 
 # 3. Clean log files
 # 3. Clean log files
 rm -f log/*.log
 rm -f log/*.log

+ 1 - 1
frameworks/C++/treefrog/views/_src/_src.pro

@@ -1,7 +1,7 @@
 TARGET = view
 TARGET = view
 TEMPLATE = lib
 TEMPLATE = lib
 CONFIG += shared x86_64 c++11
 CONFIG += shared x86_64 c++11
-QT += network xml
+QT += network xml qml
 QT -= gui
 QT -= gui
 DEFINES += TF_DLL
 DEFINES += TF_DLL
 INCLUDEPATH += ../../helpers ../../models
 INCLUDEPATH += ../../helpers ../../models

+ 1 - 0
frameworks/C++/treefrog/views/fortune/.trim_mode

@@ -0,0 +1 @@
+2

+ 1 - 2
frameworks/C++/treefrog/views/fortune/index.erb

@@ -11,8 +11,7 @@
 <th>message</th>
 <th>message</th>
 </tr>
 </tr>
 <% tfetch(QList<Fortune>, fortuneList); %>
 <% tfetch(QList<Fortune>, fortuneList); %>
-<% for (QListIterator<Fortune> it(fortuneList); it.hasNext(); ) {
-     const Fortune &i = it.next(); %>
+<% for (auto &i : fortuneList) { %>
 <tr>
 <tr>
 <td><%= i.id() %></td>
 <td><%= i.id() %></td>
 <td><%= i.message() %></td>
 <td><%= i.message() %></td>

+ 22 - 0
frameworks/C++/treefrog/views/fortune/mindex.erb

@@ -0,0 +1,22 @@
+<!DOCTYPE HTML>
+<%#include "mngfortune.h" %>
+<html>
+<head>
+<title>Fortunes</title>
+</head>
+<body>
+<table>
+<tr>
+<th>id</th>
+<th>message</th>
+</tr>
+<% tfetch(QList<MngFortune>, fortuneList); %>
+<% for (auto &i : fortuneList) { %>
+<tr>
+<td><%= i.id() %></td>
+<td><%= i.message() %></td>
+</tr>
+<% } %>
+</table>
+</body>
+</html>

+ 1 - 0
frameworks/C++/treefrog/views/world/.trim_mode

@@ -0,0 +1 @@
+2

+ 3 - 0
frameworks/C++/ulib/README.md

@@ -11,12 +11,14 @@ This is the [ULib](http://stefanocasazza.github.io/ULib/) portion of a [benchmar
 * [Database test source (SQL)](src/db.usp)
 * [Database test source (SQL)](src/db.usp)
 * [Database test source (REDIS)](src/rdb.usp)
 * [Database test source (REDIS)](src/rdb.usp)
 * [Database test source (MONGODB)](src/mdb.usp)
 * [Database test source (MONGODB)](src/mdb.usp)
+* [Database test source (ELASTICSEARCH)](src/edb.usp)
 
 
 ### Variable Query Test
 ### Variable Query Test
 
 
 * [Variable Query test source (SQL)](src/query.usp)
 * [Variable Query test source (SQL)](src/query.usp)
 * [Variable Query test source (REDIS)](src/rquery.usp)
 * [Variable Query test source (REDIS)](src/rquery.usp)
 * [Variable Query test source (MONGODB)](src/mquery.usp)
 * [Variable Query test source (MONGODB)](src/mquery.usp)
+* [Variable Query test source (ELASTICSEARCH)](src/equery.usp)
 
 
 ### Fortune Query Test
 ### Fortune Query Test
 
 
@@ -29,6 +31,7 @@ This is the [ULib](http://stefanocasazza.github.io/ULib/) portion of a [benchmar
 * [Variable Query (update) test source (SQL)](src/update.usp)
 * [Variable Query (update) test source (SQL)](src/update.usp)
 * [Variable Query (update) test source (REDIS)](src/rupdate.usp)
 * [Variable Query (update) test source (REDIS)](src/rupdate.usp)
 * [Variable Query (update) test source (MONGODB)](src/mupdate.usp)
 * [Variable Query (update) test source (MONGODB)](src/mupdate.usp)
+* [Variable Query (update) test source (ELASTICSEARCH)](src/eupdate.usp)
 
 
 ### Plaintext Test
 ### Plaintext Test
 
 

+ 55 - 1
frameworks/C++/ulib/benchmark_config.json

@@ -19,7 +19,7 @@
       "notes": "",
       "notes": "",
       "versus": ""
       "versus": ""
     },
     },
-    "json": {
+    "json_normal": {
       "setup_file": "setup_json",
       "setup_file": "setup_json",
       "json_url": "/json",
       "json_url": "/json",
       "port": 8080,
       "port": 8080,
@@ -37,6 +37,60 @@
       "notes": "",
       "notes": "",
       "versus": ""
       "versus": ""
     },
     },
+    "json_medium": {
+      "setup_file": "setup_json_medium",
+      "json_url": "/json",
+      "port": 8080,
+      "approach": "Realistic",
+      "classification": "Platform",
+      "database": "None",
+      "framework": "ULib",
+      "language": "C++",
+      "orm": "Micro",
+      "platform": "ULib",
+      "webserver": "ULib",
+      "os": "Linux",
+      "database_os": "Linux",
+      "display_name": "ULib",
+      "notes": "",
+      "versus": ""
+    },
+    "json_large": {
+      "setup_file": "setup_json_large",
+      "json_url": "/json",
+      "port": 8080,
+      "approach": "Realistic",
+      "classification": "Platform",
+      "database": "None",
+      "framework": "ULib",
+      "language": "C++",
+      "orm": "Micro",
+      "platform": "ULib",
+      "webserver": "ULib",
+      "os": "Linux",
+      "database_os": "Linux",
+      "display_name": "ULib",
+      "notes": "",
+      "versus": ""
+    },
+    "json_extra": {
+      "setup_file": "setup_json_extra",
+      "json_url": "/json",
+      "port": 8080,
+      "approach": "Realistic",
+      "classification": "Platform",
+      "database": "None",
+      "framework": "ULib",
+      "language": "C++",
+      "orm": "Micro",
+      "platform": "ULib",
+      "webserver": "ULib",
+      "os": "Linux",
+      "database_os": "Linux",
+      "display_name": "ULib",
+      "notes": "",
+      "versus": ""
+    },
     "mysql": {
     "mysql": {
       "setup_file": "setup_mysql",
       "setup_file": "setup_mysql",
       "db_url": "/db",
       "db_url": "/db",

+ 24 - 0
frameworks/C++/ulib/setup_elasticsearch.sh

@@ -0,0 +1,24 @@
+#!/bin/bash
+
+fw_depends ulib
+
+MAX_THREADS=$(( 2 * $MAX_THREADS ))
+
+# 1. Change ULib Server (userver_tcp) configuration
+sed -i "s|TCP_LINGER_SET .*|TCP_LINGER_SET 0|g"									  $IROOT/ULib/benchmark.cfg
+sed -i "s|LISTEN_BACKLOG .*|LISTEN_BACKLOG 256|g"								  $IROOT/ULib/benchmark.cfg
+sed -i "s|PREFORK_CHILD .*|PREFORK_CHILD ${MAX_THREADS}|g"					  $IROOT/ULib/benchmark.cfg
+sed -i "s|CLIENT_FOR_PARALLELIZATION .*|CLIENT_FOR_PARALLELIZATION 100|g" $IROOT/ULib/benchmark.cfg
+
+# 2. Start ULib Server (userver_tcp)
+export ELASTICSEARCH_HOST=$DBHOST
+export UMEMPOOL="1261,0,0,49,274,-14,-15,-24,40"
+
+# Never use setcap inside of TRAVIS 
+[ "$TRAVIS" != "true" ] || { \
+if [ `ulimit -r` -eq 99 ]; then
+	sudo setcap cap_sys_nice,cap_sys_resource,cap_net_bind_service,cap_net_raw+eip $IROOT/ULib/bin/userver_tcp
+fi
+}
+
+$IROOT/ULib/bin/userver_tcp -c $IROOT/ULib/benchmark.cfg &

+ 2 - 4
frameworks/C++/ulib/setup_json.sh

@@ -2,10 +2,8 @@
 
 
 fw_depends ulib
 fw_depends ulib
 
 
-# Travis is broken
-if [ "$TRAVIS" != "true" ]; then
-MAX_THREADS=$(( 3 * $MAX_THREADS / 2 ))
-else
+# Travis is really broken!!
+if [ "$TRAVIS" == "true" ]; then
 MAX_THREADS=$(( 2 * $MAX_THREADS ))
 MAX_THREADS=$(( 2 * $MAX_THREADS ))
 fi
 fi
 
 

+ 28 - 0
frameworks/C++/ulib/setup_json_extra.sh

@@ -0,0 +1,28 @@
+#!/bin/bash
+
+fw_depends ulib
+
+# Travis is broken
+if [ "$TRAVIS" != "true" ]; then
+MAX_THREADS=$(( 3 * $MAX_THREADS ))
+else
+MAX_THREADS=$(( 2 * $MAX_THREADS ))
+fi
+
+# 1. Change ULib Server (userver_tcp) configuration
+sed -i "s|TCP_LINGER_SET .*|TCP_LINGER_SET 0|g"									  $IROOT/ULib/benchmark.cfg
+sed -i "s|LISTEN_BACKLOG .*|LISTEN_BACKLOG 256|g"								  $IROOT/ULib/benchmark.cfg
+sed -i "s|PREFORK_CHILD .*|PREFORK_CHILD ${MAX_THREADS}|g"					  $IROOT/ULib/benchmark.cfg
+sed -i "s|CLIENT_FOR_PARALLELIZATION .*|CLIENT_FOR_PARALLELIZATION 100|g" $IROOT/ULib/benchmark.cfg
+
+# 2. Start ULib Server (userver_tcp)
+export UMEMPOOL="58,0,0,41,273,-15,-14,-20,36"
+
+# Never use setcap inside of TRAVIS 
+[ "$TRAVIS" != "true" ] || { \
+if [ `ulimit -r` -eq 99 ]; then
+	sudo setcap cap_sys_nice,cap_sys_resource,cap_net_bind_service,cap_net_raw+eip $IROOT/ULib/bin/userver_tcp
+fi
+}
+
+$IROOT/ULib/bin/userver_tcp -c $IROOT/ULib/benchmark.cfg &

+ 23 - 0
frameworks/C++/ulib/setup_json_large.sh

@@ -0,0 +1,23 @@
+#!/bin/bash
+
+fw_depends ulib
+
+MAX_THREADS=$(( 2 * $MAX_THREADS ))
+
+# 1. Change ULib Server (userver_tcp) configuration
+sed -i "s|TCP_LINGER_SET .*|TCP_LINGER_SET 0|g"									  $IROOT/ULib/benchmark.cfg
+sed -i "s|LISTEN_BACKLOG .*|LISTEN_BACKLOG 256|g"								  $IROOT/ULib/benchmark.cfg
+sed -i "s|PREFORK_CHILD .*|PREFORK_CHILD ${MAX_THREADS}|g"					  $IROOT/ULib/benchmark.cfg
+sed -i "s|CLIENT_FOR_PARALLELIZATION .*|CLIENT_FOR_PARALLELIZATION 100|g" $IROOT/ULib/benchmark.cfg
+
+# 2. Start ULib Server (userver_tcp)
+export UMEMPOOL="58,0,0,41,273,-15,-14,-20,36"
+
+# Never use setcap inside of TRAVIS 
+[ "$TRAVIS" != "true" ] || { \
+if [ `ulimit -r` -eq 99 ]; then
+	sudo setcap cap_sys_nice,cap_sys_resource,cap_net_bind_service,cap_net_raw+eip $IROOT/ULib/bin/userver_tcp
+fi
+}
+
+$IROOT/ULib/bin/userver_tcp -c $IROOT/ULib/benchmark.cfg &

+ 28 - 0
frameworks/C++/ulib/setup_json_medium.sh

@@ -0,0 +1,28 @@
+#!/bin/bash
+
+fw_depends ulib
+
+# Travis is broken
+if [ "$TRAVIS" != "true" ]; then
+MAX_THREADS=$(( 3 * $MAX_THREADS / 2 ))
+else
+MAX_THREADS=$(( 2 * $MAX_THREADS ))
+fi
+
+# 1. Change ULib Server (userver_tcp) configuration
+sed -i "s|TCP_LINGER_SET .*|TCP_LINGER_SET 0|g"									  $IROOT/ULib/benchmark.cfg
+sed -i "s|LISTEN_BACKLOG .*|LISTEN_BACKLOG 256|g"								  $IROOT/ULib/benchmark.cfg
+sed -i "s|PREFORK_CHILD .*|PREFORK_CHILD ${MAX_THREADS}|g"					  $IROOT/ULib/benchmark.cfg
+sed -i "s|CLIENT_FOR_PARALLELIZATION .*|CLIENT_FOR_PARALLELIZATION 100|g" $IROOT/ULib/benchmark.cfg
+
+# 2. Start ULib Server (userver_tcp)
+export UMEMPOOL="58,0,0,41,273,-15,-14,-20,36"
+
+# Never use setcap inside of TRAVIS 
+[ "$TRAVIS" != "true" ] || { \
+if [ `ulimit -r` -eq 99 ]; then
+	sudo setcap cap_sys_nice,cap_sys_resource,cap_net_bind_service,cap_net_raw+eip $IROOT/ULib/bin/userver_tcp
+fi
+}
+
+$IROOT/ULib/bin/userver_tcp -c $IROOT/ULib/benchmark.cfg &

+ 3 - 0
frameworks/C++/ulib/source_code

@@ -1,13 +1,16 @@
 ./src/db.usp
 ./src/db.usp
+./src/edb.usp
 ./src/rdb.usp
 ./src/rdb.usp
 ./src/mdb.usp
 ./src/mdb.usp
 ./src/world.h
 ./src/world.h
 ./src/json.usp
 ./src/json.usp
 ./src/fortune.h
 ./src/fortune.h
 ./src/query.usp
 ./src/query.usp
+./src/equery.usp
 ./src/rquery.usp
 ./src/rquery.usp
 ./src/mquery.usp
 ./src/mquery.usp
 ./src/update.usp
 ./src/update.usp
+./src/eupdate.usp
 ./src/rupdate.usp
 ./src/rupdate.usp
 ./src/mupdate.usp
 ./src/mupdate.usp
 ./src/fortune.usp
 ./src/fortune.usp

+ 5 - 5
frameworks/C++/ulib/src/db.usp

@@ -17,21 +17,21 @@ static void usp_fork_db()
 {
 {
    U_TRACE(5, "::usp_fork_db()")
    U_TRACE(5, "::usp_fork_db()")
 
 
-   psql_db = U_NEW(UOrmSession(U_CONSTANT_TO_PARAM("hello_world")));
+   U_NEW(UOrmSession, psql_db, UOrmSession(U_CONSTANT_TO_PARAM("hello_world")));
 
 
    if (psql_db->isReady())
    if (psql_db->isReady())
       {
       {
-      pstmt_db = U_NEW(UOrmStatement(*psql_db, U_CONSTANT_TO_PARAM("SELECT randomNumber FROM World WHERE id = ?")));
+      U_NEW(UOrmStatement, pstmt_db, UOrmStatement(*psql_db, U_CONSTANT_TO_PARAM("SELECT randomNumber FROM World WHERE id = ?")));
 
 
       if (pstmt_db == 0) U_WARNING("usp_fork_db(): we cound't connect to db");
       if (pstmt_db == 0) U_WARNING("usp_fork_db(): we cound't connect to db");
 
 
-      pworld_db = U_NEW(World);
+      U_NEW(World, pworld_db, World);
 
 
       pstmt_db->use( pworld_db->id);
       pstmt_db->use( pworld_db->id);
       pstmt_db->into(pworld_db->randomNumber);
       pstmt_db->into(pworld_db->randomNumber);
 
 
 #  ifndef AS_cpoll_cppsp_DO
 #  ifndef AS_cpoll_cppsp_DO
-      pvalue = U_NEW(UValue(OBJECT_VALUE));
+      U_NEW(UValue, pvalue, UValue(OBJECT_VALUE));
 #  endif
 #  endif
       }
       }
 }
 }
@@ -58,7 +58,7 @@ static void usp_end_db()
 Content-Type: application/json
 Content-Type: application/json
 -->
 -->
 <!--#code
 <!--#code
-pworld_db->id = u_get_num_random(10000);
+pworld_db->id = u_get_num_random(10000-1);
 
 
 pstmt_db->execute();
 pstmt_db->execute();
 
 

+ 68 - 0
frameworks/C++/ulib/src/edb.usp

@@ -0,0 +1,68 @@
+<!--#
+Test type 2: Single database query
+TechEmpower Web Framework Benchmarks
+-->
+<!--#declaration
+#include "world.h"
+
+static char buffer[128];
+static UElasticSearchClient* es;
+
+#ifndef AS_cpoll_cppsp_DO
+static UValue*	pvalue;
+#endif
+
+#define QLEN U_CONSTANT_SIZE("{\"query\":{\"match\":{\"_id\":\"")
+
+static void usp_fork_edb()
+{
+	U_TRACE(5, "::usp_fork_edb()")
+
+	U_NEW(UElasticSearchClient, es, UElasticSearchClient);
+
+	if (es->connect() == false)
+		{
+		U_WARNING("usp_fork_edb(): connection disabled or failed");
+
+		return;
+		}
+
+	u__memcpy(buffer,	"{\"query\":{\"match\":{\"_id\":\"", QLEN, __PRETTY_FUNCTION__);
+
+#ifndef AS_cpoll_cppsp_DO
+	U_NEW(UValue, pvalue, UValue(OBJECT_VALUE));
+#endif
+}
+
+#ifdef DEBUG
+static void usp_end_edb()
+{
+	U_TRACE(5, "::usp_end_edb()")
+
+	delete es;
+
+#ifndef AS_cpoll_cppsp_DO
+	if (pvalue) delete pvalue;
+#endif
+}
+#endif
+-->
+<!--#header
+Content-Type: application/json
+-->
+<!--#code
+uint32_t id;
+UString result;
+
+(void) es->sendPOST(U_CONSTANT_TO_PARAM("/tfb/world/_search"), buffer, u__snprintf(buffer+QLEN, 128, "%u\"}}}", id = u_get_num_random(10000-1))+QLEN);
+
+(void) UValue::jfind(es->getContent(), U_CONSTANT_TO_PARAM("randomNumber"), result);
+
+#ifdef AS_cpoll_cppsp_DO
+USP_PRINTF_ADD("{\"id\":%u,\"randomNumber\":%v}", id, result.rep);
+#else
+World world(id, u_strtoul(result.data(), result.end()));
+USP_JSON_stringify(*pvalue, World, world);
+pvalue->clear();
+#endif
+-->

+ 102 - 0
frameworks/C++/ulib/src/equery.usp

@@ -0,0 +1,102 @@
+<!--#
+Test type 3: Multiple database queries
+TechEmpower Web Framework Benchmarks
+-->
+<!--#declaration
+#include "world.h"
+
+static char buffer[128];
+static UElasticSearchClient* es;
+
+#ifndef AS_cpoll_cppsp_DO
+static UValue* pvalue;
+static UVector<World*>* pvworld_query;
+#endif
+
+#define QLEN U_CONSTANT_SIZE("{\"query\":{\"match\":{\"_id\":\"")
+
+static void usp_fork_equery()
+{
+   U_TRACE(5, "::usp_fork_equery()")
+
+   U_NEW(UElasticSearchClient, es, UElasticSearchClient);
+
+   if (es->connect() == false)
+      {
+      U_WARNING("usp_fork_equery(): connection disabled or failed");
+
+      return;
+      }
+
+   u__memcpy(buffer, "{\"query\":{\"match\":{\"_id\":\"", QLEN, __PRETTY_FUNCTION__);
+
+#ifndef AS_cpoll_cppsp_DO
+   U_NEW(UValue, pvalue, UValue(ARRAY_VALUE));
+   U_NEW(UVector<World*>, pvworld_query, UVector<World*>(500));
+#endif
+}
+
+#ifdef DEBUG
+static void usp_end_equery()
+{
+   U_TRACE(5, "::usp_end_equery()")
+
+   delete es;
+
+#ifndef AS_cpoll_cppsp_DO
+   if (pvalue)
+      {
+      delete pvalue;
+      delete pvworld_query;
+      }
+#endif
+}
+#endif
+-->
+<!--#header
+Content-Type: application/json
+-->
+<!--#code
+uint32_t id;
+UString rnumber;
+int i = 0, num_queries = UHTTP::getFormFirstNumericValue(1, 500);
+
+#ifdef AS_cpoll_cppsp_DO
+USP_PUTS_CHAR('[');
+#endif
+
+while (true)
+   {
+   (void) es->sendPOST(U_CONSTANT_TO_PARAM("/tfb/world/_search"), buffer, QLEN+u__snprintf(buffer+QLEN, 128, "%u\"}}}", id = u_get_num_random(10000-1)));
+
+   rnumber.clear();
+
+   (void) UValue::jfind(es->getContent(), U_CONSTANT_TO_PARAM("randomNumber"), rnumber);
+
+#ifdef AS_cpoll_cppsp_DO
+   USP_PRINTF("{\"id\":%u,\"randomNumber\":%v}", id, rnumber.rep);
+#else
+   World* pworld;
+
+   U_NEW(World, pworld, World(id, u_strtoul(rnumber.data(), rnumber.end())));
+
+   pvworld_query->push_back(pworld);
+#endif
+
+   if (++i == num_queries) break;
+
+#ifdef AS_cpoll_cppsp_DO
+   USP_PUTS_CHAR(',');
+#endif
+
+   rnumber.clear();
+   }
+
+#ifdef AS_cpoll_cppsp_DO
+USP_PUTS_CHAR(']');
+#else
+USP_JSON_stringify(*pvalue, UVector<World*>, *pvworld_query);
+pvalue->clear();
+pvworld_query->clear();
+#endif
+-->

+ 108 - 0
frameworks/C++/ulib/src/eupdate.usp

@@ -0,0 +1,108 @@
+<!--#
+Test type 5: Database updates
+TechEmpower Web Framework Benchmarks
+-->
+<!--#declaration
+#include "world.h"
+
+static char* pbuffer1;
+static char* pbuffer2;
+static char buffer1[128];
+static char buffer2[128];
+static UElasticSearchClient* es;
+
+#ifndef AS_cpoll_cppsp_DO
+static UValue* pvalue;
+static UVector<World*>* pvworld_update;
+#endif
+
+#define ULEN U_CONSTANT_SIZE("/tfb/world/")
+#define QLEN U_CONSTANT_SIZE("{\"doc\":{\"_id\":\"")
+
+static void usp_fork_eupdate()
+{
+   U_TRACE(5, "::usp_fork_eupdate()")
+
+   U_NEW(UElasticSearchClient, es, UElasticSearchClient);
+
+   if (es->connect() == false)
+      {
+      U_WARNING("usp_fork_eupdate(): connection disabled or failed");
+
+      return;
+      }
+
+   u__memcpy(buffer1, "/tfb/world/", ULEN, __PRETTY_FUNCTION__);
+
+   pbuffer1 = buffer1 + ULEN;
+
+   u__memcpy(buffer2, "{\"doc\":{\"_id\":\"", QLEN, __PRETTY_FUNCTION__);
+
+   pbuffer2 = buffer2 + QLEN;
+
+#ifndef AS_cpoll_cppsp_DO
+   U_NEW(UValue, pvalue, UValue(ARRAY_VALUE));
+   U_NEW(UVector<World*>, pvworld_update, UVector<World*>(500));
+#endif
+}
+
+#ifdef DEBUG
+static void usp_end_eupdate()
+{
+   U_TRACE(5, "::usp_end_eupdate()")
+
+   delete es;
+
+#ifndef AS_cpoll_cppsp_DO
+   if (pvalue)
+      {
+      delete pvalue;
+      delete pvworld_update;
+      }
+#endif
+}
+#endif
+-->
+<!--#header
+Content-Type: application/json
+-->
+<!--#code
+uint32_t len1, len2, id, rnum;
+int i = 0, num_queries = UHTTP::getFormFirstNumericValue(1, 500);
+
+#ifdef AS_cpoll_cppsp_DO
+USP_PUTS_CHAR('[');
+#endif
+
+while (true)
+   {
+   len1 = u__snprintf(pbuffer1, 100, "%u/_update", id = u_get_num_random(10000-1));
+   len2 = u__snprintf(pbuffer2, 100, "%u\"}}",   rnum = u_get_num_random(10000-1));
+
+   (void) es->sendPOST(buffer1, len1+ULEN, buffer2, len2+QLEN);
+
+#ifdef AS_cpoll_cppsp_DO
+   USP_PRINTF("{\"id\":%u,\"randomNumber\":%u}", id, rnum);
+#else
+   World* pworld;
+
+   U_NEW(World, pworld, World(id, rnum));
+
+   pvworld_update->push_back(pworld);
+#endif
+
+   if (++i == num_queries) break;
+
+#ifdef AS_cpoll_cppsp_DO
+   USP_PUTS_CHAR(',');
+#endif
+   }
+
+#ifdef AS_cpoll_cppsp_DO
+USP_PUTS_CHAR(']');
+#else
+USP_JSON_stringify(*pvalue, UVector<World*>, *pvworld_update);
+pvalue->clear();
+pvworld_update->clear();
+#endif
+-->

+ 16 - 8
frameworks/C++/ulib/src/fortune.usp

@@ -16,23 +16,23 @@ static void usp_fork_fortune()
 {
 {
    U_TRACE(5, "::usp_fork_fortune()")
    U_TRACE(5, "::usp_fork_fortune()")
 
 
-   psql_fortune = U_NEW(UOrmSession(U_CONSTANT_TO_PARAM("fortune")));
+   U_NEW(UOrmSession, psql_fortune, UOrmSession(U_CONSTANT_TO_PARAM("fortune")));
 
 
    if (psql_fortune->isReady())
    if (psql_fortune->isReady())
       {
       {
-      pstmt_fortune = U_NEW(UOrmStatement(*psql_fortune, U_CONSTANT_TO_PARAM("SELECT id, message FROM Fortune")));
+      U_NEW(UOrmStatement, pstmt_fortune, UOrmStatement(*psql_fortune, U_CONSTANT_TO_PARAM("SELECT id, message FROM Fortune")));
 
 
       if (pstmt_fortune == 0) U_WARNING("usp_fork_fortune(): we cound't connect to db");
       if (pstmt_fortune == 0) U_WARNING("usp_fork_fortune(): we cound't connect to db");
 
 
       if (UOrmDriver::isPGSQL()) *psql_fortune << "BEGIN ISOLATION LEVEL SERIALIZABLE; COMMIT";
       if (UOrmDriver::isPGSQL()) *psql_fortune << "BEGIN ISOLATION LEVEL SERIALIZABLE; COMMIT";
 
 
-      pfortune = U_NEW(Fortune);
+      U_NEW(Fortune, pfortune, Fortune);
 
 
       pstmt_fortune->into(*pfortune);
       pstmt_fortune->into(*pfortune);
 
 
-      pencoded     = U_NEW(UString(100U));
-      pvfortune    = U_NEW(UVector<Fortune*>);
-      pfortune2add = U_NEW(Fortune(0, U_STRING_FROM_CONSTANT("Additional fortune added at request time.")));
+      U_NEW(UString, pencoded, UString(100U));
+      U_NEW(UVector<Fortune*>, pvfortune, UVector<Fortune*>);
+      U_NEW(Fortune, pfortune2add, Fortune(0, U_STRING_FROM_CONSTANT("Additional fortune added at request time.")));
       }
       }
 }
 }
 
 
@@ -55,10 +55,18 @@ static void usp_end_fortune()
 #endif
 #endif
 -->
 -->
 <!doctype html><html><head><title>Fortunes</title></head><body><table><tr><th>id</th><th>message</th></tr><!--#code
 <!doctype html><html><head><title>Fortunes</title></head><body><table><tr><th>id</th><th>message</th></tr><!--#code
+Fortune* item;
+
+U_NEW(Fortune, item, Fortune(*pfortune2add));
+pvfortune->push_back(item);
+
 pstmt_fortune->execute();
 pstmt_fortune->execute();
 
 
-     pvfortune->push_back(U_NEW(Fortune(*pfortune2add)));
-do { pvfortune->push_back(U_NEW(Fortune(*pfortune))); } while (pstmt_fortune->nextRow());
+do {
+   U_NEW(Fortune, item, Fortune(*pfortune));
+   pvfortune->push_back(item);
+   }
+while (pstmt_fortune->nextRow());
 
 
 pvfortune->sort(Fortune::cmp_obj);
 pvfortune->sort(Fortune::cmp_obj);
 
 

+ 2 - 2
frameworks/C++/ulib/src/json.usp

@@ -18,8 +18,8 @@ static void usp_init_json()
    U_TRACE(5, "::usp_init_json()")
    U_TRACE(5, "::usp_init_json()")
 
 
 #ifndef AS_cpoll_cppsp_DO
 #ifndef AS_cpoll_cppsp_DO
-   pkey   = U_NEW(U_STRING_FROM_CONSTANT("message"));
-   pvalue = U_NEW(U_STRING_FROM_CONSTANT("Hello, World!"));
+   U_NEW(UString, pkey,   U_STRING_FROM_CONSTANT("message"));
+   U_NEW(UString, pvalue, U_STRING_FROM_CONSTANT("Hello, World!"));
 #endif
 #endif
 }
 }
 
 

+ 25 - 36
frameworks/C++/ulib/src/mdb.usp

@@ -5,58 +5,47 @@ TechEmpower Web Framework Benchmarks
 <!--#declaration
 <!--#declaration
 #include "world.h"
 #include "world.h"
 
 
-static World* pworld;
-static UString* jquery;
 static UMongoDBClient* mc;
 static UMongoDBClient* mc;
 
 
 #ifndef AS_cpoll_cppsp_DO
 #ifndef AS_cpoll_cppsp_DO
-static UValue* pvalue;
+static UValue*	pvalue;
 #endif
 #endif
 
 
 static void usp_fork_mdb()
 static void usp_fork_mdb()
 {
 {
-   U_TRACE(5, "::usp_fork_mdb()")
+	U_TRACE(5, "::usp_fork_mdb()")
 
 
-   mc = U_NEW(UMongoDBClient);
+	U_NEW(UMongoDBClient, mc, UMongoDBClient);
 
 
-   if (mc->connect() == false)
-      {
-      U_WARNING("usp_fork_mdb(): connection failed");
+	if (mc->connect() == false)
+		{
+		U_WARNING("usp_fork_mdb(): connection failed");
 
 
-      return;
-      }
+		return;
+		}
 
 
-   if (mc->selectCollection("hello_world", "World") == false)
-      {
-      U_WARNING("usp_fork_mdb(): selectCollection() failed");
+	if (mc->selectCollection("hello_world", "World") == false)
+		{
+		U_WARNING("usp_fork_mdb(): selectCollection() failed");
 
 
-      return;
-      }
-
-   pworld = U_NEW(World);
-   jquery = U_NEW(U_STRING_FROM_CONSTANT("{'randomNumber'"));
+		return;
+		}
 
 
 #ifndef AS_cpoll_cppsp_DO
 #ifndef AS_cpoll_cppsp_DO
-   pvalue = U_NEW(UValue(OBJECT_VALUE));
+	U_NEW(UValue, pvalue, UValue(OBJECT_VALUE));
 #endif
 #endif
 }
 }
 
 
 #ifdef DEBUG
 #ifdef DEBUG
 static void usp_end_mdb()
 static void usp_end_mdb()
 {
 {
-   U_TRACE(5, "::usp_end_mdb()")
-
-   delete mc;
+	U_TRACE(5, "::usp_end_mdb()")
 
 
-   if (pworld)
-      {
-      delete pworld;
-      delete jquery;
+	delete mc;
 
 
-#  ifndef AS_cpoll_cppsp_DO
-      delete pvalue;
-#  endif
-      }
+#ifndef AS_cpoll_cppsp_DO
+	if (pvalue) delete pvalue;
+#endif
 }
 }
 #endif
 #endif
 -->
 -->
@@ -64,18 +53,18 @@ static void usp_end_mdb()
 Content-Type: application/json
 Content-Type: application/json
 -->
 -->
 <!--#code
 <!--#code
+uint32_t id;
 UString result;
 UString result;
 
 
-(void) mc->findOne(pworld->id = u_get_num_random(10000));
-
-(void) UValue::jread(mc->vitem[0], *jquery, result); // { "_id" : 8980.000000, "id" : 8980.000000, "randomNumber" : 2131.000000 }
+(void) mc->findOne(id = u_get_num_random(10000-1));
 
 
-pworld->randomNumber = u_strtoul(result.data(), result.end());
+(void) UValue::jfind(mc->vitem[0], U_CONSTANT_TO_PARAM("randomNumber"), result);
 
 
 #ifdef AS_cpoll_cppsp_DO
 #ifdef AS_cpoll_cppsp_DO
-USP_PRINTF_ADD("{\"id\":%u,\"randomNumber\":%v}", pworld->id, result.rep);
+USP_PRINTF_ADD("{\"id\":%u,\"randomNumber\":%v}", id, result.rep);
 #else
 #else
-USP_JSON_stringify(*pvalue, World, *pworld);
+World world(id, u_strtoul(result.data(), result.end()));
+USP_JSON_stringify(*pvalue, World, world);
 pvalue->clear();
 pvalue->clear();
 #endif
 #endif
 -->
 -->

+ 48 - 44
frameworks/C++/ulib/src/mfortune.usp

@@ -5,7 +5,6 @@ TechEmpower Web Framework Benchmarks
 <!--#declaration
 <!--#declaration
 #include "fortune.h"
 #include "fortune.h"
 
 
-static UString* jquery;
 static UString* pencoded;
 static UString* pencoded;
 static UMongoDBClient* mc;
 static UMongoDBClient* mc;
 static Fortune* pfortune2add;
 static Fortune* pfortune2add;
@@ -13,77 +12,82 @@ static UVector<Fortune*>* pvfortune;
 
 
 static void usp_fork_mfortune()
 static void usp_fork_mfortune()
 {
 {
-   U_TRACE(5, "::usp_fork_mfortune()")
+	U_TRACE(5, "::usp_fork_mfortune()")
 
 
-   mc = U_NEW(UMongoDBClient);
+	U_NEW(UMongoDBClient, mc, UMongoDBClient);
 
 
-   if (mc->connect() == false)
-      {
-      U_WARNING("usp_fork_mfortune(): connection failed");
+	if (mc->connect() == false)
+		{
+		U_WARNING("usp_fork_mfortune(): connection failed");
 
 
-      return;
-      }
+		return;
+		}
 
 
-   if (mc->selectCollection("hello_world", "Fortune") == false)
-      {
-      U_WARNING("usp_fork_mfortune(): selectCollection() failed");
+	if (mc->selectCollection("hello_world", "Fortune") == false)
+		{
+		U_WARNING("usp_fork_mfortune(): selectCollection() failed");
 
 
-      return;
-      }
+		return;
+		}
 
 
-   jquery       = U_NEW(U_STRING_FROM_CONSTANT("{'message'"));
-   pencoded     = U_NEW(UString(100U));
-   pvfortune    = U_NEW(UVector<Fortune*>);
-   pfortune2add = U_NEW(Fortune(0, U_STRING_FROM_CONSTANT("Additional fortune added at request time.")));
+	U_NEW(UString, pencoded, UString(100U));
+	U_NEW(UVector<Fortune*>, pvfortune, UVector<Fortune*>);
+	U_NEW(Fortune, pfortune2add, Fortune(0, U_STRING_FROM_CONSTANT("Additional fortune added at request time.")));
 }
 }
 
 
 #ifdef DEBUG
 #ifdef DEBUG
 static void usp_end_mfortune()
 static void usp_end_mfortune()
 {
 {
-   U_TRACE(5, "::usp_end_mfortune()")
+	U_TRACE(5, "::usp_end_mfortune()")
 
 
-   delete mc;
+	delete mc;
 
 
-   if (jquery)
-      {
-      delete jquery;
-      delete pencoded;
-      delete pvfortune;
-      delete pfortune2add;
-      }
+	if (pencoded)
+		{
+		delete pencoded;
+		delete pvfortune;
+		delete pfortune2add;
+		}
 }
 }
 #endif
 #endif
 -->
 -->
 <!doctype html><html><head><title>Fortunes</title></head><body><table><tr><th>id</th><th>message</th></tr><!--#code
 <!doctype html><html><head><title>Fortunes</title></head><body><table><tr><th>id</th><th>message</th></tr><!--#code
+Fortune* item;
 uint32_t i, n;
 uint32_t i, n;
 UString result;
 UString result;
 
 
-(void) mc->findAll();
+U_NEW(Fortune, item, Fortune(*pfortune2add));
+
+pvfortune->push_back(item);
 
 
-pvfortune->push_back(U_NEW(Fortune(*pfortune2add)));
+(void) mc->findAll();
 
 
 for (i = 0, n = mc->vitem.size(); i < n; ++i)
 for (i = 0, n = mc->vitem.size(); i < n; ++i)
-   {
-   (void) UValue::jread(mc->vitem[i], *jquery, result); // { "_id" : 5.000000, "id" : 5.000000, "message" : "A computer program does what you tell it to do, not what you want it to do." }
+	{
+	result.clear();
+
+	(void) UValue::jfind(mc->vitem[i], U_CONSTANT_TO_PARAM("message"), result);
+
+   U_NEW(Fortune, item, Fortune(i+1, result));
 
 
-   pvfortune->push_back(U_NEW(Fortune(i+1, result)));
-   }
+   pvfortune->push_back(item);
+	}
 
 
 pvfortune->sort(Fortune::cmp_obj);
 pvfortune->sort(Fortune::cmp_obj);
 
 
 for (i = 0, ++n; i < n; ++i)
 for (i = 0, ++n; i < n; ++i)
-   {
-   Fortune* elem = (*pvfortune)[i];
-
-   UXMLEscape::encode(elem->message, *pencoded);
-
-   USP_PRINTF_ADD(
-      "<tr>"
-      "<td>%u</td>"
-      "<td>%v</td>"
-      "</tr>",
-      elem->id, pencoded->rep);
-   }
+	{
+	Fortune* elem = (*pvfortune)[i];
+
+	UXMLEscape::encode(elem->message, *pencoded);
+
+	USP_PRINTF_ADD(
+		"<tr>"
+		"<td>%u</td>"
+		"<td>%v</td>"
+		"</tr>",
+		elem->id, pencoded->rep);
+	}
 
 
 pvfortune->clear();
 pvfortune->clear();
 --></table></body></html>
 --></table></body></html>

+ 38 - 41
frameworks/C++/ulib/src/mquery.usp

@@ -5,61 +5,53 @@ TechEmpower Web Framework Benchmarks
 <!--#declaration
 <!--#declaration
 #include "world.h"
 #include "world.h"
 
 
-static UString* jquery;
 static UMongoDBClient* mc;
 static UMongoDBClient* mc;
-static World* pworld_query;
 
 
 #ifndef AS_cpoll_cppsp_DO
 #ifndef AS_cpoll_cppsp_DO
-static UValue* pvalue;
+static UValue*	pvalue;
 static UVector<World*>* pvworld_query;
 static UVector<World*>* pvworld_query;
 #endif
 #endif
 
 
 static void usp_fork_mquery()
 static void usp_fork_mquery()
 {
 {
-   U_TRACE(5, "::usp_fork_mquery()")
+	U_TRACE(5, "::usp_fork_mquery()")
 
 
-   mc = U_NEW(UMongoDBClient);
+   U_NEW(UMongoDBClient, mc, UMongoDBClient);
 
 
-   if (mc->connect() == false)
-      {
-      U_WARNING("usp_fork_mquery(): connection disabled or failed");
+	if (mc->connect() == false)
+		{
+		U_WARNING("usp_fork_mquery(): connection disabled or failed");
 
 
-      return;
-      }
+		return;
+		}
 
 
-   if (mc->selectCollection("hello_world", "World") == false)
-      {
-      U_WARNING("usp_fork_mquery(): selectCollection() failed");
+	if (mc->selectCollection("hello_world", "World") == false)
+		{
+		U_WARNING("usp_fork_mquery(): selectCollection() failed");
 
 
-      return;
-      }
-
-   jquery       = U_NEW(U_STRING_FROM_CONSTANT("{'randomNumber'"));
-   pworld_query = U_NEW(World);
+		return;
+		}
 
 
 #ifndef AS_cpoll_cppsp_DO
 #ifndef AS_cpoll_cppsp_DO
-   pvalue        = U_NEW(UValue(ARRAY_VALUE));
-   pvworld_query = U_NEW(UVector<World*>(500));
+	U_NEW(UValue, pvalue, UValue(ARRAY_VALUE));
+	U_NEW(UVector<World*>, pvworld_query, UVector<World*>(500));
 #endif
 #endif
 }
 }
 
 
 #ifdef DEBUG
 #ifdef DEBUG
 static void usp_end_mquery()
 static void usp_end_mquery()
 {
 {
-   U_TRACE(5, "::usp_end_mquery()")
-
-   delete mc;
+	U_TRACE(5, "::usp_end_mquery()")
 
 
-   if (jquery)
-      {
-      delete jquery;
-      delete pworld_query;
+	delete mc;
 
 
-#  ifndef AS_cpoll_cppsp_DO
-      delete pvalue;
-      delete pvworld_query;
-#  endif
-      }
+#ifndef AS_cpoll_cppsp_DO
+	if (pvalue)
+		{
+		delete pvalue;
+		delete pvworld_query;
+		}
+#endif
 }
 }
 #endif
 #endif
 -->
 -->
@@ -67,6 +59,7 @@ static void usp_end_mquery()
 Content-Type: application/json
 Content-Type: application/json
 -->
 -->
 <!--#code
 <!--#code
+uint32_t id;
 UString rnumber;
 UString rnumber;
 int i = 0, num_queries = UHTTP::getFormFirstNumericValue(1, 500);
 int i = 0, num_queries = UHTTP::getFormFirstNumericValue(1, 500);
 
 
@@ -75,25 +68,29 @@ USP_PUTS_CHAR('[');
 #endif
 #endif
 
 
 while (true)
 while (true)
-   {
-   (void) mc->findOne(pworld_query->id = u_get_num_random(10000));
+	{
+	(void) mc->findOne(id = u_get_num_random(10000-1));
+
+	rnumber.clear();
 
 
-   (void) UValue::jread(mc->vitem[0], *jquery, rnumber); // { "_id" : 8980.000000, "id" : 8980.000000, "randomNumber" : 2131.000000 }
+	(void) UValue::jfind(mc->vitem[0], U_CONSTANT_TO_PARAM("randomNumber"), rnumber);
 
 
 #ifdef AS_cpoll_cppsp_DO
 #ifdef AS_cpoll_cppsp_DO
-   USP_PRINTF("{\"id\":%u,\"randomNumber\":%v}", pworld_query->id, rnumber.rep);
+	USP_PRINTF("{\"id\":%u,\"randomNumber\":%v}", id, rnumber.rep);
 #else
 #else
-   pworld_query->randomNumber = u_strtoul(rnumber.data(), rnumber.end());
+	World* pworld;
+
+	U_NEW(World, pworld, World(id, u_strtoul(rnumber.data(), rnumber.end())));
 
 
-   pvworld_query->push_back(U_NEW(World(*pworld_query)));
+	pvworld_query->push_back(pworld);
 #endif
 #endif
 
 
-   if (++i == num_queries) break;
+	if (++i == num_queries) break;
 
 
 #ifdef AS_cpoll_cppsp_DO
 #ifdef AS_cpoll_cppsp_DO
-   USP_PUTS_CHAR(',');
+	USP_PUTS_CHAR(',');
 #endif
 #endif
-   }
+	}
 
 
 #ifdef AS_cpoll_cppsp_DO
 #ifdef AS_cpoll_cppsp_DO
 USP_PUTS_CHAR(']');
 USP_PUTS_CHAR(']');

+ 17 - 16
frameworks/C++/ulib/src/mupdate.usp

@@ -6,7 +6,6 @@ TechEmpower Web Framework Benchmarks
 #include "world.h"
 #include "world.h"
 
 
 static UMongoDBClient* mc;
 static UMongoDBClient* mc;
-static World* pworld_update;
 
 
 #ifndef AS_cpoll_cppsp_DO
 #ifndef AS_cpoll_cppsp_DO
 static UValue* pvalue;
 static UValue* pvalue;
@@ -17,7 +16,7 @@ static void usp_fork_mupdate()
 {
 {
    U_TRACE(5, "::usp_fork_mupdate()")
    U_TRACE(5, "::usp_fork_mupdate()")
 
 
-   mc = U_NEW(UMongoDBClient);
+   U_NEW(UMongoDBClient, mc, UMongoDBClient);
 
 
    if (mc->connect() == false)
    if (mc->connect() == false)
       {
       {
@@ -33,11 +32,9 @@ static void usp_fork_mupdate()
       return;
       return;
       }
       }
 
 
-   pworld_update = U_NEW(World);
-
 #ifndef AS_cpoll_cppsp_DO
 #ifndef AS_cpoll_cppsp_DO
-   pvalue         = U_NEW(UValue(ARRAY_VALUE));
-   pvworld_update = U_NEW(UVector<World*>(500));
+   U_NEW(UValue, pvalue, UValue(ARRAY_VALUE));
+   U_NEW(UVector<World*>, pvworld_update, UVector<World*>(500));
 #endif
 #endif
 }
 }
 
 
@@ -48,15 +45,13 @@ static void usp_end_mupdate()
 
 
    delete mc;
    delete mc;
 
 
-   if (pworld_update)
+#ifndef AS_cpoll_cppsp_DO
+   if (pvalue)
       {
       {
-      delete pworld_update;
-
-#  ifndef AS_cpoll_cppsp_DO
       delete pvalue;
       delete pvalue;
       delete pvworld_update;
       delete pvworld_update;
-#  endif
       }
       }
+#endif
 }
 }
 #endif
 #endif
 -->
 -->
@@ -64,6 +59,8 @@ static void usp_end_mupdate()
 Content-Type: application/json
 Content-Type: application/json
 -->
 -->
 <!--#code
 <!--#code
+uint32_t id, rnum;
+mongoc_bulk_operation_t* bulk = mc->createBulk(false);
 int i = 0, num_queries = UHTTP::getFormFirstNumericValue(1, 500);
 int i = 0, num_queries = UHTTP::getFormFirstNumericValue(1, 500);
 
 
 #ifdef AS_cpoll_cppsp_DO
 #ifdef AS_cpoll_cppsp_DO
@@ -72,14 +69,16 @@ USP_PUTS_CHAR('[');
 
 
 while (true)
 while (true)
    {
    {
-   (void) mc->findOne(pworld_update->id = u_get_num_random(10000));
-
-   (void) mc->update(pworld_update->id, "randomNumber", pworld_update->randomNumber = u_get_num_random(10000));
+   mc->updateOneBulk(bulk, id = u_get_num_random(10000-1), "randomNumber", rnum = u_get_num_random(10000-1));
 
 
 #ifdef AS_cpoll_cppsp_DO
 #ifdef AS_cpoll_cppsp_DO
-   USP_PRINTF("{\"id\":%u,\"randomNumber\":%u}", pworld_update->id, pworld_update->randomNumber);
+   USP_PRINTF("{\"id\":%u,\"randomNumber\":%u}", id, rnum);
 #else
 #else
-   pvworld_update->push_back(U_NEW(World(*pworld_update)));
+   World* pworld;
+
+   U_NEW(World, pworld, World(id, rnum));
+
+   pvworld_update->push_back(pworld);
 #endif
 #endif
 
 
    if (++i == num_queries) break;
    if (++i == num_queries) break;
@@ -89,6 +88,8 @@ while (true)
 #endif
 #endif
    }
    }
 
 
+(void) mc->executeBulk(bulk);
+
 #ifdef AS_cpoll_cppsp_DO
 #ifdef AS_cpoll_cppsp_DO
 USP_PUTS_CHAR(']');
 USP_PUTS_CHAR(']');
 #else
 #else

+ 11 - 7
frameworks/C++/ulib/src/query.usp

@@ -18,24 +18,24 @@ static void usp_fork_query()
 {
 {
    U_TRACE(5, "::usp_fork_query()")
    U_TRACE(5, "::usp_fork_query()")
 
 
-   psql_query = U_NEW(UOrmSession(U_CONSTANT_TO_PARAM("hello_world")));
+   U_NEW(UOrmSession, psql_query, UOrmSession(U_CONSTANT_TO_PARAM("hello_world")));
 
 
    if (psql_query->isReady())
    if (psql_query->isReady())
       {
       {
-      pstmt_query = U_NEW(UOrmStatement(*psql_query, U_CONSTANT_TO_PARAM("SELECT randomNumber FROM World WHERE id = ?")));
+      U_NEW(UOrmStatement, pstmt_query, UOrmStatement(*psql_query, U_CONSTANT_TO_PARAM("SELECT randomNumber FROM World WHERE id = ?")));
 
 
       if (pstmt_query == 0) U_WARNING("usp_fork_query(): we cound't connect to db");
       if (pstmt_query == 0) U_WARNING("usp_fork_query(): we cound't connect to db");
 
 
       if (UOrmDriver::isPGSQL()) *psql_query << "BEGIN TRANSACTION";
       if (UOrmDriver::isPGSQL()) *psql_query << "BEGIN TRANSACTION";
 
 
-      pworld_query = U_NEW(World);
+      U_NEW(World, pworld_query, World);
 
 
       pstmt_query->use( pworld_query->id);
       pstmt_query->use( pworld_query->id);
       pstmt_query->into(pworld_query->randomNumber);
       pstmt_query->into(pworld_query->randomNumber);
 
 
 #  ifndef AS_cpoll_cppsp_DO
 #  ifndef AS_cpoll_cppsp_DO
-      pvalue        = U_NEW(UValue(ARRAY_VALUE));
-      pvworld_query = U_NEW(UVector<World*>(500));
+      U_NEW(UValue, pvalue, UValue(ARRAY_VALUE));
+      U_NEW(UVector<World*>, pvworld_query, UVector<World*>(500));
 #  endif
 #  endif
       }
       }
 }
 }
@@ -71,14 +71,18 @@ USP_PUTS_CHAR('[');
 
 
 while (true)
 while (true)
    {
    {
-   pworld_query->id = u_get_num_random(10000);
+   pworld_query->id = u_get_num_random(10000-1);
 
 
    pstmt_query->execute();
    pstmt_query->execute();
 
 
 #ifdef AS_cpoll_cppsp_DO
 #ifdef AS_cpoll_cppsp_DO
    USP_PRINTF("{\"id\":%u,\"randomNumber\":%u}", pworld_query->id, pworld_query->randomNumber);
    USP_PRINTF("{\"id\":%u,\"randomNumber\":%u}", pworld_query->id, pworld_query->randomNumber);
 #else
 #else
-   pvworld_query->push_back(U_NEW(World(*pworld_query)));
+   World* pworld;
+
+   U_NEW(World, pworld, World(*pworld_query));
+
+   pvworld_query->push_back(pworld);
 #endif
 #endif
 
 
    if (++i == num_queries) break;
    if (++i == num_queries) break;

+ 22 - 31
frameworks/C++/ulib/src/rdb.usp

@@ -5,50 +5,43 @@ TechEmpower Web Framework Benchmarks
 <!--#declaration
 <!--#declaration
 #include "world.h"
 #include "world.h"
 
 
-static World* pworld;
+static char buffer[128];
 static UREDISClient_Base* rc;
 static UREDISClient_Base* rc;
 
 
 #ifndef AS_cpoll_cppsp_DO
 #ifndef AS_cpoll_cppsp_DO
-static UValue* pvalue;
+static UValue*	pvalue;
 #endif
 #endif
 
 
 static void usp_fork_rdb()
 static void usp_fork_rdb()
 {
 {
-   U_TRACE(5, "::usp_fork_rdb()")
+	U_TRACE(5, "::usp_fork_rdb()")
 
 
-   rc = U_NEW(UREDISClient<UTCPSocket>);
+	U_NEW(UREDISClient<UTCPSocket>, rc, UREDISClient<UTCPSocket>);
 
 
-   if (rc->connect() == false)
-      {
-      U_WARNING("usp_fork_rdb(): %V", rc->UClient_Base::getResponse().rep);
+	if (rc->connect() == false)
+		{
+		U_WARNING("usp_fork_rdb(): %V", rc->UClient_Base::getResponse().rep);
 
 
-      return;
-      }
+		return;
+		}
 
 
-   pworld = U_NEW(World);
+	u__memcpy(buffer, "world:", U_CONSTANT_SIZE("world:"), __PRETTY_FUNCTION__);
 
 
 #ifndef AS_cpoll_cppsp_DO
 #ifndef AS_cpoll_cppsp_DO
-   pvalue = U_NEW(UValue(OBJECT_VALUE));
+	U_NEW(UValue, pvalue, UValue(OBJECT_VALUE));
 #endif
 #endif
-
-   u__memcpy(u_buffer, "world:", U_CONSTANT_SIZE("world:"), __PRETTY_FUNCTION__);
 }
 }
 
 
 #ifdef DEBUG
 #ifdef DEBUG
 static void usp_end_rdb()
 static void usp_end_rdb()
 {
 {
-   U_TRACE(5, "::usp_end_rdb()")
-
-   delete rc;
+	U_TRACE(5, "::usp_end_rdb()")
 
 
-   if (pworld)
-      {
-      delete pworld;
+	delete rc;
 
 
-#  ifndef AS_cpoll_cppsp_DO
-      delete pvalue;
-#  endif
-      }
+#ifndef AS_cpoll_cppsp_DO
+	if (pvalue) delete pvalue;
+#endif
 }
 }
 #endif
 #endif
 -->
 -->
@@ -56,18 +49,16 @@ static void usp_end_rdb()
 Content-Type: application/json
 Content-Type: application/json
 -->
 -->
 <!--#code
 <!--#code
-UStringRep* rep;
-
-(void) rc->get(u_buffer, 6+u_num2str32(u_buffer+6, pworld->id = u_get_num_random(10000)));
-
-rep = rc->vitem[0].rep;
+uint32_t id;
 
 
-pworld->randomNumber = u_strtoul(rep->data(), rep->end());
+(void) rc->get(buffer, 6+u_num2str32(buffer+6, id = u_get_num_random(10000-1)));
 
 
 #ifdef AS_cpoll_cppsp_DO
 #ifdef AS_cpoll_cppsp_DO
-USP_PRINTF_ADD("{\"id\":%u,\"randomNumber\":%v}", pworld->id, rep);
+USP_PRINTF_ADD("{\"id\":%u,\"randomNumber\":%v}", id, rc->vitem[0].rep);
 #else
 #else
-USP_JSON_stringify(*pvalue, World, *pworld);
+UStringRep* rep = rc->vitem[0].rep;
+World world(id, u_strtoul(rep->data(), rep->end()));
+USP_JSON_stringify(*pvalue, World, world);
 pvalue->clear();
 pvalue->clear();
 #endif
 #endif
 -->
 -->

+ 14 - 6
frameworks/C++/ulib/src/rfortune.usp

@@ -14,7 +14,7 @@ static void usp_fork_rfortune()
 {
 {
    U_TRACE(5, "::usp_fork_rfortune()")
    U_TRACE(5, "::usp_fork_rfortune()")
 
 
-   rc = U_NEW(UREDISClient<UTCPSocket>);
+   U_NEW(UREDISClient<UTCPSocket>, rc, UREDISClient<UTCPSocket>);
 
 
    if (rc->connect() == false)
    if (rc->connect() == false)
       {
       {
@@ -23,9 +23,9 @@ static void usp_fork_rfortune()
       return;
       return;
       }
       }
 
 
-   pencoded     = U_NEW(UString(100U));
-   pvfortune    = U_NEW(UVector<Fortune*>);
-   pfortune2add = U_NEW(Fortune(0, U_STRING_FROM_CONSTANT("Additional fortune added at request time.")));
+   U_NEW(UString, pencoded, UString(100U));
+   U_NEW(UVector<Fortune*>, pvfortune, UVector<Fortune*>);
+   U_NEW(Fortune, pfortune2add, Fortune(0, U_STRING_FROM_CONSTANT("Additional fortune added at request time.")));
 }
 }
 
 
 #ifdef DEBUG
 #ifdef DEBUG
@@ -45,13 +45,21 @@ static void usp_end_rfortune()
 #endif
 #endif
 -->
 -->
 <!doctype html><html><head><title>Fortunes</title></head><body><table><tr><th>id</th><th>message</th></tr><!--#code
 <!doctype html><html><head><title>Fortunes</title></head><body><table><tr><th>id</th><th>message</th></tr><!--#code
+Fortune* item;
 uint32_t i, n;
 uint32_t i, n;
 
 
+U_NEW(Fortune, item, Fortune(*pfortune2add));
+
+pvfortune->push_back(item);
+
 (void) rc->lrange(U_CONSTANT_TO_PARAM("fortunes 0 -1"));
 (void) rc->lrange(U_CONSTANT_TO_PARAM("fortunes 0 -1"));
 
 
-pvfortune->push_back(U_NEW(Fortune(*pfortune2add)));
+for (i = 0, n = rc->vitem.size(); i < n; ++i)
+   {
+   U_NEW(Fortune, item, Fortune(i+1, rc->vitem[i]));
 
 
-for (i = 0, n = rc->vitem.size(); i < n; ++i) pvfortune->push_back(U_NEW(Fortune(i+1, rc->vitem[i])));
+   pvfortune->push_back(item);
+   }
 
 
 pvfortune->sort(Fortune::cmp_obj);
 pvfortune->sort(Fortune::cmp_obj);
 
 

+ 36 - 33
frameworks/C++/ulib/src/rquery.usp

@@ -5,48 +5,49 @@ TechEmpower Web Framework Benchmarks
 <!--#declaration
 <!--#declaration
 #include "world.h"
 #include "world.h"
 
 
+static char buffer[128];
 static UREDISClient_Base* rc;
 static UREDISClient_Base* rc;
-static UVector<World*>* pvworld_query;
+static UVector<World*>*	pvworld_query;
 
 
 #ifndef AS_cpoll_cppsp_DO
 #ifndef AS_cpoll_cppsp_DO
-static UValue* pvalue;
+static UValue*	pvalue;
 #endif
 #endif
 
 
 static void usp_fork_rquery()
 static void usp_fork_rquery()
 {
 {
-   U_TRACE(5, "::usp_fork_rquery()")
+	U_TRACE(5, "::usp_fork_rquery()")
 
 
-   rc = U_NEW(UREDISClient<UTCPSocket>);
+	U_NEW(UREDISClient<UTCPSocket>, rc, UREDISClient<UTCPSocket>);
 
 
-   if (rc->connect() == false)
-      {
-      U_WARNING("usp_fork_rquery(): %V", rc->UClient_Base::getResponse().rep);
+	if (rc->connect() == false)
+		{
+		U_WARNING("usp_fork_rquery(): %V", rc->UClient_Base::getResponse().rep);
 
 
-      return;
-      }
+		return;
+		}
 
 
-   pvworld_query = U_NEW(UVector<World*>(500));
+	U_NEW(UVector<World*>, pvworld_query, UVector<World*>(500));
 
 
 #ifndef AS_cpoll_cppsp_DO
 #ifndef AS_cpoll_cppsp_DO
-   pvalue = U_NEW(UValue(ARRAY_VALUE));
+	U_NEW(UValue, pvalue, UValue(ARRAY_VALUE));
 #endif
 #endif
 }
 }
 
 
 #ifdef DEBUG
 #ifdef DEBUG
 static void usp_end_rquery()
 static void usp_end_rquery()
 {
 {
-   U_TRACE(5, "::usp_end_rquery()")
+	U_TRACE(5, "::usp_end_rquery()")
 
 
-   delete rc;
+	delete rc;
 
 
-   if (pvworld_query)
-      {
-      delete pvworld_query;
+	if (pvworld_query)
+		{
+		delete pvworld_query;
 
 
-#  ifndef AS_cpoll_cppsp_DO
-      delete pvalue;
-#  endif
-      }
+#	ifndef AS_cpoll_cppsp_DO
+		delete pvalue;
+#	endif
+		}
 }
 }
 #endif
 #endif
 -->
 -->
@@ -56,7 +57,7 @@ Content-Type: application/json
 <!--#code
 <!--#code
 World* pworld;
 World* pworld;
 UStringRep* rep;
 UStringRep* rep;
-char* pbuffer = u_buffer;
+char* pbuffer = buffer;
 int i, num_queries = UHTTP::getFormFirstNumericValue(1, 500);
 int i, num_queries = UHTTP::getFormFirstNumericValue(1, 500);
 
 
 #ifdef AS_cpoll_cppsp_DO
 #ifdef AS_cpoll_cppsp_DO
@@ -64,36 +65,38 @@ USP_PUTS_CHAR('[');
 #endif
 #endif
 
 
 for (i = 0; i < num_queries; ++i)
 for (i = 0; i < num_queries; ++i)
-   {
-   pvworld_query->push_back(pworld = U_NEW(World));
+	{
+	U_NEW(World, pworld, World);
+
+	pvworld_query->push_back(pworld);
 
 
-   u_put_unalignedp64(pbuffer, U_MULTICHAR_CONSTANT64(' ','w','o','r','l','d',':','\0'));
+	u_put_unalignedp64(pbuffer, U_MULTICHAR_CONSTANT64(' ','w','o','r','l','d',':','\0'));
 
 
-   pbuffer += 7+u_num2str32(pbuffer+7, pworld->id = u_get_num_random(10000));
-   }
+	pbuffer += 7+u_num2str32(pbuffer+7, pworld->id = u_get_num_random(10000-1));
+	}
 
 
-(void) rc->mget(u_buffer, pbuffer-u_buffer);
+(void) rc->mget(buffer, pbuffer-buffer);
 
 
 i = 0;
 i = 0;
 
 
 while (true)
 while (true)
    {
    {
-   pworld = pvworld_query->at(i);
+	pworld = pvworld_query->at(i);
 
 
-   rep = rc->vitem[i].rep;
+	rep = rc->vitem[i].rep;
 
 
-   pworld->randomNumber = u_strtoul(rep->data(), rep->end());
+	pworld->randomNumber = u_strtoul(rep->data(), rep->end());
 
 
 #ifdef AS_cpoll_cppsp_DO
 #ifdef AS_cpoll_cppsp_DO
-   USP_PRINTF("{\"id\":%u,\"randomNumber\":%v}", pworld->id, rep);
+	USP_PRINTF("{\"id\":%u,\"randomNumber\":%v}", pworld->id, rep);
 #endif
 #endif
 
 
    if (++i == num_queries) break;
    if (++i == num_queries) break;
 
 
 #ifdef AS_cpoll_cppsp_DO
 #ifdef AS_cpoll_cppsp_DO
-   USP_PUTS_CHAR(',');
+	USP_PUTS_CHAR(',');
 #endif
 #endif
-   }
+	}
 
 
 #ifdef AS_cpoll_cppsp_DO
 #ifdef AS_cpoll_cppsp_DO
 USP_PUTS_CHAR(']');
 USP_PUTS_CHAR(']');

+ 38 - 35
frameworks/C++/ulib/src/rupdate.usp

@@ -5,48 +5,49 @@ TechEmpower Web Framework Benchmarks
 <!--#declaration
 <!--#declaration
 #include "world.h"
 #include "world.h"
 
 
+static char buffer[128];
 static UREDISClient_Base* rc;
 static UREDISClient_Base* rc;
 static UVector<World*>* pvworld;
 static UVector<World*>* pvworld;
 
 
 #ifndef AS_cpoll_cppsp_DO
 #ifndef AS_cpoll_cppsp_DO
-static UValue* pvalue;
+static UValue*	pvalue;
 #endif
 #endif
 
 
 static void usp_fork_rupdate()
 static void usp_fork_rupdate()
 {
 {
-   U_TRACE(5, "::usp_fork_rupdate()")
+	U_TRACE(5, "::usp_fork_rupdate()")
 
 
-   rc = U_NEW(UREDISClient<UTCPSocket>);
+	U_NEW(UREDISClient<UTCPSocket>, rc, UREDISClient<UTCPSocket>);
 
 
-   if (rc->connect() == false)
-      {
-      U_WARNING("usp_fork_rupdate(): %V", rc->UClient_Base::getResponse().rep);
+	if (rc->connect() == false)
+		{
+		U_WARNING("usp_fork_rupdate(): %V", rc->UClient_Base::getResponse().rep);
 
 
-      return;
-      }
+		return;
+		}
 
 
-   pvworld = U_NEW(UVector<World*>(500));
+	U_NEW(UVector<World*>, pvworld, UVector<World*>(500));
 
 
 #ifndef AS_cpoll_cppsp_DO
 #ifndef AS_cpoll_cppsp_DO
-   pvalue = U_NEW(UValue(ARRAY_VALUE));
+	U_NEW(UValue, pvalue, UValue(ARRAY_VALUE));
 #endif
 #endif
 }
 }
 
 
 #ifdef DEBUG
 #ifdef DEBUG
 static void usp_end_rupdate()
 static void usp_end_rupdate()
 {
 {
-   U_TRACE(5, "::usp_end_rupdate()")
+	U_TRACE(5, "::usp_end_rupdate()")
 
 
-   delete rc;
+	delete rc;
 
 
-   if (pvworld)
-      {
-      delete pvworld;
+	if (pvworld)
+		{
+		delete pvworld;
 
 
-#  ifndef AS_cpoll_cppsp_DO
-      delete pvalue;
-#  endif
-      }
+#	ifndef AS_cpoll_cppsp_DO
+		delete pvalue;
+#	endif
+		}
 }
 }
 #endif
 #endif
 -->
 -->
@@ -55,7 +56,7 @@ Content-Type: application/json
 -->
 -->
 <!--#code
 <!--#code
 World* pworld;
 World* pworld;
-char* pbuffer = u_buffer;
+char* pbuffer = buffer;
 int i, num_queries = UHTTP::getFormFirstNumericValue(1, 500);
 int i, num_queries = UHTTP::getFormFirstNumericValue(1, 500);
 
 
 #ifdef AS_cpoll_cppsp_DO
 #ifdef AS_cpoll_cppsp_DO
@@ -63,41 +64,43 @@ USP_PUTS_CHAR('[');
 #endif
 #endif
 
 
 for (i = 0; i < num_queries; ++i)
 for (i = 0; i < num_queries; ++i)
-   {
-   pvworld->push_back(pworld = U_NEW(World));
+	{
+	U_NEW(World, pworld, World);
+
+	pvworld->push_back(pworld);
 
 
-   u_put_unalignedp64(pbuffer, U_MULTICHAR_CONSTANT64(' ','w','o','r','l','d',':','\0'));
+	u_put_unalignedp64(pbuffer, U_MULTICHAR_CONSTANT64(' ','w','o','r','l','d',':','\0'));
 
 
-   pbuffer += 7+u_num2str32(pbuffer+7, pworld->id = u_get_num_random(10000));
-   }
+	pbuffer += 7+u_num2str32(pbuffer+7, pworld->id = u_get_num_random(10000-1));
+	}
 
 
-(void) rc->mget(u_buffer, pbuffer-u_buffer);
+(void) rc->mget(buffer, pbuffer-buffer);
 
 
 i = 0;
 i = 0;
-pbuffer = u_buffer;
+pbuffer = buffer;
 
 
 while (true)
 while (true)
    {
    {
-   pworld = pvworld->at(i);
+	pworld = pvworld->at(i);
 
 
-   u_put_unalignedp64(pbuffer, U_MULTICHAR_CONSTANT64(' ','w','o','r','l','d',':','\0'));
+	u_put_unalignedp64(pbuffer, U_MULTICHAR_CONSTANT64(' ','w','o','r','l','d',':','\0'));
 
 
-   pbuffer += 7+u_num2str32(pbuffer+7, pworld->id);
+	pbuffer += 7+u_num2str32(pbuffer+7, pworld->id);
   *pbuffer  = ' ';
   *pbuffer  = ' ';
-   pbuffer += 1+u_num2str32(pbuffer+1, pworld->randomNumber = u_get_num_random(10000));
+	pbuffer += 1+u_num2str32(pbuffer+1, pworld->randomNumber = u_get_num_random(10000-1));
 
 
 #ifdef AS_cpoll_cppsp_DO
 #ifdef AS_cpoll_cppsp_DO
-   USP_PRINTF("{\"id\":%u,\"randomNumber\":%u}", pworld->id, pworld->randomNumber);
+	USP_PRINTF("{\"id\":%u,\"randomNumber\":%u}", pworld->id, pworld->randomNumber);
 #endif
 #endif
 
 
    if (++i == num_queries) break;
    if (++i == num_queries) break;
 
 
 #ifdef AS_cpoll_cppsp_DO
 #ifdef AS_cpoll_cppsp_DO
-   USP_PUTS_CHAR(',');
+	USP_PUTS_CHAR(',');
 #endif
 #endif
-   }
+	}
 
 
-(void) rc->mset(u_buffer, pbuffer-u_buffer);
+(void) rc->mset(buffer, pbuffer-buffer);
 
 
 #ifdef AS_cpoll_cppsp_DO
 #ifdef AS_cpoll_cppsp_DO
 USP_PUTS_CHAR(']');
 USP_PUTS_CHAR(']');

+ 13 - 11
frameworks/C++/ulib/src/update.usp

@@ -19,12 +19,12 @@ static void usp_fork_update()
 {
 {
    U_TRACE(5, "::usp_fork_update()")
    U_TRACE(5, "::usp_fork_update()")
 
 
-   psql_update = U_NEW(UOrmSession(U_CONSTANT_TO_PARAM("hello_world")));
+   U_NEW(UOrmSession, psql_update, UOrmSession(U_CONSTANT_TO_PARAM("hello_world")));
 
 
    if (psql_update->isReady())
    if (psql_update->isReady())
       {
       {
-      pstmt1 = U_NEW(UOrmStatement(*psql_update, U_CONSTANT_TO_PARAM("SELECT randomNumber FROM World WHERE id = ?")));
-      pstmt2 = U_NEW(UOrmStatement(*psql_update, U_CONSTANT_TO_PARAM("UPDATE World SET randomNumber = ? WHERE id = ?")));
+      U_NEW(UOrmStatement, pstmt1, UOrmStatement(*psql_update, U_CONSTANT_TO_PARAM("SELECT randomNumber FROM World WHERE id = ?")));
+      U_NEW(UOrmStatement, pstmt2, UOrmStatement(*psql_update, U_CONSTANT_TO_PARAM("UPDATE World SET randomNumber = ? WHERE id = ?")));
 
 
       if (pstmt1 == 0 ||
       if (pstmt1 == 0 ||
           pstmt2 == 0)
           pstmt2 == 0)
@@ -32,17 +32,15 @@ static void usp_fork_update()
          U_WARNING("usp_fork_update(): we cound't connect to db");
          U_WARNING("usp_fork_update(): we cound't connect to db");
          }
          }
 
 
-		if (UOrmDriver::isPGSQL()) *psql_update << "SET synchronous_commit TO OFF";
-
-      pworld_update = U_NEW(World);
+      U_NEW(World, pworld_update, World);
 
 
       pstmt1->use( pworld_update->id);
       pstmt1->use( pworld_update->id);
       pstmt1->into(pworld_update->randomNumber);
       pstmt1->into(pworld_update->randomNumber);
       pstmt2->use( pworld_update->randomNumber, pworld_update->id);
       pstmt2->use( pworld_update->randomNumber, pworld_update->id);
 
 
 #  ifndef AS_cpoll_cppsp_DO
 #  ifndef AS_cpoll_cppsp_DO
-      pvalue         = U_NEW(UValue(ARRAY_VALUE));
-      pvworld_update = U_NEW(UVector<World*>(500));
+      U_NEW(UValue, pvalue, UValue(ARRAY_VALUE));
+      U_NEW(UVector<World*>, pvworld_update, UVector<World*>(500));
 #  endif
 #  endif
       }
       }
 }
 }
@@ -80,18 +78,22 @@ USP_PUTS_CHAR('[');
 
 
 while (true)
 while (true)
    {
    {
-   pworld_update->id = u_get_num_random(10000);
+   pworld_update->id = u_get_num_random(10000-1);
 
 
    pstmt1->execute();
    pstmt1->execute();
 
 
-   pworld_update->randomNumber = u_get_num_random(10000);
+   pworld_update->randomNumber = u_get_num_random(10000-1);
 
 
    pstmt2->execute();
    pstmt2->execute();
 
 
 #ifdef AS_cpoll_cppsp_DO
 #ifdef AS_cpoll_cppsp_DO
    USP_PRINTF("{\"id\":%u,\"randomNumber\":%u}", pworld_update->id, pworld_update->randomNumber);
    USP_PRINTF("{\"id\":%u,\"randomNumber\":%u}", pworld_update->id, pworld_update->randomNumber);
 #else
 #else
-   pvworld_update->push_back(U_NEW(World(*pworld_update)));
+   World* pworld;
+
+   U_NEW(World, pworld, World(*pworld_update));
+
+   pvworld_update->push_back(pworld);
 #endif
 #endif
 
 
    if (++i == num_queries) break;
    if (++i == num_queries) break;

+ 2 - 4
frameworks/C++/ulib/src/world.h

@@ -27,11 +27,9 @@ public:
 #  endif
 #  endif
       }
       }
 
 
-   World(const World& w) : id(w.id), randomNumber(w.randomNumber)
+   World(uint32_t _id, uint32_t _randomNumber) : id(_id), randomNumber(_randomNumber)
       {
       {
-      U_TRACE_REGISTER_OBJECT(5, World, "%p", &w)
-
-      U_MEMORY_TEST_COPY(w)
+      U_TRACE_REGISTER_OBJECT(5, World, "%u,%u", _id, _randomNumber)
       }
       }
 
 
    ~World()
    ~World()

+ 2 - 0
frameworks/C++/wt/.gitignore

@@ -0,0 +1,2 @@
+/benchmark.wt
+/benchmark_postgres.wt

+ 3 - 1
frameworks/C/duda/.gitignore

@@ -1,3 +1,5 @@
 *.o
 *.o
 *~
 *~
-
+/Makefile
+/main.d
+/ws.duda

+ 23 - 0
frameworks/C/h2o/CMakeLists.txt

@@ -0,0 +1,23 @@
+cmake_minimum_required(VERSION 2.8.0)
+project(h2o_app)
+find_library(H2O_LIB h2o-evloop)
+find_library(MUSTACHE_C_LIB mustache_c)
+find_library(YAJL_LIB yajl)
+find_path(H2O_INCLUDE h2o.h)
+find_path(MUSTACHE_C_INCLUDE mustache.h)
+find_path(YAJL_INCLUDE yajl/yajl_gen.h)
+set(COMMON_OPTIONS -flto -pthread)
+add_compile_options(-std=gnu11 -pedantic -Wall -Wextra ${COMMON_OPTIONS})
+set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -fsanitize=address")
+set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -fstack-protector-all -D_FORTIFY_SOURCE=2")
+set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -Ofast")
+set(CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO} -Ofast")
+add_definitions(-DH2O_USE_LIBUV=0)
+include_directories(src ${H2O_INCLUDE} ${MUSTACHE_C_INCLUDE} ${YAJL_INCLUDE})
+file(GLOB SOURCES "src/*.c")
+add_executable(${PROJECT_NAME} ${SOURCES})
+target_link_libraries(${PROJECT_NAME} ${COMMON_OPTIONS})
+target_link_libraries(${PROJECT_NAME} ${H2O_LIB} ssl crypto pq ${MUSTACHE_C_LIB} ${YAJL_LIB})
+install(TARGETS ${PROJECT_NAME} RUNTIME DESTINATION bin)
+file(GLOB TEMPLATES "template/*")
+install(FILES ${TEMPLATES} DESTINATION share/${PROJECT_NAME}/template)

+ 11 - 0
frameworks/C/h2o/README.md

@@ -0,0 +1,11 @@
+# h2o
+
+This is a framework implementation using the [H2O](https://h2o.examp1e.net/) HTTP server.
+
+## Requirements
+
+CMake, H2O, libpq, mustache-c, OpenSSL, YAJL
+
+## Contact
+
+Anton Kirilov <[email protected]>

+ 9 - 10
frameworks/Crystal/moonshine/benchmark_config.json → frameworks/C/h2o/benchmark_config.json

@@ -1,8 +1,8 @@
 {
 {
-  "framework": "moonshine",
+  "framework": "h2o",
   "tests": [{
   "tests": [{
     "default": {
     "default": {
-      "setup_file": "setup-postgres",
+      "setup_file": "setup",
       "json_url": "/json",
       "json_url": "/json",
       "db_url": "/db",
       "db_url": "/db",
       "query_url": "/queries?queries=",
       "query_url": "/queries?queries=",
@@ -11,19 +11,18 @@
       "plaintext_url": "/plaintext",
       "plaintext_url": "/plaintext",
       "port": 8080,
       "port": 8080,
       "approach": "Realistic",
       "approach": "Realistic",
-      "classification": "Fullstack",
+      "classification": "Platform",
       "database": "Postgres",
       "database": "Postgres",
-      "framework": "moonshine",
-      "language": "Crystal",
-      "flavor": "Crystal12",
-      "orm": "micro",
+      "framework": "None",
+      "language": "C",
+      "flavor": "C11",
+      "orm": "Raw",
       "platform": "None",
       "platform": "None",
       "webserver": "None",
       "webserver": "None",
       "os": "Linux",
       "os": "Linux",
       "database_os": "Linux",
       "database_os": "Linux",
-      "display_name": "Moonshine",
-      "notes": "",
-      "versus": "crystal"
+      "display_name": "H2O",
+      "notes": ""
     }
     }
   }]
   }]
 }
 }

+ 57 - 0
frameworks/C/h2o/setup.sh

@@ -0,0 +1,57 @@
+#!/bin/bash
+
+fw_depends h2o mustache-c yajl
+
+H2O_APP_HOME="${IROOT}/h2o_app"
+BUILD_DIR="${H2O_APP_HOME}_build"
+H2O_APP_PROFILE_PORT="54321"
+H2O_APP_PROFILE_URL="http://127.0.0.1:$H2O_APP_PROFILE_PORT"
+
+build_h2o_app()
+{
+	cmake -DCMAKE_INSTALL_PREFIX="$H2O_APP_HOME" -DCMAKE_BUILD_TYPE=Release \
+		-DCMAKE_LIBRARY_PATH="${H2O_HOME}/lib;${MUSTACHE_C_HOME}/lib;${YAJL_HOME}/lib" \
+		-DCMAKE_INCLUDE_PATH="${H2O_HOME}/include;${MUSTACHE_C_HOME}/include;${YAJL_HOME}/include" \
+		-DCMAKE_C_FLAGS="-march=native $1" "$TROOT"
+	make -j "$(nproc)"
+}
+
+run_curl()
+{
+	for ((i = 0; i < 10; i++)); do
+		curl "${H2O_APP_PROFILE_URL}/$1" > /dev/null 2>&1
+	done
+}
+
+run_h2o_app()
+{
+	"$1/h2o_app" -a2 -f "$2/template/fortunes.mustache" -m2 "$3" "$4" \
+		-d "host=$DBHOST dbname=hello_world user=benchmarkdbuser password=benchmarkdbpass" &
+}
+
+generate_profile_data()
+{
+	run_h2o_app . "${TROOT}" -p$H2O_APP_PROFILE_PORT -t1
+	local -r H2O_APP_PROFILE_PID=$!
+	while ! curl ${H2O_APP_PROFILE_URL} > /dev/null 2>&1; do sleep 1; done
+	run_curl json
+	run_curl db
+	run_curl queries?queries=20
+	run_curl fortunes
+	run_curl updates?queries=20
+	run_curl plaintext
+	kill -s SIGTERM $H2O_APP_PROFILE_PID
+	wait $H2O_APP_PROFILE_PID
+}
+
+install -d "$BUILD_DIR"
+pushd "$BUILD_DIR"
+build_h2o_app "-fprofile-generate"
+generate_profile_data
+make clean
+rm -f CMakeCache.txt
+build_h2o_app "-fprofile-use"
+make -j "$(nproc)" install
+popd
+rm -rf "$BUILD_DIR"
+run_h2o_app "${H2O_APP_HOME}/bin" "${H2O_APP_HOME}/share/h2o_app"

+ 23 - 0
frameworks/C/h2o/source_code

@@ -0,0 +1,23 @@
+./src/bitset.h
+./src/database.c
+./src/database.h
+./src/error.c
+./src/error.h
+./src/event_loop.c
+./src/event_loop.h
+./src/fortune.c
+./src/fortune.h
+./src/list.h
+./src/main.c
+./src/request_handler.c
+./src/request_handler.h
+./src/template.c
+./src/template.h
+./src/thread.c
+./src/thread.h
+./src/tls.c
+./src/tls.h
+./src/utility.c
+./src/utility.h
+./src/world.c
+./src/world.h

Some files were not shown because too many files changed in this diff