Browse Source

[Lithium] Optimize updates with transactions and sorting. (#5353)

* Lithium Optimize updates with transactions and sorting.

* [Lithium] bulk update.
Matthieu Garrigues 5 years ago
parent
commit
162eb01bf0

+ 1 - 1
frameworks/C++/lithium/lithium-mysql.dockerfile

@@ -6,7 +6,7 @@ RUN apt install -yqq libboost-context-dev
 
 COPY ./ ./
 
-ENV COMMIT=9a87e6791a855b9f21dee132eaf8605913026901
+ENV COMMIT=e8dc32136a1a5b766dc7626101cf5b64e2510af5
 
 RUN wget https://raw.githubusercontent.com/matt-42/lithium/$COMMIT/single_headers/lithium_mysql.hh
 RUN wget https://raw.githubusercontent.com/matt-42/lithium/$COMMIT/single_headers/lithium_http_backend.hh

+ 1 - 1
frameworks/C++/lithium/lithium-postgres.dockerfile

@@ -5,7 +5,7 @@ RUN apt install -yqq g++-9 libboost-dev postgresql-server-dev-all libpq-dev wget
 
 COPY ./ ./
 
-ENV COMMIT=9a87e6791a855b9f21dee132eaf8605913026901
+ENV COMMIT=e8dc32136a1a5b766dc7626101cf5b64e2510af5
 
 RUN wget https://raw.githubusercontent.com/matt-42/lithium/$COMMIT/single_headers/lithium_pgsql.hh
 RUN wget https://raw.githubusercontent.com/matt-42/lithium/$COMMIT/single_headers/lithium_http_backend.hh

+ 22 - 2
frameworks/C++/lithium/lithium.cc

@@ -90,16 +90,36 @@ int main(int argc, char* argv[]) {
     std::string N_str = request.get_parameters(s::N = std::optional<std::string>()).N.value_or("1");
     int N = atoi(N_str.c_str());
     N = std::max(1, std::min(N, 500));
-    
+
+     
     auto c = random_numbers.connect(request.yield);
+    auto& raw_c = c.backend_connection();
+
     std::vector<decltype(random_numbers.all_fields())> numbers(N);
+    
+    raw_c("START TRANSACTION");
     for (int i = 0; i < N; i++)
     {
       numbers[i] = c.find_one(s::id = 1 + rand() % 9999).value();
       numbers[i].randomNumber = 1 + rand() % 9999;
-      c.update(numbers[i]);
     }
 
+    std::sort(numbers.begin(), numbers.end(), [] (auto a, auto b) { return a.id < b.id; });
+
+#if TFB_MYSQL
+    for (int i = 0; i < N; i++)
+      c.update(numbers[i]);
+#elif TFB_PGSQL
+    std::ostringstream ss;
+    ss << "UPDATE World SET randomNumber=tmp.randomNumber FROM (VALUES ";
+    for (int i = 0; i < N; i++)
+      ss << "(" << numbers[i].id << ", " << numbers[i].randomNumber << ") "<< (i == N-1 ? "": ",");
+    ss << ") AS tmp(id, randomNumber) WHERE tmp.id = World.id";
+    raw_c(ss.str());
+#endif
+    
+    raw_c("COMMIT");
+
     response.write_json(numbers);
   };