From 69f36c9b4f5df19f09156689b333afe29a017eed Mon Sep 17 00:00:00 2001 From: Douglas Rumbaugh Date: Fri, 23 Feb 2024 15:40:49 -0500 Subject: Benchmark updates --- benchmarks/include/standard_benchmarks.h | 212 +++++++++++++++++++++++++++++++ 1 file changed, 212 insertions(+) create mode 100644 benchmarks/include/standard_benchmarks.h (limited to 'benchmarks/include/standard_benchmarks.h') diff --git a/benchmarks/include/standard_benchmarks.h b/benchmarks/include/standard_benchmarks.h new file mode 100644 index 0000000..a42cdd6 --- /dev/null +++ b/benchmarks/include/standard_benchmarks.h @@ -0,0 +1,212 @@ +/* + * benchmarks/include/bench.h + * + * Copyright (C) 2023 Douglas Rumbaugh + * + * All rights reserved. Published under the Modified BSD License. + * + */ +#pragma once + +#include +#include +#include + +#include "framework/DynamicExtension.h" +#include "framework/interface/Query.h" +#include "psu-util/progress.h" +#include "benchmark_types.h" + +static size_t g_deleted_records = 0; +static double delete_proportion = 0.05; + +template +static void run_queries(DE *extension, std::vector &queries, gsl_rng *rng) { + size_t total; + for (size_t i=0; iquery(q); + auto r = res.get(); + total += r.size(); + } +} + + +template +static void insert_records(DE *extension, size_t start, size_t stop, + std::vector &records, std::vector &to_delete, + size_t &delete_idx, bool delete_records, gsl_rng *rng) { + + psudb::progress_update(0, "Insert Progress"); + size_t reccnt = 0; + for (size_t i=start; iinsert(records[i])) { + psudb::progress_update((double) i / (double)(stop - start), "Insert Progress"); + usleep(1); + } + + if (delete_records && gsl_rng_uniform(rng) <= + delete_proportion && to_delete[delete_idx] <= i) { + + while (!extension->erase(records[to_delete[delete_idx]])) { + usleep(1); + } + + delete_idx++; + g_deleted_records++; + } + } + + psudb::progress_update(1, "Insert Progress"); +} + +template +static bool insert_tput_bench(DE &de_index, std::fstream &file, size_t insert_cnt, + double delete_prop, gsl_rng *rng, std::vector &to_delete, bool binary=false) { + + size_t delete_cnt = insert_cnt * delete_prop; + + size_t applied_deletes = 0; + size_t applied_inserts = 0; + + std::vector insert_vec; + std::vector delete_vec; + insert_vec.reserve(BATCH); + delete_vec.reserve(BATCH*delete_prop); + + size_t delete_idx = 0; + + bool continue_benchmark = true; + + size_t total_time = 0; + + while (applied_inserts < insert_cnt && continue_benchmark) { + continue_benchmark = build_insert_vec(file, insert_vec, BATCH, delete_prop, to_delete, binary); + if (applied_deletes < delete_cnt) { + build_delete_vec(to_delete, delete_vec, BATCH*delete_prop); + delete_idx = 0; + } + + if (insert_vec.size() == 0) { + break; + } + + if constexpr (PROGRESS) { + psudb::progress_update((double) applied_inserts / (double) insert_cnt, "inserting:"); + } + + auto insert_start = std::chrono::high_resolution_clock::now(); + for (size_t i=0; i) { + de_index.erase_one(delete_vec[delete_idx++].key); + } else if constexpr (std::is_same_v) { + de_index.remove(delete_vec[delete_idx++]); + } else { + de_index.erase(delete_vec[delete_idx++]); + } + applied_deletes++; + } + + // insert the record; + if constexpr (std::is_same_v) { + de_index.add(insert_vec[i]); + } else { + de_index.insert(insert_vec[i]); + } + applied_inserts++; + } + auto insert_stop = std::chrono::high_resolution_clock::now(); + + total_time += std::chrono::duration_cast(insert_stop - insert_start).count(); + } + + if constexpr (PROGRESS) { + psudb::progress_update(1.0, "inserting:"); + } + + size_t throughput = (((double) (applied_inserts + applied_deletes) / (double) total_time) * 1e9); + + fprintf(stdout, "%ld\t", throughput); + + return continue_benchmark; +} + +template +static bool query_latency_bench(DE &de_index, std::vector queries, size_t trial_cnt=1) { + char progbuf[25]; + if constexpr (PROGRESS) { + sprintf(progbuf, "querying:"); + } + + size_t total_time = 0; + size_t total_results = 0; + + for (size_t i=0; i(stop - start).count(); + } + + psudb::progress_update(1.0, progbuf); + + size_t query_latency = total_time / (trial_cnt * queries.size()); + + fprintf(stdout, "%ld\t", query_latency); + fflush(stdout); + + return true; +} + + +template Q, bool PROGRESS=true> +static bool static_latency_bench(Shard *shard, std::vector queries, size_t trial_cnt=100) { + char progbuf[25]; + if constexpr (PROGRESS) { + sprintf(progbuf, "querying:"); + } + + size_t total_time = 0; + size_t total_results = 0; + + for (size_t i=0; i states(1); + + auto start = std::chrono::high_resolution_clock::now(); + for (size_t j=0; j(stop - start).count(); + } + + psudb::progress_update(1.0, progbuf); + + size_t query_latency = total_time / (trial_cnt * queries.size()); + + fprintf(stdout, "%ld\t", query_latency); + fflush(stdout); + + return true; +} -- cgit v1.2.3 From b1b5ab106122e6917f6b34452be95e617506f05d Mon Sep 17 00:00:00 2001 From: "Douglas B. Rumbaugh" Date: Mon, 25 Mar 2024 12:54:17 -0400 Subject: Updates for build on OpenBSD Necessary updates to get the codebase building under OpenBSD 7.5 with clang. This is a minimal set of changes to get building to work, which includes disabling several things that aren't directly compatable. More work will be necessary to get full functionality. In particular, Triespline, PGM, and the reference M-tree do not currently build on OpenBSD with clang due to GNU dependencies or other gcc specific features. --- benchmarks/include/standard_benchmarks.h | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'benchmarks/include/standard_benchmarks.h') diff --git a/benchmarks/include/standard_benchmarks.h b/benchmarks/include/standard_benchmarks.h index a42cdd6..5fc549d 100644 --- a/benchmarks/include/standard_benchmarks.h +++ b/benchmarks/include/standard_benchmarks.h @@ -102,8 +102,10 @@ static bool insert_tput_bench(DE &de_index, std::fstream &file, size_t insert_cn if (applied_deletes < delete_cnt && delete_idx < delete_vec.size() && gsl_rng_uniform(rng) < delete_prop) { if constexpr (std::is_same_v) { de_index.erase_one(delete_vec[delete_idx++].key); + #ifdef _GNU_SOURCE } else if constexpr (std::is_same_v) { de_index.remove(delete_vec[delete_idx++]); + #endif } else { de_index.erase(delete_vec[delete_idx++]); } @@ -111,11 +113,16 @@ static bool insert_tput_bench(DE &de_index, std::fstream &file, size_t insert_cn } // insert the record; + #ifdef _GNU_SOURCE if constexpr (std::is_same_v) { de_index.add(insert_vec[i]); } else { de_index.insert(insert_vec[i]); } + #else + de_index.insert(insert_vec[i]); + #endif + applied_inserts++; } auto insert_stop = std::chrono::high_resolution_clock::now(); -- cgit v1.2.3 From 7c2f43ff039795576bc0014c367b893fbbaceca4 Mon Sep 17 00:00:00 2001 From: Douglas Rumbaugh Date: Fri, 19 Apr 2024 14:39:33 -0400 Subject: Benchmark updates --- benchmarks/include/standard_benchmarks.h | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) (limited to 'benchmarks/include/standard_benchmarks.h') diff --git a/benchmarks/include/standard_benchmarks.h b/benchmarks/include/standard_benchmarks.h index 5fc549d..fe53d62 100644 --- a/benchmarks/include/standard_benchmarks.h +++ b/benchmarks/include/standard_benchmarks.h @@ -21,7 +21,7 @@ static size_t g_deleted_records = 0; static double delete_proportion = 0.05; template -static void run_queries(DE *extension, std::vector &queries, gsl_rng *rng) { +static void run_queries(DE *extension, std::vector &queries) { size_t total; for (size_t i=0; i &queries, gsl_rng *rng) { } +template +static void run_static_queries(S *shard, std::vector &queries) { + size_t total; + for (size_t i=0; i static void insert_records(DE *extension, size_t start, size_t stop, std::vector &records, std::vector &to_delete, -- cgit v1.2.3 From 8479f3ce863dfb6d3b20ff4678fa6fe92ee86b52 Mon Sep 17 00:00:00 2001 From: Douglas Rumbaugh Date: Fri, 19 Apr 2024 16:50:18 -0400 Subject: Fixed some benchmarking bugs --- benchmarks/include/standard_benchmarks.h | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'benchmarks/include/standard_benchmarks.h') diff --git a/benchmarks/include/standard_benchmarks.h b/benchmarks/include/standard_benchmarks.h index fe53d62..83e3aaa 100644 --- a/benchmarks/include/standard_benchmarks.h +++ b/benchmarks/include/standard_benchmarks.h @@ -40,6 +40,12 @@ static void run_static_queries(S *shard, std::vector &queries) { auto q = &queries[i]; auto state = Q::get_query_state(shard, q); + + std::vector shards = {shard}; + std::vector states = {state}; + + Q::process_query_states(q, states, nullptr); + auto res = Q::query(shard, state, q); total += res.size(); -- cgit v1.2.3 From 438feac7e56fee425d9c6f1a43298ff9dc5b71d1 Mon Sep 17 00:00:00 2001 From: Douglas Rumbaugh Date: Fri, 19 Apr 2024 17:38:16 -0400 Subject: Properly implemented support for iteratively decomposable problems --- benchmarks/include/standard_benchmarks.h | 6 ------ 1 file changed, 6 deletions(-) (limited to 'benchmarks/include/standard_benchmarks.h') diff --git a/benchmarks/include/standard_benchmarks.h b/benchmarks/include/standard_benchmarks.h index 83e3aaa..f5af558 100644 --- a/benchmarks/include/standard_benchmarks.h +++ b/benchmarks/include/standard_benchmarks.h @@ -22,20 +22,17 @@ static double delete_proportion = 0.05; template static void run_queries(DE *extension, std::vector &queries) { - size_t total; for (size_t i=0; iquery(q); auto r = res.get(); - total += r.size(); } } template static void run_static_queries(S *shard, std::vector &queries) { - size_t total; for (size_t i=0; i &queries) { std::vector states = {state}; Q::process_query_states(q, states, nullptr); - auto res = Q::query(shard, state, q); - - total += res.size(); } } -- cgit v1.2.3 From 0bb5b46ec2b64be17f6269631915e62d02e315e4 Mon Sep 17 00:00:00 2001 From: Douglas Rumbaugh Date: Mon, 22 Apr 2024 12:27:43 -0400 Subject: Added plain BSM and MDSP BSM benchmark --- benchmarks/include/standard_benchmarks.h | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) (limited to 'benchmarks/include/standard_benchmarks.h') diff --git a/benchmarks/include/standard_benchmarks.h b/benchmarks/include/standard_benchmarks.h index f5af558..74bf93f 100644 --- a/benchmarks/include/standard_benchmarks.h +++ b/benchmarks/include/standard_benchmarks.h @@ -16,17 +16,20 @@ #include "framework/interface/Query.h" #include "psu-util/progress.h" #include "benchmark_types.h" +#include "psu-util/bentley-saxe.h" static size_t g_deleted_records = 0; static double delete_proportion = 0.05; -template +template static void run_queries(DE *extension, std::vector &queries) { for (size_t i=0; iquery(q); - auto r = res.get(); + if constexpr (!BSM) { + auto r = res.get(); + } } } @@ -47,6 +50,22 @@ static void run_static_queries(S *shard, std::vector &queries) { } +/* + * Insert records into a standard Bentley-Saxe extension. Deletes are not + * supported. + */ +template +static void insert_records(psudb::bsm::BentleySaxe *extension, + size_t start, size_t stop, std::vector &records) { + + psudb::progress_update(0, "Insert Progress"); + size_t reccnt = 0; + for (size_t i=start; iinsert(records[i]); + } + + psudb::progress_update(1, "Insert Progress"); +} template -- cgit v1.2.3 From 4a1dde3148e0e84b47c884bc0bb69c60678b4558 Mon Sep 17 00:00:00 2001 From: Douglas Rumbaugh Date: Mon, 22 Apr 2024 15:09:07 -0400 Subject: Benchmark update+reorganization The Alex benchmark isn't updated yet. --- benchmarks/include/standard_benchmarks.h | 69 ++++++++++++++++++++++++++------ 1 file changed, 56 insertions(+), 13 deletions(-) (limited to 'benchmarks/include/standard_benchmarks.h') diff --git a/benchmarks/include/standard_benchmarks.h b/benchmarks/include/standard_benchmarks.h index 74bf93f..aaef679 100644 --- a/benchmarks/include/standard_benchmarks.h +++ b/benchmarks/include/standard_benchmarks.h @@ -14,6 +14,7 @@ #include "framework/DynamicExtension.h" #include "framework/interface/Query.h" +#include "query/irs.h" #include "psu-util/progress.h" #include "benchmark_types.h" #include "psu-util/bentley-saxe.h" @@ -24,15 +25,41 @@ static double delete_proportion = 0.05; template static void run_queries(DE *extension, std::vector &queries) { for (size_t i=0; iquery(q); - if constexpr (!BSM) { - auto r = res.get(); + if constexpr (std::is_same_v) { + std::vector result; + auto res = extension->get_nearest_by_limit(queries[i].point, queries[i].k); + + auto itr = res.begin(); + while (itr != res.end()) { + result.emplace_back(itr->data); + itr++; + } + } else if constexpr (std::is_same_v) { + size_t tot = 0; + auto ptr = extension->find(queries[i].lower_bound); + while (ptr != extension->end() && ptr->first <= queries[i].upper_bound) { + tot++; + ++ptr; + } + } else { + auto res = extension->query(&queries[i]); + if constexpr (!BSM) { + auto r = res.get(); + } } } } +template +static void run_btree_queries(BenchBTree *btree, std::vector> &queries) { + std::vector sample_set; + sample_set.reserve(queries[0].sample_size); + + for (size_t i=0; irange_sample(queries[i].lower_bound, queries[i].upper_bound, queries[i].sample_size, sample_set, queries[i].rng); + } +} + template static void run_static_queries(S *shard, std::vector &queries) { @@ -68,26 +95,42 @@ static void insert_records(psudb::bsm::BentleySaxe *extension, } -template -static void insert_records(DE *extension, size_t start, size_t stop, +template +static void insert_records(DE *structure, size_t start, size_t stop, std::vector &records, std::vector &to_delete, size_t &delete_idx, bool delete_records, gsl_rng *rng) { psudb::progress_update(0, "Insert Progress"); size_t reccnt = 0; for (size_t i=start; iinsert(records[i])) { - psudb::progress_update((double) i / (double)(stop - start), "Insert Progress"); - usleep(1); + + if constexpr (std::is_same_v) { + structure->insert(records[i]); + } else if constexpr (std::is_same_v) { + structure->add(records[i]); + } else if constexpr (std::is_same_v) { + structure->insert_or_assign(records[i].key, records[i].value); + } else { + while (!structure->insert(records[i])) { + psudb::progress_update((double) i / (double)(stop - start), "Insert Progress"); + usleep(1); + } } if (delete_records && gsl_rng_uniform(rng) <= delete_proportion && to_delete[delete_idx] <= i) { - while (!extension->erase(records[to_delete[delete_idx]])) { - usleep(1); + if constexpr (std::is_same_v) { + structure->erase_one(records[to_delete[delete_idx]].key); + } else if constexpr (std::is_same_v) { + structure->remove(records[to_delete[delete_idx]]); + } else if constexpr (std::is_same_v) { + structure->erase(records[to_delete[delete_idx]].key); + } else { + while (!structure->erase(records[to_delete[delete_idx]])) { + usleep(1); + } } - delete_idx++; g_deleted_records++; } -- cgit v1.2.3 From 47a386b50d904d3f1b7ce3cfc13c29ea96dd1e43 Mon Sep 17 00:00:00 2001 From: Douglas Rumbaugh Date: Tue, 30 Apr 2024 14:18:08 -0400 Subject: Added VPTree BSM benchmark --- benchmarks/include/standard_benchmarks.h | 39 +++++++++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) (limited to 'benchmarks/include/standard_benchmarks.h') diff --git a/benchmarks/include/standard_benchmarks.h b/benchmarks/include/standard_benchmarks.h index aaef679..76b5f7c 100644 --- a/benchmarks/include/standard_benchmarks.h +++ b/benchmarks/include/standard_benchmarks.h @@ -34,6 +34,14 @@ static void run_queries(DE *extension, std::vector &queries) { result.emplace_back(itr->data); itr++; } + + #ifdef BENCH_PRINT_RESULTS + fprintf(stdout, "\n\n"); + for (auto &r : result) { + fprintf(stdout, "%ld %lf %lf %lf %lf %lf %lf\n", result.size(), r.data[0], + r.data[1], r.data[2], r.data[3], r.data[4], r.data[5]); + } + #endif } else if constexpr (std::is_same_v) { size_t tot = 0; auto ptr = extension->find(queries[i].lower_bound); @@ -44,7 +52,26 @@ static void run_queries(DE *extension, std::vector &queries) { } else { auto res = extension->query(&queries[i]); if constexpr (!BSM) { - auto r = res.get(); + auto result = res.get(); + #ifdef BENCH_PRINT_RESULTS + fprintf(stdout, "\n\n"); + for (int i=result.size()-1; i>=0; i--) { + auto &r = result[i]; + fprintf(stdout, "%ld %lf %lf %lf %lf %lf %lf\n", result.size(), r.data[0], + r.data[1], r.data[2], r.data[3], r.data[4], r.data[5]); + } + fflush(stdout); + #endif + } else { + #ifdef BENCH_PRINT_RESULTS + fprintf(stdout, "\n\n"); + for (int i=res.size()-1; i>=0; i--) { + auto &r = res[i]; + fprintf(stdout, "%ld %lf %lf %lf %lf %lf %lf\n", res.size(), r.data[0], + r.data[1], r.data[2], r.data[3], r.data[4], r.data[5]); + } + fflush(stdout); + #endif } } } @@ -73,6 +100,16 @@ static void run_static_queries(S *shard, std::vector &queries) { Q::process_query_states(q, states, nullptr); auto res = Q::query(shard, state, q); + + #ifdef BENCH_PRINT_RESULTS + fprintf(stdout, "\n\n"); + for (int i=res.size()-1; i>=0; i--) { + auto &r = res[i].rec; + fprintf(stdout, "%ld %lf %lf %lf %lf %lf %lf\n", res.size(), r.data[0], + r.data[1], r.data[2], r.data[3], r.data[4], r.data[5]); + } + fflush(stdout); + #endif } } -- cgit v1.2.3 From 349cfd5090f586b7ec189b72c00786522199fe34 Mon Sep 17 00:00:00 2001 From: Douglas Rumbaugh Date: Wed, 1 May 2024 16:03:19 -0400 Subject: TS BSM Adjustments --- benchmarks/include/standard_benchmarks.h | 39 +++++++++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) (limited to 'benchmarks/include/standard_benchmarks.h') diff --git a/benchmarks/include/standard_benchmarks.h b/benchmarks/include/standard_benchmarks.h index 76b5f7c..1261a4c 100644 --- a/benchmarks/include/standard_benchmarks.h +++ b/benchmarks/include/standard_benchmarks.h @@ -22,6 +22,19 @@ static size_t g_deleted_records = 0; static double delete_proportion = 0.05; +static volatile size_t total = 0; + +template +static void run_queries(DE *extension, DE *ghost, std::vector &queries) { + for (size_t i=0; i res = extension->query(&queries[i]); + std::vector negres = ghost->query(&queries[i]); + auto result = res[0].first - negres[0].first; + total = result; + } +} + + template static void run_queries(DE *extension, std::vector &queries) { for (size_t i=0; i &queries) { fflush(stdout); #endif } else { + total = res.size(); #ifdef BENCH_PRINT_RESULTS fprintf(stdout, "\n\n"); for (int i=res.size()-1; i>=0; i--) { @@ -123,7 +137,6 @@ static void insert_records(psudb::bsm::BentleySaxe *extension, size_t start, size_t stop, std::vector &records) { psudb::progress_update(0, "Insert Progress"); - size_t reccnt = 0; for (size_t i=start; iinsert(records[i]); } @@ -132,6 +145,30 @@ static void insert_records(psudb::bsm::BentleySaxe *extension, } +template +static void insert_records(psudb::bsm::BentleySaxe *extension, + psudb::bsm::BentleySaxe *ghost, + size_t start, size_t stop, std::vector &records, + std::vector &to_delete, size_t &delete_idx, + gsl_rng *rng) { + + psudb::progress_update(0, "Insert Progress"); + size_t reccnt = 0; + for (size_t i=start; iinsert(records[i]); + + if (gsl_rng_uniform(rng) <= delete_proportion && to_delete[delete_idx] <= i) { + ghost->insert(records[to_delete[delete_idx]]); + delete_idx++; + g_deleted_records++; + } + + } + +} + + template static void insert_records(DE *structure, size_t start, size_t stop, std::vector &records, std::vector &to_delete, -- cgit v1.2.3 From 265610435e1164a9acc39ca02ea1139acd37c46c Mon Sep 17 00:00:00 2001 From: Douglas Rumbaugh Date: Thu, 9 May 2024 14:10:29 -0400 Subject: Added benchmarks for BigANN --- benchmarks/include/standard_benchmarks.h | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) (limited to 'benchmarks/include/standard_benchmarks.h') diff --git a/benchmarks/include/standard_benchmarks.h b/benchmarks/include/standard_benchmarks.h index 1261a4c..b805c08 100644 --- a/benchmarks/include/standard_benchmarks.h +++ b/benchmarks/include/standard_benchmarks.h @@ -55,7 +55,16 @@ static void run_queries(DE *extension, std::vector &queries) { r.data[1], r.data[2], r.data[3], r.data[4], r.data[5]); } #endif - } else if constexpr (std::is_same_v) { + } else if constexpr (std::is_same_v) { + std::vector result; + auto res = extension->get_nearest_by_limit(queries[i].point, queries[i].k); + + auto itr = res.begin(); + while (itr != res.end()) { + result.emplace_back(itr->data); + itr++; + } + }else if constexpr (std::is_same_v) { size_t tot = 0; auto ptr = extension->find(queries[i].lower_bound); while (ptr != extension->end() && ptr->first <= queries[i].upper_bound) { @@ -180,7 +189,7 @@ static void insert_records(DE *structure, size_t start, size_t stop, if constexpr (std::is_same_v) { structure->insert(records[i]); - } else if constexpr (std::is_same_v) { + } else if constexpr (std::is_same_v || std::is_same_v) { structure->add(records[i]); } else if constexpr (std::is_same_v) { structure->insert_or_assign(records[i].key, records[i].value); @@ -196,7 +205,7 @@ static void insert_records(DE *structure, size_t start, size_t stop, if constexpr (std::is_same_v) { structure->erase_one(records[to_delete[delete_idx]].key); - } else if constexpr (std::is_same_v) { + } else if constexpr (std::is_same_v || std::is_same_v) { structure->remove(records[to_delete[delete_idx]]); } else if constexpr (std::is_same_v) { structure->erase(records[to_delete[delete_idx]].key); @@ -255,7 +264,7 @@ static bool insert_tput_bench(DE &de_index, std::fstream &file, size_t insert_cn if constexpr (std::is_same_v) { de_index.erase_one(delete_vec[delete_idx++].key); #ifdef _GNU_SOURCE - } else if constexpr (std::is_same_v) { + } else if constexpr (std::is_same_v || std::is_same_v) { de_index.remove(delete_vec[delete_idx++]); #endif } else { @@ -266,7 +275,7 @@ static bool insert_tput_bench(DE &de_index, std::fstream &file, size_t insert_cn // insert the record; #ifdef _GNU_SOURCE - if constexpr (std::is_same_v) { + if constexpr (std::is_same_v || std::is_same_v) { de_index.add(insert_vec[i]); } else { de_index.insert(insert_vec[i]); -- cgit v1.2.3