From 99ea5e41426d4206b993b7bfca3261f47e8caa81 Mon Sep 17 00:00:00 2001 From: colin Date: Sat, 5 Apr 2025 20:49:06 +0800 Subject: [PATCH 1/3] Add TsFile benchmark. --- cpp/CMakeLists.txt | 7 +- cpp/bench_mark/CMakeLists.txt | 32 +- cpp/bench_mark/bench_mark_src/CMakeLists.txt | 57 - cpp/bench_mark/bench_mark_src/bench_mark.cc | 161 - cpp/bench_mark/build.sh | 29 +- .../{bench_mark_src => src}/bench_conf.h | 14 +- cpp/bench_mark/src/bench_mark.cc | 45 + cpp/bench_mark/src/bench_mark_c.cc | 257 ++ .../bench_mark.h => src/bench_mark_c_cpp.h} | 11 +- cpp/bench_mark/src/bench_mark_cpp.cc | 257 ++ cpp/bench_mark/src/bench_mark_utils.cc | 119 + cpp/bench_mark/src/bench_mark_utils.h | 33 + cpp/src/common/device_id.h | 95 +- cpp/src/common/schema.h | 2 +- cpp/src/common/tablet.cc | 3 +- cpp/src/common/tsfile_common.cc | 4 +- cpp/src/common/tsfile_common.h | 19 +- cpp/src/encoding/gorilla_decoder.h | 2 +- cpp/src/file/tsfile_io_reader.cc | 43 +- cpp/src/file/tsfile_io_reader.h | 11 +- cpp/src/reader/device_meta_iterator.cc | 4 +- cpp/src/writer/time_chunk_writer.cc | 3 + cpp/test/common/tsfile_common_test.cc | 28 +- java/bench_mark/pom.xml | 80 + .../java/org/apache/tsfile/BenchMark.java | 203 ++ .../java/org/apache/tsfile/BenchMarkConf.java | 82 + .../java/org/apache/tsfile/MemoryMonitor.java | 71 + java/pom.xml | 1 + python/bench_mark/bench_mark.py | 185 + python/bench_mark/memory_usage_python.csv | 3004 +++++++++++++++++ python/requirements.txt | 3 +- python/setup.py | 23 +- python/tsfile/tablet.py | 3 +- 33 files changed, 4523 insertions(+), 368 deletions(-) delete mode 100644 cpp/bench_mark/bench_mark_src/CMakeLists.txt delete mode 100644 cpp/bench_mark/bench_mark_src/bench_mark.cc rename cpp/bench_mark/{bench_mark_src => src}/bench_conf.h (74%) create mode 100644 cpp/bench_mark/src/bench_mark.cc create mode 100644 cpp/bench_mark/src/bench_mark_c.cc rename cpp/bench_mark/{bench_mark_src/bench_mark.h => src/bench_mark_c_cpp.h} (70%) create mode 100644 cpp/bench_mark/src/bench_mark_cpp.cc create mode 100644 cpp/bench_mark/src/bench_mark_utils.cc create mode 100644 cpp/bench_mark/src/bench_mark_utils.h create mode 100644 java/bench_mark/pom.xml create mode 100644 java/bench_mark/src/main/java/org/apache/tsfile/BenchMark.java create mode 100644 java/bench_mark/src/main/java/org/apache/tsfile/BenchMarkConf.java create mode 100644 java/bench_mark/src/main/java/org/apache/tsfile/MemoryMonitor.java create mode 100644 python/bench_mark/bench_mark.py create mode 100644 python/bench_mark/memory_usage_python.csv diff --git a/cpp/CMakeLists.txt b/cpp/CMakeLists.txt index 75684ce0c..ff1789d7c 100755 --- a/cpp/CMakeLists.txt +++ b/cpp/CMakeLists.txt @@ -26,7 +26,6 @@ if(CMAKE_CXX_COMPILER_ID MATCHES "GNU") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-error=maybe-uninitialized -D__STDC_FORMAT_MACROS") endif() -message("cmake using: USE_CPP11=${USE_CPP11}") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") if(DEFINED ENV{CXX}) @@ -104,7 +103,13 @@ add_subdirectory(third_party) add_subdirectory(src) add_subdirectory(test) add_subdirectory(examples) +add_subdirectory(bench_mark) +set(TESTS_ENABLED ON) if(TESTS_ENABLED) add_dependencies(TsFile_Test tsfile) endif() +set(BENCH_MARK_ENABLED ON) +if(BENCH_MARK_ENABLED) + add_dependencies(bench_mark tsfile) +endif() diff --git a/cpp/bench_mark/CMakeLists.txt b/cpp/bench_mark/CMakeLists.txt index 6db63999c..36f8dac97 100644 --- a/cpp/bench_mark/CMakeLists.txt +++ b/cpp/bench_mark/CMakeLists.txt @@ -17,17 +17,37 @@ specific language governing permissions and limitations under the License. ]] message("Running in bench_mark directory") +cmake_minimum_required(VERSION 3.11) +project(tsfile_bench_mark_project) + if(DEFINED ENV{CXX}) set(CMAKE_CXX_COMPILER $ENV{CXX}) endif() -set(CMAKE_CXX_FLAGS "$ENV{CXX_FLAGS} -Wall -Werror") +include_directories( + ${LIBRARY_INCLUDE_DIR} + ${THIRD_PARTY_INCLUDE} + ${CMAKE_SOURCE_DIR}/third_party/lz4 + ${CMAKE_SOURCE_DIR}/third_party/lzokay + ${CMAKE_SOURCE_DIR}/third_party/zlib-1.2.13 + ${CMAKE_SOURCE_DIR}/third_party/google_snappy + ${CMAKE_SOURCE_DIR}/third_party/antlr4-cpp-runtime-4/runtime/src + ${CMAKE_SOURCE_DIR}/src + +) -if (${USE_CPP11}) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") - set(CMAKE_CXX_STANDARD 11) +link_directories(${LIBRARY_OUTPUT_PATH}) +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") +if (CMAKE_BUILD_TYPE STREQUAL "Debug") + SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -O0") else() - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++03") + SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3") endif() +message("CMAKE DEBUG: CMAKE_CXX_FLAGS=${CMAKE_CXX_FLAGS}") -add_subdirectory(bench_mark_src) \ No newline at end of file +add_executable(bench_mark + src/bench_mark_cpp.cc + src/bench_mark_c.cc + src/bench_mark.cc + src/bench_mark_utils.cc) +target_link_libraries(bench_mark tsfile) diff --git a/cpp/bench_mark/bench_mark_src/CMakeLists.txt b/cpp/bench_mark/bench_mark_src/CMakeLists.txt deleted file mode 100644 index dbad71f91..000000000 --- a/cpp/bench_mark/bench_mark_src/CMakeLists.txt +++ /dev/null @@ -1,57 +0,0 @@ -#[[ -Licensed to the Apache Software Foundation (ASF) under one -or more contributor license agreements. See the NOTICE file -distributed with this work for additional information -regarding copyright ownership. The ASF licenses this file -to you under the Apache License, Version 2.0 (the -"License"); you may not use this file except in compliance -with the License. You may obtain a copy of the License at - - https://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, -software distributed under the License is distributed on an -"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -KIND, either express or implied. See the License for the -specific language governing permissions and limitations -under the License. -]] -cmake_minimum_required(VERSION 3.1) -project(libtsfile_bench_mark_project) -message("Running in bench_mark/bench_mark_src directory") -if(DEFINED ENV{CXX}) - set(CMAKE_CXX_COMPILER $ENV{CXX}) -endif() - -set(SDK_BENCH_MARK_DIR ${PROJECT_SOURCE_DIR}/) -message("PROJECT DIR: ${SDK_BENCH_MARK_DIR}") -set(SDK_INCLUDE_DIR_DEBUG ${SKD_BENCHH_MARK_DIR}../../build/Debug/bin/libtsfile_sdk/include) -set(SDK_INCLUDE_DIR_RELEASE ${SKD_BENCHH_MARK_DIR}../../build/Release/bin/libtsfile_sdk/include) -set(SDK_LIB_DIR_DEBUG ${SKD_BENCHH_MARK_DIR}../../build/Debug/bin/libtsfile_sdk/lib) -set(SDK_LIB_DIR_RELEASE ${SKD_BENCHH_MARK_DIR}../../build/Release/bin/libtsfile_sdk/lib) - -if (USE_SDK_DEBUG) - SET(SKD_INCLUDE_DIR ${SDK_INCLUDE_DIR_DEBUG}) - SET(SDK_LIB_DIR ${SDK_LIB_DIR_DEBUG}) - SET(CMAKE_CXX_FLAGS "-g -O0") -else() - SET(SKD_INCLUDE_DIR ${SDK_INCLUDE_DIR_RELEASE}) - SET(SDK_LIB_DIR ${SDK_LIB_DIR_RELEASE}) - SET(CMAKE_CXX_FLAGS "-O3") -endif() - -include_directories(${SKD_INCLUDE_DIR}) -set(MAKE_INCLUDE ${CMAKE_CURRENT_SOURCE_DIR}/../../src) -include_directories(${MAKE_INCLUDE}) -message("MAKE_INCLUDE: ${MAKE_INCLUDE}") -message("SDK_INCLUDE_DIR: ${SKD_INCLUDE_DIR}") -message("SDK_LIB_DIR: ${SDK_LIB_DIR}") - -link_directories(${SDK_LIB_DIR}) -find_library(my_tsfile_lib NAMES tsfile PATHS ${SDK_LIB_DIR} NO_DEFAULT_PATH REQUIRED) -add_executable(bench_mark_src bench_mark.cc) -target_link_libraries(bench_mark_src ${my_tsfile_lib}) - - - - diff --git a/cpp/bench_mark/bench_mark_src/bench_mark.cc b/cpp/bench_mark/bench_mark_src/bench_mark.cc deleted file mode 100644 index 09c9eb98f..000000000 --- a/cpp/bench_mark/bench_mark_src/bench_mark.cc +++ /dev/null @@ -1,161 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * License); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -#include -#include -#include -#include -#include - -#include "bench_conf.h" -#include "common/db_common.h" -#include "common/global.h" -#include "common/path.h" -#include "writer/tsfile_writer.h" - -std::vector register_timeseries(storage::TsFileWriter& writer, - int timeseries_num, - std::vector type_list) { - auto start = std::chrono::high_resolution_clock::now(); - int sum = std::accumulate(type_list.begin(), type_list.end(), 0); - std::vector ratio_list; - for (int i = 0; i < type_list.size(); i++) { - ratio_list.push_back((float)type_list[i] / sum); - } - std::vector type_num; - for (int i = 0; i < common::TSDataType::TEXT - 1; i++) { - type_num.push_back((int)std::ceil(timeseries_num * ratio_list[i])); - } - type_num.push_back(timeseries_num - - std::accumulate(type_num.begin(), type_num.end(), 0)); - writer.open("/tmp/tsfile_test.tsfile", O_CREAT | O_RDWR, 0644); - int ind = 0; - int ret = 0; - int type = 0; - for (auto num : type_num) { - for (int i = 0; i < num; i++) { - std::string device_name = "root.db001.dev" + std::to_string(ind); - std::string measurement_name = "m" + std::to_string(ind); - ret = writer.register_timeseries( - device_name, measurement_name, (common::TSDataType)type, - common::TSEncoding::PLAIN, - common::CompressionType::UNCOMPRESSED); - ind++; - } - std::cout << "register finished for TsDataType" - << common::s_data_type_names[type] - << " timeseries num: " << num << std::endl; - type++; - } - auto end = std::chrono::high_resolution_clock::now(); - std::chrono::duration elapsed = end - start; - std::cout << "register " << timeseries_num << "timeseries in file" - << "./test_data/tsfile_test.tsfile" << std::endl; - std::cout << "register timeseries cost time: " << elapsed.count() << "s" - << std::endl; - return type_num; -} - -void test_writer_benchmark(storage::TsFileWriter& writer, int loop_num, - std::vector type_num) { - std::cout << "start writing data" << std::endl; - auto start = std::chrono::high_resolution_clock::now(); - int type = 0; - for (int i = 0; i < loop_num; i++) { - int ind = 0; - for (auto num : type_num) { - for (int j = 0; j < num; j++) { - std::string device_name = - "root.db001.dev" + std::to_string(ind); - std::string measurement_name = "m" + std::to_string(ind); - long long currentTimeStamp = i; - storage::TsRecord record(currentTimeStamp, device_name, 1); - switch (type) { - case common::INT32: { - storage::DataPoint point(measurement_name, 10000 + i); - record.points_.push_back(point); - break; - } - case common::INT64: { - storage::DataPoint point(measurement_name, - int64_t(10000 + i)); - record.points_.push_back(point); - break; - } - case common::BOOLEAN: { - storage::DataPoint point(measurement_name, i / 2 == 0); - record.points_.push_back(point); - break; - } - case common::FLOAT: { - storage::DataPoint point(measurement_name, (float)i); - record.points_.push_back(point); - break; - } - case common::DOUBLE: { - storage::DataPoint point(measurement_name, (double)i); - record.points_.push_back(point); - break; - } - } - int ret = writer.write_record(record); - ASSERT(ret == 0); - ind++; - } - type++; - } - } - - auto end = std::chrono::high_resolution_clock::now(); - std::chrono::duration elapsed = end - start; - int timeseries_num = std::accumulate(type_num.begin(), type_num.end(), 0); - std::cout << "writer loop: " << loop_num - << " timeseries num: " << timeseries_num << " records in file" - << "./test_data/tsfile_test.tsfile" << std::endl; - std::cout << "total num of points: " << loop_num * timeseries_num - << std::endl; - std::cout << "writer data cost time: " << elapsed.count() << "s" - << std::endl; - std::cout << "writer data speed:" - << loop_num * timeseries_num / elapsed.count() << " points/s" - << std::endl; - writer.flush(); - writer.close(); - auto end_flush = std::chrono::high_resolution_clock::now(); - std::chrono::duration elapsed_flush = end_flush - end; - std::cout << "flush data cost time: " << elapsed_flush.count() << "s" - << std::endl; -} - -int main() { - std::cout << "LibTsFile benchmark" << std::endl; - std::cout << "LOOP_NUM:" << bench::LOOP_NUM << std::endl; - std::cout << "THREAD_NUM:" << bench::THREAD_NUM << std::endl; - std::cout << "TIMESERIES_NUM:" << bench::TIMESERIES_NUM << std::endl; - std::cout << "TYPE_LIST: " << bench::TYPE_LIST[0] << ":" - << bench::TYPE_LIST[1] << ":" << bench::TYPE_LIST[2] << ":" - << bench::TYPE_LIST[3] << ":" << bench::TYPE_LIST[4] << ":" - << bench::TYPE_LIST[5] << std::endl; - std::cout << "init tsfile config value" << std::endl; - common::init_config_value(); - storage::TsFileWriter writer; - auto type_num = - register_timeseries(writer, bench::TIMESERIES_NUM, bench::TYPE_LIST); - test_writer_benchmark(writer, bench::LOOP_NUM, type_num); - return 0; -} diff --git a/cpp/bench_mark/build.sh b/cpp/bench_mark/build.sh index e0e4b0cb6..2f40dee36 100644 --- a/cpp/bench_mark/build.sh +++ b/cpp/bench_mark/build.sh @@ -18,33 +18,10 @@ # build_type=Debug -env_for_cyber=0 use_cpp11=1 -if [[ ${env_for_cyber} -eq 1 ]] -then - export PATH=$PATH:~/dev/gcc-linaro-5.5.0-2017.10-x86_64_arm-linux-gnueabi/bin - export CROSS_COMPILE=arm-linux-gnueabi- - export ARCH=arm - export CC=${CROSS_COMPILE}gcc - export CXX=${CROSS_COMPILE}g++ - echo "set up gcc for cyber" -fi +mkdir -p build/Release +cd build/Release - -if [ ${build_type} = "Debug" ] -then - mkdir -p build/Debug - cd build/Debug - use_sdk_debug=1 -else - mkdir -p build/Release - cd build/Release - use_sdk_debug=0 -fi - -echo "use_sdk_debug=${use_sdk_debug}" -cmake ../../ \ - -DUSE_SDK_DEBUG=$use_sdk_debug \ - -DUSE_CPP11=$use_cpp11 +cmake ../../ make diff --git a/cpp/bench_mark/bench_mark_src/bench_conf.h b/cpp/bench_mark/src/bench_conf.h similarity index 74% rename from cpp/bench_mark/bench_mark_src/bench_conf.h rename to cpp/bench_mark/src/bench_conf.h index 486d0b14f..728c3fc1e 100644 --- a/cpp/bench_mark/bench_mark_src/bench_conf.h +++ b/cpp/bench_mark/src/bench_conf.h @@ -17,11 +17,17 @@ * under the License. */ +#ifndef TSFILE_BENCH_MARK_BENCH_CONF_H +#define TSFILE_BENCH_MARK_BENCH_CONF_H + #include namespace bench { -int LOOP_NUM = 100000; -int THREAD_NUM = 1; -int TIMESERIES_NUM = 50; -std::vector TYPE_LIST = {0, 0, 1, 0, 1}; +static int tablet_num = 1000; +static int tag1_num = 1; +static int tag2_num = 10; +static int timestamp_per_tag = 1000; +static std::vector field_type_vector = {1, 1, 1, 1, 1}; } // namespace bench + +#endif // TSFILE_BENCH_MARK_BENCH_CONF_H diff --git a/cpp/bench_mark/src/bench_mark.cc b/cpp/bench_mark/src/bench_mark.cc new file mode 100644 index 000000000..0d19d95b5 --- /dev/null +++ b/cpp/bench_mark/src/bench_mark.cc @@ -0,0 +1,45 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * License); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#include +#include + +#include "bench_mark_c_cpp.h" + +int main(int argc, char* argv[]) { + if (argc != 2) { + std::cerr << "Usage: " << argv[0] << " " << std::endl; + return 1; + } + + std::string mode(argv[1]); + + if (mode == "cpp") { + bench_mark_cpp_write(); + bench_mark_cpp_read(); + } else if (mode == "c") { + bench_mark_c_write(); + bench_mark_c_read(); + } else { + std::cerr << "Invalid mode. Use 'cpp' or 'c'." << std::endl; + return 1; + } + + return 0; +} diff --git a/cpp/bench_mark/src/bench_mark_c.cc b/cpp/bench_mark/src/bench_mark_c.cc new file mode 100644 index 000000000..f4ddca9b8 --- /dev/null +++ b/cpp/bench_mark/src/bench_mark_c.cc @@ -0,0 +1,257 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * License); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#include + +#include +#include +#include +#include + +#include + +#include "bench_conf.h" +#include "bench_mark_c_cpp.h" +#include "bench_mark_utils.h" +#include "cwrapper/tsfile_cwrapper.h" +#define HANDLE_ERROR(err_no) \ + do { \ + if (err_no != 0) { \ + printf("get err no: %d", err_no); \ + return err_no; \ + } \ + } while (0) + +char** column_list; +TSDataType* data_types_c; +int column_num_c = 0; + +int bench_mark_c_write() { + ERRNO code = 0; + char* table_name = "TestTable"; + print_config(false); + TableSchema table_schema; + + + table_schema.table_name = strdup(table_name); + int column = 0; + for (auto data_type : bench::field_type_vector) { + column += data_type; + } + column_list = new char*[column + 2]; + data_types_c = new TSDataType[column + 2]; + column_num_c = column; + + std::ofstream csv_file("memory_usage_c.csv"); + if (!csv_file.is_open()) { + std::cout << "csv create failed!" << std::endl; + return 0; + } + csv_file << "iter_num,memory_usage(kb)\n"; + int iter_num = 0; + csv_file << iter_num++ <<","<< get_memory_usage() << "\n"; + + table_schema.column_schemas = + (ColumnSchema*)malloc(sizeof(ColumnSchema) * (2 + column)); + table_schema.column_num = column + 2; + table_schema.column_schemas[0] = + (ColumnSchema){.column_name = strdup("TAG1"), + .data_type = TS_DATATYPE_STRING, + .column_category = TAG}; + column_list[0] = strdup("TAG1"); + data_types_c[0] = TS_DATATYPE_STRING; + table_schema.column_schemas[1] = + (ColumnSchema){.column_name = strdup("TAG2"), + .data_type = TS_DATATYPE_STRING, + .column_category = TAG}; + column_list[1] = strdup("TAG2"); + data_types_c[1] = TS_DATATYPE_STRING; + + int col = 2; + for (int i = 0; i < bench::field_type_vector.size(); i++) { + int column_num = bench::field_type_vector[i]; + for (int j = 0; j < column_num; j++) { + column_list[col] = + strdup(std::string("FIELD" + std::to_string(i)).c_str()); + data_types_c[col] = static_cast(data_type[i]); + table_schema.column_schemas[col++] = (ColumnSchema){ + .column_name = + strdup(std::string("FIELD" + std::to_string(i)).c_str()), + .data_type = static_cast(data_type[i]), + .column_category = FIELD}; + } + } + + remove("bench_mark_c.tsfile"); + WriteFile file = write_file_new("bench_mark_c.tsfile", &code); + HANDLE_ERROR(code); + TsFileWriter writer = tsfile_writer_new(file, &table_schema, &code); + HANDLE_ERROR(code); + free_table_schema(table_schema); + int64_t prepare_time = 0; + int64_t writing_time = 0; + int64_t timestamp = 0; + int64_t row_num = + bench::tag1_num * bench::tag2_num * bench::timestamp_per_tag; + auto start = std::chrono::high_resolution_clock::now(); + for (int i = 0; i < bench::tablet_num; i++) { + csv_file << iter_num++ <<","<< get_memory_usage() << "\n"; + int cur_row = 0; + print_progress_bar(i, bench::tablet_num); + auto prepare_start = std::chrono::high_resolution_clock::now(); + auto tablet = + tablet_new(column_list, data_types_c, column + 2, row_num); + for (int tag1 = 0; tag1 < bench::tag1_num; tag1++) { + for (int tag2 = 0; tag2 < bench::tag2_num; tag2++) { + for (int row = 0; row < bench::timestamp_per_tag; row++) { + tablet_add_timestamp(tablet, cur_row, timestamp + row); + tablet_add_value_by_index_string( + tablet, cur_row, 0, + std::string("TAG1_" + std::to_string(tag1)).c_str()); + tablet_add_value_by_index_string( + tablet, cur_row, 1, + std::string("TAG2_" + std::to_string(tag2)).c_str()); + for (int col = 2; col < column + 2; col++) { + switch (data_types_c[col]) { + case TS_DATATYPE_INT32: + tablet_add_value_by_index_int32_t( + tablet, cur_row, col, + static_cast(timestamp)); + break; + case TS_DATATYPE_INT64: + tablet_add_value_by_index_int64_t( + tablet, cur_row, col, + static_cast(timestamp)); + break; + case TS_DATATYPE_FLOAT: + tablet_add_value_by_index_float( + tablet, cur_row, col, + static_cast(timestamp)); + break; + case TS_DATATYPE_DOUBLE: + tablet_add_value_by_index_double( + tablet, cur_row, col, + static_cast(timestamp)); + break; + case TS_DATATYPE_BOOLEAN: + tablet_add_value_by_index_bool( + tablet, cur_row, col, + static_cast(timestamp % 2)); + break; + default: + ; + } + } + cur_row++; + } + } + } + csv_file << iter_num++ <<","<< get_memory_usage() << "\n"; + auto prepare_end = std::chrono::high_resolution_clock::now(); + prepare_time += std::chrono::duration_cast( + prepare_end - prepare_start) + .count(); + + auto writing_start = std::chrono::high_resolution_clock::now(); + tsfile_writer_write(writer, tablet); + auto writing_end = std::chrono::high_resolution_clock::now(); + writing_time += std::chrono::duration_cast( + writing_end - writing_start) + .count(); + free_tablet(&tablet); + timestamp += bench::timestamp_per_tag; + csv_file << iter_num++ <<","<< get_memory_usage() << "\n"; + } + + csv_file << iter_num++ <<","<< get_memory_usage() << "\n"; + auto close_start = std::chrono::high_resolution_clock::now(); + tsfile_writer_close(writer); + auto close_end = std::chrono::high_resolution_clock::now(); + + writing_time += std::chrono::duration_cast( + close_end - close_start) + .count(); + free_write_file(&file); + auto end = std::chrono::high_resolution_clock::now(); + + csv_file << iter_num++ <<","<< get_memory_usage() << "\n"; + FILE* file_to_size = fopen("bench_mark_c.tsfile", "rb"); + if (!file_to_size) { + std::cout << "unable to open file" << std::endl; + return -1; + } + fseeko(file_to_size, 0, SEEK_END); + off_t size = ftello(file_to_size); + fclose(file_to_size); + + std::cout << "=======" << std::endl; + std::cout << "Finish writing for C" << std::endl; + std::cout << "Tsfile size is " << size << " bytes " << " ~ " << size / 1024 + << "KB" << std::endl; + + double pre_time = prepare_time / 1000.0 / 1000.0; + double write_time = writing_time / 1000.0 / 1000.0; + std::cout << "Preparing time is " << pre_time << " s" << std::endl; + std::cout << "Writing time is " << write_time << " s" << std::endl; + std::cout << "writing speed is " + << static_cast( + bench::tablet_num * bench::tag1_num * bench::tag2_num * + bench::timestamp_per_tag * (column_num_c + 2) / + (pre_time + write_time)) + << " points/s" << std::endl; + std::cout << "total time is " + << std::chrono::duration_cast(end - + start) + .count() / + 1000.0 / 1000.0 + << " s" << std::endl; + std::cout << "========" << std::endl; + return 0; +} + +int bench_mark_c_read() { + std::cout << "Bench mark c read" << std::endl; + int code = common::E_OK; + TsFileReader reader = tsfile_reader_new("bench_mark_c.tsfile", &code); + ResultSet result = + tsfile_query_table(reader, "TestTable", column_list, column_num_c, + INT64_MIN, INT64_MAX, &code); + int64_t row = 0; + auto read_start = std::chrono::high_resolution_clock::now(); + while (tsfile_result_set_next(result, &code) && code == common::E_OK) { + row++; + } + auto read_end = std::chrono::high_resolution_clock::now(); + int64_t total_points = row * column_num_c; + double reading_time; + reading_time = std::chrono::duration_cast( + read_end - read_start) + .count() / + 1000.0 / 1000.0; + + std::cout << "total points is " << total_points << std::endl; + std::cout << "reading time is " << reading_time << " s" << std::endl; + std::cout << "read speed:" + << static_cast(total_points / reading_time) + << " points/s" << std::endl; + std::cout << "====================" << std::endl; + free_tsfile_result_set(&result); + tsfile_reader_close(reader); + return 0; +} \ No newline at end of file diff --git a/cpp/bench_mark/bench_mark_src/bench_mark.h b/cpp/bench_mark/src/bench_mark_c_cpp.h similarity index 70% rename from cpp/bench_mark/bench_mark_src/bench_mark.h rename to cpp/bench_mark/src/bench_mark_c_cpp.h index e3bbd95d6..001de9c49 100644 --- a/cpp/bench_mark/bench_mark_src/bench_mark.h +++ b/cpp/bench_mark/src/bench_mark_c_cpp.h @@ -1,5 +1,5 @@ /* - * Licensed to the Apache Software Foundation (ASF) under one +* Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file @@ -16,3 +16,12 @@ * specific language governing permissions and limitations * under the License. */ +#ifndef TSFILE_BENCH_MARK_BENCH_MARK_C_CPP_H +#define TSFILE_BENCH_MARK_BENCH_MARK_C_CPP_H + +int bench_mark_c_write(); +int bench_mark_cpp_read(); +int bench_mark_cpp_write(); +int bench_mark_c_read(); + +#endif // TSFILE_BENCH_MARK_BENCH_MARK_C_CPP_H \ No newline at end of file diff --git a/cpp/bench_mark/src/bench_mark_cpp.cc b/cpp/bench_mark/src/bench_mark_cpp.cc new file mode 100644 index 000000000..2467c9f87 --- /dev/null +++ b/cpp/bench_mark/src/bench_mark_cpp.cc @@ -0,0 +1,257 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * License); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#include + +#include +#include +#include +#include + +#include "bench_conf.h" +#include "bench_mark_c_cpp.h" +#include "bench_mark_utils.h" +#include "common/db_common.h" +#include "common/path.h" +#include "common/tablet.h" +#include "file/write_file.h" +#include "utils/db_utils.h" +#include "writer/tsfile_table_writer.h" + +using namespace storage; +using namespace common; + +std::vector columns_name; +std::vector data_types; + +TableSchema* gen_table_schema(const std::vector& field_type_vector) { + std::vector schemas; + // 2 TAG Columns default + for (int i = 0; i < 2; i++) { + std::string column_name = std::string("TAG" + std::to_string(i)); + schemas.emplace_back(column_name, common::TSDataType::STRING, + common::ColumnCategory::TAG); + columns_name.push_back(column_name); + data_types.push_back(TSDataType::STRING); + } + for (int i = 0; i < field_type_vector.size(); i++) { + int column_num = field_type_vector[i]; + for (int j = 0; j < column_num; j++) { + auto column_name = + std::string("FIELD" + std::to_string(i) + std::to_string(j)); + auto type = static_cast(data_type[i]); + data_types.push_back(type); + columns_name.push_back(column_name); + schemas.emplace_back(column_name, type, ColumnCategory::FIELD); + } + } + return new TableSchema("TestTable", schemas); +} + +int bench_mark_cpp_write() { + int code = common::E_OK; + print_config(true); + remove("bench_mark_cpp.tsfile"); + libtsfile_init(); + // benchmark for write + WriteFile file = WriteFile(); + + int flags = O_WRONLY | O_CREAT | O_TRUNC; +#ifdef _WIN32 + flags |= O_BINARY; +#endif + mode_t mode = 0666; + code = file.create("bench_mark_cpp.tsfile", flags, mode); + if (code != common::E_OK) { + return -1; + } + + std::ofstream csv_file("memory_usage_cpp.csv"); + if (!csv_file.is_open()) { + std::cout << "csv create failed!" << std::endl; + return 0; + } + csv_file << "iter_num,memory_usage(kb)\n"; + int iter_num = 0; + csv_file << iter_num++ <<","<< get_memory_usage() << "\n"; + + TableSchema* table_schema = gen_table_schema(bench::field_type_vector); + auto writer = new TsFileTableWriter(&file, table_schema); + delete (table_schema); + + int64_t timestamp = 0; + int64_t prepare_time = 0; + int64_t writing_time = 0; + + auto start = std::chrono::high_resolution_clock::now(); + + + for (int tablet_i = 0; tablet_i < bench::tablet_num; tablet_i++) { + csv_file << iter_num++ <<","<< get_memory_usage() << "\n"; + print_progress_bar(tablet_i, bench::tablet_num); + auto prepare_start = std::chrono::high_resolution_clock::now(); + auto tablet = Tablet( + columns_name, data_types, + bench::tag1_num * bench::tag2_num * bench::timestamp_per_tag); + int row_num = 0; + for (int tag1 = 0; tag1 < bench::tag1_num; tag1++) { + for (int tag2 = 0; tag2 < bench::tag2_num; tag2++) { + for (int row = 0; row < bench::timestamp_per_tag; row++) { + tablet.add_timestamp(row_num, timestamp + row); + tablet.add_value( + row_num, 0, + std::string("tag1_" + std::to_string(tag1)).c_str()); + tablet.add_value( + row_num, 1, + std::string("tag2_" + std::to_string(tag2)).c_str()); + for (int col = 0; col < data_types.size(); col++) { + switch (data_types[col]) { + case TSDataType::INT32: + tablet.add_value( + row_num, col, + static_cast(timestamp)); + break; + case TSDataType::INT64: + tablet.add_value( + row_num, col, + static_cast(timestamp)); + break; + case TSDataType::FLOAT: + tablet.add_value( + row_num, col, + static_cast(timestamp * 1.1)); + break; + case TSDataType::DOUBLE: + tablet.add_value( + row_num, col, + static_cast(timestamp * 1.1)); + break; + + case TSDataType::BOOLEAN: + tablet.add_value( + row_num, col, + static_cast(timestamp % 2)); + break; + default: + ; + } + } + row_num++; + } + } + } + csv_file << iter_num++ <<","<< get_memory_usage() << "\n"; + auto prepare_end = std::chrono::high_resolution_clock::now(); + + prepare_time += std::chrono::duration_cast( + prepare_end - prepare_start) + .count(); + + auto write_start = std::chrono::high_resolution_clock::now(); + writer->write_table(tablet); + auto write_end = std::chrono::high_resolution_clock::now(); + writing_time += std::chrono::duration_cast( + write_end - write_start) + .count(); + timestamp += bench::timestamp_per_tag; + csv_file << iter_num++ <<","<< get_memory_usage() << "\n"; + } + csv_file << iter_num++ <<","<< get_memory_usage() << "\n"; + auto close_start = std::chrono::high_resolution_clock::now(); + writer->flush(); + csv_file << iter_num++ <<","<< get_memory_usage() << "\n"; + writer->close(); + csv_file << iter_num++ <<","<< get_memory_usage() << "\n"; + auto close_end = std::chrono::high_resolution_clock::now(); + + writing_time += std::chrono::duration_cast( + close_end - close_start) + .count(); + delete writer; + auto end = std::chrono::high_resolution_clock::now(); + + FILE* file_to_size = fopen("bench_mark_cpp.tsfile", "rb"); + if (!file_to_size) { + std::cout << "unable to open file" << std::endl; + return -1; + } + csv_file << iter_num++ <<","<< get_memory_usage() << "\n"; + fseeko(file_to_size, 0, SEEK_END); + off_t size = ftello(file_to_size); + fclose(file_to_size); + + std::cout << "=======" << std::endl; + std::cout << "Finish writing for CPP" << std::endl; + std::cout << "Tsfile size is " << size << " bytes " << " ~ " << size / 1024 + << "KB" << std::endl; + + double pre_time = prepare_time / 1000.0 / 1000.0; + double write_time = writing_time / 1000.0 / 1000.0; + std::cout << "Preparing time is " << pre_time << " s" << std::endl; + std::cout << "Writing time is " << write_time << " s" << std::endl; + std::cout << "writing speed is " + << static_cast( + bench::tablet_num * bench::tag1_num * bench::tag2_num * + bench::timestamp_per_tag * data_types.size() / + (pre_time + write_time)) + << " points/s" << std::endl; + std::cout << "total time is " + << std::chrono::duration_cast(end - + start) + .count() / + 1000.0 / 1000.0 + << " s" << std::endl; + std::cout << "=====" << std::endl; + return 0; +} + +int bench_mark_cpp_read() { + std::cout << "bench mark cpp read" << std::endl; + libtsfile_init(); + int code = common::E_OK; + TsFileReader reader = TsFileReader(); + reader.open("bench_mark_cpp.tsfile"); + ResultSet* result_set = nullptr; + code = reader.query("TestTable", columns_name, INT64_MIN, INT64_MAX, + result_set); + bool has_next = false; + int row = 0; + auto read_start = std::chrono::high_resolution_clock::now(); + std::unordered_map columns_info; + while ((code = result_set->next(has_next)) == common::E_OK && has_next) { + row++; + } + result_set->close(); + reader.close(); + delete result_set; + auto read_end = std::chrono::high_resolution_clock::now(); + int64_t total_points = row * columns_name.size(); + double reading_time = std::chrono::duration_cast( + read_end - read_start) + .count() / + 1000.0 / 1000.0; + + std::cout << "total points is " << total_points << std::endl; + std::cout << "reading time is " << reading_time << " s" << std::endl; + std::cout << "read speed:" + << static_cast(total_points / reading_time) + << " points/s" << std::endl; + std::cout << "====================" << std::endl; + return 0; +} diff --git a/cpp/bench_mark/src/bench_mark_utils.cc b/cpp/bench_mark/src/bench_mark_utils.cc new file mode 100644 index 000000000..841f8c0c8 --- /dev/null +++ b/cpp/bench_mark/src/bench_mark_utils.cc @@ -0,0 +1,119 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * License); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#include "bench_mark_utils.h" + +#include + +#include +#include +#include + +#ifdef __APPLE__ +#include +#include +#include +#include +#endif + + +#include "bench_conf.h" +using namespace bench; + +void print_config(bool is_cpp) { + std::cout << "====================" << std::endl; + std::cout << "TsFile Benchmark "<< (is_cpp ? "CPP" : "C") <<" Begin " << std::endl; + std::cout << "Tag Column num: " << 2 << std::endl; + std::cout << "TAG1 num: " << tag1_num << " TAG2 num: " << tag2_num + << std::endl; + std::cout << "Filed column (type x num) : " << std::endl; + int column_num = 0; + for (int i = 0; i < 5; i++) { + std::cout << data_types_name[i] << "x" << field_type_vector[i] << " "; + column_num += field_type_vector[i]; + } + + std::cout << std::endl; + std::cout << "Tablet num:" << tablet_num << std::endl; + std::cout << "Tablet row num per tag:" << timestamp_per_tag << std::endl; + std::cout << "Total points is " + << tablet_num * tag1_num * tag2_num * timestamp_per_tag * + (column_num) + << std::endl; +} + +void print_progress_bar(int current, int total, int barWidth) { + float progress = static_cast(current) / total; + int pos = barWidth * progress; + + std::cout << "["; + for (int i = 0; i < barWidth; ++i) { + if (i < pos) + std::cout << "="; + else if (i == pos) + std::cout << ">"; + else + std::cout << " "; + } + std::cout << "] " << int(progress * 100.0) << " %\r"; + std::cout.flush(); +} + +int get_memory_usage() { +#ifdef _WIN32 +#include +#include + PROCESS_MEMORY_COUNTERS pmc; + if (GetProcessMemoryInfo(GetCurrentProcess(), &pmc, sizeof(pmc))) { + return pmc.WorkingSetSize / 1024 ; + } else { + return 0; + } +#elif defined(__linux__) + std::ifstream status_file("/proc/self/status"); + std::string line; + while (std::getline(status_file, line)) { + if (line.find("VmRSS") == 0) { + size_t num_pos = line.find_first_of("0123456789"); + if (num_pos != std::string::npos) { + size_t end_pos = line.find_first_not_of("1234567890", num_pos); + std::string num_str = line.substr(num_pos, end_pos - num_pos); + + unsigned long vm_rss_kb = strtoul(num_str.c_str(), nullptr, 10); + return vm_rss_kb; + } + } + } +#elif defined(__APPLE__) + + task_basic_info_data_t info; + mach_msg_type_number_t count = TASK_BASIC_INFO_COUNT; + kern_return_t ret = task_info( + mach_task_self(), + TASK_BASIC_INFO, + (task_info_t)&info, + &count + ); + if (ret == KERN_SUCCESS) { + return info.resident_size / 1024 ; + } else { + return 0; + } +#endif +} diff --git a/cpp/bench_mark/src/bench_mark_utils.h b/cpp/bench_mark/src/bench_mark_utils.h new file mode 100644 index 000000000..4027ffc61 --- /dev/null +++ b/cpp/bench_mark/src/bench_mark_utils.h @@ -0,0 +1,33 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * License); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#ifndef TSFILE_BENCH_MARK_BENCH_MARK_UTILS_H +#define TSFILE_BENCH_MARK_BENCH_MARK_UTILS_H + + +static const char* data_types_name[5] = {"BOOLEAN", "INT32", "INT64", "FLOAT", + "DOUBLE"}; +static const int data_type[5] = {0, 1, 2, 3, 4}; + +void print_config(bool is_cpp); +void print_progress_bar(int current, int total, int barWidth = 50); +int get_memory_usage(); + + +#endif // TSFILE_BENCH_MARK_BENCH_MARK_UTILS_H \ No newline at end of file diff --git a/cpp/src/common/device_id.h b/cpp/src/common/device_id.h index 021cb6aaf..195207eb0 100644 --- a/cpp/src/common/device_id.h +++ b/cpp/src/common/device_id.h @@ -35,7 +35,7 @@ namespace storage { class IDeviceID { -public: + public: virtual ~IDeviceID() = default; virtual int serialize(common::ByteStream& write_stream) { return 0; } virtual int deserialize(common::ByteStream& read_stream) { return 0; } @@ -49,10 +49,10 @@ class IDeviceID { virtual bool operator==(const IDeviceID& other) { return false; } virtual bool operator!=(const IDeviceID& other) { return false; } -protected: + protected: IDeviceID() : empty_segments_() {} -private: + private: const std::vector empty_segments_; }; @@ -64,7 +64,7 @@ struct IDeviceIDComparator { }; class StringArrayDeviceID : public IDeviceID { -public: + public: explicit StringArrayDeviceID(const std::vector& segments) : segments_(formalize(segments)) {} @@ -73,14 +73,19 @@ class StringArrayDeviceID : public IDeviceID { explicit StringArrayDeviceID() : segments_() {} + StringArrayDeviceID(const std::vector& segments, bool internal) + : segments_(segments) {} + ~StringArrayDeviceID() override = default; std::string get_device_name() const override { - return segments_.empty() ? "" : std::accumulate(std::next(segments_.begin()), segments_.end(), - segments_.front(), - [](std::string a, const std::string& b) { - return std::move(a) + "." + b; - }); + return segments_.empty() + ? "" + : std::accumulate(std::next(segments_.begin()), + segments_.end(), segments_.front(), + [](std::string a, const std::string& b) { + return std::move(a) + "." + b; + }); }; int serialize(common::ByteStream& write_stream) override { @@ -88,12 +93,12 @@ class StringArrayDeviceID : public IDeviceID { if (RET_FAIL(common::SerializationUtil::write_var_uint(segment_num(), write_stream))) { return ret; - } + } for (const auto& segment : segments_) { - if (RET_FAIL(common::SerializationUtil::write_var_str(segment, - write_stream))) { + if (RET_FAIL(common::SerializationUtil::write_var_str( + segment, write_stream))) { return ret; - } + } } return ret; } @@ -101,13 +106,15 @@ class StringArrayDeviceID : public IDeviceID { int deserialize(common::ByteStream& read_stream) override { int ret = common::E_OK; uint32_t num_segments; - if (RET_FAIL(common::SerializationUtil::read_var_uint(num_segments, read_stream))) { + if (RET_FAIL(common::SerializationUtil::read_var_uint(num_segments, + read_stream))) { return ret; } segments_.clear(); for (uint32_t i = 0; i < num_segments; ++i) { std::string segment; - if (RET_FAIL(common::SerializationUtil::read_var_str(segment, read_stream))) { + if (RET_FAIL(common::SerializationUtil::read_var_str( + segment, read_stream))) { return ret; } segments_.push_back(segment); @@ -133,17 +140,26 @@ class StringArrayDeviceID : public IDeviceID { } bool operator==(const IDeviceID& other) override { - auto other_segments = other.get_segments(); - return (segments_.size() == other_segments.size()) && - std::equal(segments_.begin(), segments_.end(), - other_segments.begin()); + auto const& other_segments = other.get_segments(); + if (segments_.size() != other_segments.size()) { + return false; + } + + for (size_t i = 0; i < segments_.size(); ++i) { + const std::string& a = segments_[i]; + const std::string& b = other_segments[i]; + + if (a.size() != b.size()) return false; + if (a != b) return false; + } + return true; } bool operator!=(const IDeviceID& other) override { return !(*this == other); } -private: + private: std::vector segments_; std::vector formalize( @@ -173,8 +189,9 @@ class StringArrayDeviceID : public IDeviceID { if (segment_cnt == 1) { // "root" -> {"root"} final_segments.push_back(splits[0]); - } else if (segment_cnt < static_cast( - storage::DEFAULT_SEGMENT_NUM_FOR_TABLE_NAME + 1)) { + } else if (segment_cnt < + static_cast( + storage::DEFAULT_SEGMENT_NUM_FOR_TABLE_NAME + 1)) { // "root.a" -> {"root", "a"} // "root.a.b" -> {"root.a", "b"} std::string table_name = std::accumulate( @@ -184,26 +201,26 @@ class StringArrayDeviceID : public IDeviceID { }); final_segments.push_back(table_name); final_segments.push_back(splits.back()); - } else { - // "root.a.b.c" -> {"root.a.b", "c"} - // "root.a.b.c.d" -> {"root.a.b", "c", "d"} - std::string table_name = std::accumulate( - splits.begin(), - splits.begin() + storage::DEFAULT_SEGMENT_NUM_FOR_TABLE_NAME, - std::string(), [](const std::string& a, const std::string& b) { - return a.empty() ? b : a + storage::PATH_SEPARATOR + b; - }); - - final_segments.emplace_back(std::move(table_name)); - final_segments.insert( - final_segments.end(), - splits.begin() + storage::DEFAULT_SEGMENT_NUM_FOR_TABLE_NAME, - splits.end()); - } + } else { + // "root.a.b.c" -> {"root.a.b", "c"} + // "root.a.b.c.d" -> {"root.a.b", "c", "d"} + std::string table_name = std::accumulate( + splits.begin(), + splits.begin() + storage::DEFAULT_SEGMENT_NUM_FOR_TABLE_NAME, + std::string(), [](const std::string& a, const std::string& b) { + return a.empty() ? b : a + storage::PATH_SEPARATOR + b; + }); + + final_segments.emplace_back(std::move(table_name)); + final_segments.insert( + final_segments.end(), + splits.begin() + storage::DEFAULT_SEGMENT_NUM_FOR_TABLE_NAME, + splits.end()); + } return final_segments; } }; -} +} // namespace storage #endif \ No newline at end of file diff --git a/cpp/src/common/schema.h b/cpp/src/common/schema.h index 72fd028f5..67dbfb91a 100644 --- a/cpp/src/common/schema.h +++ b/cpp/src/common/schema.h @@ -63,7 +63,7 @@ struct MeasurementSchema { : measurement_name_(measurement_name), data_type_(data_type), encoding_(get_default_encoding_for_type(data_type)), - compression_type_(common::UNCOMPRESSED), + compression_type_(common::get_default_compression_for_type(data_type)), chunk_writer_(nullptr), value_chunk_writer_(nullptr) {} diff --git a/cpp/src/common/tablet.cc b/cpp/src/common/tablet.cc index ac4a2708b..a8c9e3eb2 100644 --- a/cpp/src/common/tablet.cc +++ b/cpp/src/common/tablet.cc @@ -325,6 +325,7 @@ void Tablet::set_column_categories( std::shared_ptr Tablet::get_device_id(int i) const { std::vector id_array; + id_array.reserve(id_column_indexes_.size() + 1); id_array.push_back(insert_target_name_); for (auto id_column_idx : id_column_indexes_) { common::TSDataType data_type = INVALID_DATATYPE; @@ -339,7 +340,7 @@ std::shared_ptr Tablet::get_device_id(int i) const { break; } } - return std::make_shared(id_array); + return std::make_shared(id_array, true); } } // end namespace storage \ No newline at end of file diff --git a/cpp/src/common/tsfile_common.cc b/cpp/src/common/tsfile_common.cc index 89a007ba0..17c3d479b 100644 --- a/cpp/src/common/tsfile_common.cc +++ b/cpp/src/common/tsfile_common.cc @@ -260,7 +260,7 @@ int TsFileMeta::deserialize_from(common::ByteStream &in) { /* ================ MetaIndexNode ================ */ int MetaIndexNode::binary_search_children(std::shared_ptr key, bool exact_search, - IMetaIndexEntry &ret_index_entry, + std::shared_ptr &ret_index_entry, int64_t &ret_end_offset) { #if DEBUG_SE std::cout << "MetaIndexNode::binary_search_children start, name=" << key @@ -311,7 +311,7 @@ int MetaIndexNode::binary_search_children(std::shared_ptr key, bool return E_NOT_EXIST; } } - ret_index_entry.clone(children_[l], pa_); + ret_index_entry = children_[l]->clone(pa_); if (l == (int)children_.size() - 1) { ret_end_offset = this->end_offset_; } else { diff --git a/cpp/src/common/tsfile_common.h b/cpp/src/common/tsfile_common.h index 9fca01689..878fc4d21 100644 --- a/cpp/src/common/tsfile_common.h +++ b/cpp/src/common/tsfile_common.h @@ -738,15 +738,14 @@ struct IMetaIndexEntry { common::PageArena *pa) { return common::E_NOT_SUPPORT; } - virtual int64_t get_offset() const { return 0; } + virtual int64_t get_offset() const = 0; virtual bool is_device_level() const { return false; } virtual std::shared_ptr get_compare_key() const { return std::shared_ptr(); } virtual common::String get_name() const { return {}; } virtual std::shared_ptr get_device_id() const { return nullptr; } - virtual void clone(std::shared_ptr entry, - common::PageArena *pa) {} + virtual std::shared_ptr clone(common::PageArena *pa) = 0; #ifndef NDEBUG virtual void print(std::ostream &os) const {} friend std::ostream &operator<<(std::ostream &os, @@ -801,10 +800,8 @@ struct DeviceMetaIndexEntry : IMetaIndexEntry { std::shared_ptr get_device_id() const override { return device_id_; } - void clone(std::shared_ptr entry, - common::PageArena *pa) override { - offset_ = entry->get_offset(); - device_id_ = entry->get_device_id(); + std::shared_ptr clone(common::PageArena *pa) override { + return std::make_shared(device_id_, offset_); } #ifndef NDEBUG void print(std::ostream &os) const override { @@ -862,10 +859,8 @@ struct MeasurementMetaIndexEntry : IMetaIndexEntry { std::shared_ptr get_device_id() const override { return nullptr; } - void clone(std::shared_ptr entry, - common::PageArena *pa) override { - offset_ = entry->get_offset(); - name_.dup_from(entry->get_name(), *pa); + std::shared_ptr clone(common::PageArena *pa) override { + return std::make_shared(name_, offset_, *pa); } #ifndef NDEBUG void print(std::ostream &os) const override { @@ -915,7 +910,7 @@ struct MetaIndexNode { int binary_search_children(std::shared_ptr key, bool exact_search, - IMetaIndexEntry &ret_index_entry, + std::shared_ptr &ret_index_entry, int64_t &ret_end_offset); int serialize_to(common::ByteStream &out) { diff --git a/cpp/src/encoding/gorilla_decoder.h b/cpp/src/encoding/gorilla_decoder.h index 5b241de4f..f374b32eb 100644 --- a/cpp/src/encoding/gorilla_decoder.h +++ b/cpp/src/encoding/gorilla_decoder.h @@ -44,7 +44,7 @@ class GorillaDecoder : public Decoder { stored_trailing_zeros_ = 0; bits_left_ = 0; first_value_was_read_ = false; - has_next_ = true; + has_next_ = false; buffer_ = 0; } diff --git a/cpp/src/file/tsfile_io_reader.cc b/cpp/src/file/tsfile_io_reader.cc index 11113fc0f..a25669594 100644 --- a/cpp/src/file/tsfile_io_reader.cc +++ b/cpp/src/file/tsfile_io_reader.cc @@ -93,7 +93,7 @@ int TsFileIOReader::get_device_timeseries_meta_without_chunk_meta( PageArena &pa) { int ret = E_OK; load_tsfile_meta_if_necessary(); - DeviceMetaIndexEntry meta_index_entry; + std::shared_ptr meta_index_entry; int64_t end_offset; std::vector, int64_t> > meta_index_entry_list; @@ -101,7 +101,7 @@ int TsFileIOReader::get_device_timeseries_meta_without_chunk_meta( load_device_index_entry(std::make_shared(device_id), meta_index_entry, end_offset))) { } else if (RET_FAIL(load_all_measurement_index_entry( - meta_index_entry.offset_, end_offset, pa, + meta_index_entry->get_offset(), end_offset, pa, meta_index_entry_list))) { } else if (RET_FAIL(do_load_all_timeseries_index(meta_index_entry_list, pa, timeseries_indexs))) { @@ -215,20 +215,20 @@ int TsFileIOReader::load_timeseries_index_for_ssi( std::shared_ptr device_id, const std::string &measurement_name, TsFileSeriesScanIterator *&ssi) { int ret = E_OK; - DeviceMetaIndexEntry device_index_entry; + std::shared_ptr device_index_entry; int64_t device_ie_end_offset = 0; - MeasurementMetaIndexEntry measurement_index_entry; + std::shared_ptr measurement_index_entry; int64_t measurement_ie_end_offset = 0; // bool is_aligned = false; if (RET_FAIL(load_device_index_entry( std::make_shared(device_id), device_index_entry, device_ie_end_offset))) { } else if (RET_FAIL(load_measurement_index_entry( - measurement_name, device_index_entry.offset_, + measurement_name, device_index_entry->get_offset(), device_ie_end_offset, measurement_index_entry, measurement_ie_end_offset))) { } else if (RET_FAIL(do_load_timeseries_index( - measurement_name, measurement_index_entry.offset_, + measurement_name, measurement_index_entry->get_offset(), measurement_ie_end_offset, ssi->timeseries_index_pa_, ssi->itimeseries_index_))) { } else { @@ -249,7 +249,7 @@ int TsFileIOReader::load_timeseries_index_for_ssi( int TsFileIOReader::load_device_index_entry( std::shared_ptr device_name, - IMetaIndexEntry &device_index_entry, int64_t &end_offset) { + std::shared_ptr &device_index_entry, int64_t &end_offset) { int ret = E_OK; std::shared_ptr device_id_comparable = std::dynamic_pointer_cast(device_name); @@ -281,7 +281,7 @@ int TsFileIOReader::load_device_index_entry( int TsFileIOReader::load_measurement_index_entry( const std::string &measurement_name_str, int64_t start_offset, - int64_t end_offset, IMetaIndexEntry &ret_measurement_index_entry, + int64_t end_offset, std::shared_ptr &ret_measurement_index_entry, int64_t &ret_end_offset) { #if DEBUG_SE std::cout << "load_measurement_index_entry: measurement_name_str=" @@ -380,7 +380,8 @@ int TsFileIOReader::load_all_measurement_index_entry( int TsFileIOReader::read_device_meta_index(int32_t start_offset, int32_t end_offset, common::PageArena &pa, - MetaIndexNode *&device_meta_index) { + MetaIndexNode *&device_meta_index, + bool leaf) { int ret = E_OK; ASSERT(start_offset < end_offset); const int32_t read_size = (int32_t)(end_offset - start_offset); @@ -393,9 +394,8 @@ int TsFileIOReader::read_device_meta_index(int32_t start_offset, device_meta_index = new (m_idx_node_buf) MetaIndexNode(&pa); if (RET_FAIL(read_file_->read(start_offset, data_buf, read_size, ret_read_len))) { - } else if (RET_FAIL( - device_meta_index->deserialize_from(data_buf, read_size))) { } + ret = device_meta_index->device_deserialize_from(data_buf, read_size); return ret; } @@ -404,9 +404,9 @@ int TsFileIOReader::get_timeseries_indexes(std::shared_ptr device_id, std::vector ×eries_indexs, common::PageArena &pa) { int ret = E_OK; - DeviceMetaIndexEntry device_index_entry; + std::shared_ptr device_index_entry; int64_t device_ie_end_offset = 0; - MeasurementMetaIndexEntry measurement_index_entry; + std::shared_ptr measurement_index_entry; int64_t measurement_ie_end_offset = 0; if (RET_FAIL(load_device_index_entry( std::make_shared(device_id), device_index_entry, @@ -416,11 +416,11 @@ int TsFileIOReader::get_timeseries_indexes(std::shared_ptr device_id, int64_t idx = 0; for (const auto &measurement_name : measurement_names) { if (RET_FAIL(load_measurement_index_entry( - measurement_name, device_index_entry.offset_, + measurement_name, device_index_entry->get_offset(), device_ie_end_offset, measurement_index_entry, measurement_ie_end_offset))) { } else if (RET_FAIL(do_load_timeseries_index( - measurement_name, measurement_index_entry.offset_, + measurement_name, measurement_index_entry->get_offset(), measurement_ie_end_offset, pa, timeseries_indexs[idx++]))) { } @@ -435,7 +435,7 @@ int TsFileIOReader::get_timeseries_indexes(std::shared_ptr device_id, int TsFileIOReader::search_from_leaf_node( std::shared_ptr target_name, std::shared_ptr index_node, - IMetaIndexEntry &ret_index_entry, int64_t &ret_end_offset) { + std::shared_ptr &ret_index_entry, int64_t &ret_end_offset) { int ret = E_OK; ret = index_node->binary_search_children(target_name, true, ret_index_entry, ret_end_offset); @@ -444,15 +444,14 @@ int TsFileIOReader::search_from_leaf_node( int TsFileIOReader::search_from_internal_node( std::shared_ptr target_name, - std::shared_ptr index_node, IMetaIndexEntry &ret_index_entry, + std::shared_ptr index_node, std::shared_ptr &ret_index_entry, int64_t &ret_end_offset) { int ret = E_OK; - IMetaIndexEntry index_entry; + std::shared_ptr index_entry; int64_t end_offset = 0; ASSERT(index_node->node_type_ == INTERNAL_MEASUREMENT || index_node->node_type_ == INTERNAL_DEVICE); - if (RET_FAIL(index_node->binary_search_children( target_name, /*exact=*/false, index_entry, end_offset))) { return ret; @@ -460,7 +459,7 @@ int TsFileIOReader::search_from_internal_node( while (IS_SUCC(ret)) { // reader next level index node - const int read_size = end_offset - index_entry.get_offset(); + const int read_size = end_offset - index_entry->get_offset(); #if DEBUG_SE std::cout << "search_from_internal_node, end_offset=" << end_offset << ", index_entry.offset_=" << index_entry.get_offset() @@ -476,11 +475,11 @@ int TsFileIOReader::search_from_internal_node( MetaIndexNode *cur_level_index_node = new(buf) MetaIndexNode(&cur_level_index_node_pa); int32_t ret_read_len = 0; - if (RET_FAIL(read_file_->read(index_entry.get_offset(), data_buf, read_size, + if (RET_FAIL(read_file_->read(index_entry->get_offset(), data_buf, read_size, ret_read_len))) { } else if (read_size != ret_read_len) { ret = E_TSFILE_CORRUPTED; - } else if (RET_FAIL(cur_level_index_node->deserialize_from( + } else if (RET_FAIL(cur_level_index_node->device_deserialize_from( data_buf, read_size))) { } else { if (cur_level_index_node->node_type_ == LEAF_DEVICE) { diff --git a/cpp/src/file/tsfile_io_reader.h b/cpp/src/file/tsfile_io_reader.h index d32f690fa..bd4a293a7 100644 --- a/cpp/src/file/tsfile_io_reader.h +++ b/cpp/src/file/tsfile_io_reader.h @@ -77,7 +77,8 @@ class TsFileIOReader { std::vector &chunk_meta_list); int read_device_meta_index(int32_t start_offset, int32_t end_offset, common::PageArena &pa, - MetaIndexNode *&device_meta_index); + MetaIndexNode *&device_meta_index, + bool leaf); int get_timeseries_indexes( std::shared_ptr device_id, const std::unordered_set &measurement_names, @@ -92,12 +93,12 @@ class TsFileIOReader { int load_tsfile_meta_if_necessary(); int load_device_index_entry(std::shared_ptr target_name, - IMetaIndexEntry &device_index_entry, + std::shared_ptr &device_index_entry, int64_t &end_offset); int load_measurement_index_entry( const std::string &measurement_name, int64_t start_offset, - int64_t end_offset, IMetaIndexEntry &ret_measurement_index_entry, + int64_t end_offset, std::shared_ptr &ret_measurement_index_entry, int64_t &ret_end_offset); int load_all_measurement_index_entry( @@ -122,12 +123,12 @@ class TsFileIOReader { int search_from_leaf_node(std::shared_ptr target_name, std::shared_ptr index_node, - IMetaIndexEntry &ret_index_entry, + std::shared_ptr &ret_index_entry, int64_t &ret_end_offset); int search_from_internal_node(std::shared_ptr target_name, std::shared_ptr index_node, - IMetaIndexEntry &ret_index_entry, + std::shared_ptr &ret_index_entry, int64_t &ret_end_offset); bool filter_stasify(ITimeseriesIndex *ts_index, Filter *time_filter); diff --git a/cpp/src/reader/device_meta_iterator.cc b/cpp/src/reader/device_meta_iterator.cc index 90bcdc10d..d4512263d 100644 --- a/cpp/src/reader/device_meta_iterator.cc +++ b/cpp/src/reader/device_meta_iterator.cc @@ -78,7 +78,7 @@ int DeviceMetaIterator::load_leaf_device(MetaIndexNode* meta_index_node) { : meta_index_node->end_offset_; MetaIndexNode* child_node = nullptr; if (RET_FAIL(io_reader_->read_device_meta_index( - start_offset, end_offset, pa_, child_node))) { + start_offset, end_offset, pa_, child_node, false))) { return ret; } else { result_cache_.push( @@ -101,7 +101,7 @@ int DeviceMetaIterator::load_internal_node(MetaIndexNode* meta_index_node) { MetaIndexNode* child_node = nullptr; if (RET_FAIL(io_reader_->read_device_meta_index( - start_offset, end_offset, pa_, child_node))) { + start_offset, end_offset, pa_, child_node, false))) { return ret; } else { meta_index_nodes_.push(child_node); diff --git a/cpp/src/writer/time_chunk_writer.cc b/cpp/src/writer/time_chunk_writer.cc index 892c0d1c1..35684f596 100644 --- a/cpp/src/writer/time_chunk_writer.cc +++ b/cpp/src/writer/time_chunk_writer.cc @@ -100,6 +100,9 @@ int TimeChunkWriter::seal_cur_page(bool end_chunk) { time_page_writer_.destroy_page_data(); time_page_writer_.reset(); } else { + if (first_page_statistic_ == nullptr) { + std::cout<<"error"< ret_entry = std::make_shared< - MeasurementMetaIndexEntry>(); - ret_entry->init(ret_entry_name, 0, arena_); + std::shared_ptr ret_entry = std::make_shared< + MeasurementMetaIndexEntry>(ret_entry_name, 0, arena_); int64_t ret_offset = 0; int result = node_.binary_search_children( std::make_shared("banana"), - true, *ret_entry, ret_offset); + true, ret_entry, ret_offset); ASSERT_EQ(result, 0); ASSERT_EQ(ret_offset, 30); } TEST_F(MetaIndexNodeSearchTest, ExactSearchNotFound) { const std::string ret_entry_name(""); - std::shared_ptr ret_entry = std::make_shared< - MeasurementMetaIndexEntry>(); - ret_entry->init(ret_entry_name, 0, arena_); + std::shared_ptr ret_entry = std::make_shared< + MeasurementMetaIndexEntry>(ret_entry_name, 0, arena_); int64_t ret_offset = 0; char search_name[] = "grape"; int result = node_.binary_search_children( std::make_shared(search_name), - true, *ret_entry, ret_offset); + true, ret_entry, ret_offset); ASSERT_EQ(result, common::E_NOT_EXIST); } TEST_F(MetaIndexNodeSearchTest, NonExactSearchFound) { const std::string ret_entry_name(""); - std::shared_ptr ret_entry = std::make_shared< - MeasurementMetaIndexEntry>(); - ret_entry->init(ret_entry_name, 0, arena_); + std::shared_ptr ret_entry = std::make_shared< + MeasurementMetaIndexEntry>(ret_entry_name, 0, arena_); int64_t ret_offset = 0; char search_name[] = "blueberry"; int result = node_.binary_search_children( std::make_shared(search_name), - false, *ret_entry, ret_offset); + false, ret_entry, ret_offset); ASSERT_EQ(result, 0); ASSERT_EQ(ret_offset, 30); } TEST_F(MetaIndexNodeSearchTest, NonExactSearchNotFound) { const std::string ret_entry_name(""); - std::shared_ptr ret_entry = std::make_shared< - MeasurementMetaIndexEntry>(); - ret_entry->init(ret_entry_name, 0, arena_); + std::shared_ptr ret_entry = std::make_shared< + MeasurementMetaIndexEntry>(ret_entry_name, 0, arena_); int64_t ret_offset = 0; char search_name[] = "aardvark"; int result = node_.binary_search_children( std::make_shared(search_name), - false, *ret_entry, ret_offset); + false, ret_entry, ret_offset); ASSERT_EQ(result, common::E_NOT_EXIST); } diff --git a/java/bench_mark/pom.xml b/java/bench_mark/pom.xml new file mode 100644 index 000000000..c193d4d78 --- /dev/null +++ b/java/bench_mark/pom.xml @@ -0,0 +1,80 @@ + + + + 4.0.0 + + org.apache.tsfile + tsfile-java + 2.1.0-SNAPSHOT + + bench_mark + TsFile: Java: BenchMark + + + ch.qos.logback + logback-classic + + + org.apache.tsfile + tsfile + 2.1.0-SNAPSHOT + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + 8 + 8 + + + + org.apache.maven.plugins + maven-dependency-plugin + + + check-dependencies + + analyze-only + + verify + + true + + + + + + org.apache.maven.plugins + maven-enforcer-plugin + + + true + + + + + + diff --git a/java/bench_mark/src/main/java/org/apache/tsfile/BenchMark.java b/java/bench_mark/src/main/java/org/apache/tsfile/BenchMark.java new file mode 100644 index 000000000..5f8047f6e --- /dev/null +++ b/java/bench_mark/src/main/java/org/apache/tsfile/BenchMark.java @@ -0,0 +1,203 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.tsfile; + +import org.apache.tsfile.enums.TSDataType; +import org.apache.tsfile.exception.read.ReadProcessException; +import org.apache.tsfile.exception.write.NoMeasurementException; +import org.apache.tsfile.exception.write.NoTableException; +import org.apache.tsfile.exception.write.WriteProcessException; +import org.apache.tsfile.file.metadata.ColumnSchema; +import org.apache.tsfile.file.metadata.ColumnSchemaBuilder; +import org.apache.tsfile.file.metadata.TableSchema; +import org.apache.tsfile.fileSystem.FSFactoryProducer; +import org.apache.tsfile.read.query.dataset.ResultSet; +import org.apache.tsfile.read.v4.ITsFileReader; +import org.apache.tsfile.read.v4.TsFileReaderBuilder; +import org.apache.tsfile.write.record.Tablet; +import org.apache.tsfile.write.v4.ITsFileWriter; +import org.apache.tsfile.write.v4.TsFileWriterBuilder; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.util.ArrayList; +import java.util.List; + +public class BenchMark { + private static final Logger LOGGER = LoggerFactory.getLogger(BenchMark.class); + + public static void main(String[] args) + throws IOException, ReadProcessException, NoTableException, NoMeasurementException { + BenchMarkConf.printConfig(); + MemoryMonitor monitor = new MemoryMonitor(); + String path = "/tmp/tsfile_table_write_bench_mark.tsfile"; + File f = FSFactoryProducer.getFSFactory().getFile(path); + if (f.exists()) { + Files.delete(f.toPath()); + } + monitor.recordMemoryUsage(); + List column_names = new ArrayList<>(); + List column_types = new ArrayList<>(); + List columnSchemas = new ArrayList<>(); + columnSchemas.add( + new ColumnSchemaBuilder() + .name("TAG1") + .dataType(TSDataType.STRING) + .category(Tablet.ColumnCategory.TAG) + .build()); + + columnSchemas.add( + new ColumnSchemaBuilder() + .name("TAG2") + .dataType(TSDataType.STRING) + .category(Tablet.ColumnCategory.TAG) + .build()); + column_names.add("TAG1"); + column_names.add("TAG2"); + column_types.add(TSDataType.STRING); + column_types.add(TSDataType.STRING); + + int fieldIndex = 2; + for (int i = 0; i < BenchMarkConf.FIELD_TYPE_VECTOR.size(); i++) { + int count = BenchMarkConf.FIELD_TYPE_VECTOR.get(i); + TSDataType dataType = BenchMarkConf.getTsDataType(i); + for (int j = 0; j < count; j++) { + columnSchemas.add( + new ColumnSchemaBuilder() + .name("FIELD" + fieldIndex) + .dataType(dataType) + .category(Tablet.ColumnCategory.FIELD) + .build()); + column_names.add("FIELD" + fieldIndex); + column_types.add(dataType); + fieldIndex++; + } + } + monitor.recordMemoryUsage(); + long totalPrepareTimeNs = 0; + long totalWriteTimeNs = 0; + long start = System.nanoTime(); + TableSchema tableSchema = new TableSchema("TestTable", columnSchemas); + monitor.recordMemoryUsage(); + try (ITsFileWriter writer = + new TsFileWriterBuilder().file(f).tableSchema(tableSchema).build()) { + monitor.recordMemoryUsage(); + long timestamp = 0; + for (int table_ind = 0; table_ind < BenchMarkConf.TABLET_NUM; table_ind++) { + long prepareStartTime = System.nanoTime(); + Tablet tablet = + new Tablet( + column_names, + column_types, + BenchMarkConf.TAG1_NUM * BenchMarkConf.TAG2_NUM * BenchMarkConf.TIMESTAMP_PER_TAG); + int row_count = 0; + for (int tag1_ind = 0; tag1_ind < BenchMarkConf.TAG1_NUM; tag1_ind++) { + for (int tag2_ind = 0; tag2_ind < BenchMarkConf.TAG2_NUM; tag2_ind++) { + for (int row = 0; row < BenchMarkConf.TIMESTAMP_PER_TAG; row++) { + tablet.addTimestamp(row_count, timestamp + row); + tablet.addValue(row_count, 0, "tag1_" + tag1_ind); + tablet.addValue(row_count, 1, "tag2_" + tag2_ind); + + for (int i = 2; i < column_types.size(); i++) { + switch (column_types.get(i)) { + case INT32: + tablet.addValue(row_count, i, (int) timestamp); + break; + case INT64: + tablet.addValue(row_count, i, timestamp); + break; + case FLOAT: + tablet.addValue(row_count, i, (float) (timestamp * 1.1)); + break; + case DOUBLE: + tablet.addValue(row_count, i, (double) timestamp * 1.1); + break; + case BOOLEAN: + tablet.addValue(row_count, i, timestamp % 2 == 0); + default: + // + } + } + row_count++; + } + } + } + monitor.recordMemoryUsage(); + long prepareEndTime = System.nanoTime(); + + totalPrepareTimeNs += (prepareEndTime - prepareStartTime); + long writeStartTime = System.nanoTime(); + writer.write(tablet); + monitor.recordMemoryUsage(); + long writeEndTime = System.nanoTime(); + totalWriteTimeNs += (writeEndTime - writeStartTime); + timestamp += BenchMarkConf.TIMESTAMP_PER_TAG; + } + } catch (WriteProcessException e) { + LOGGER.error("meet error in TsFileWrite ", e); + } + monitor.recordMemoryUsage(); + long end = System.nanoTime(); + double totalPrepareTimeSec = totalPrepareTimeNs / 1_000_000_000.0; + double totalWriteTimeSec = totalWriteTimeNs / 1_000_000_000.0; + double totalTimeSec = (end - start) / 1_000_000_000.0; + + long size = f.length(); + + monitor.close(); + System.out.println("===================="); + System.out.println("finish bench mark for java"); + System.out.printf("tsfile size is %d bytes ~ %dKB%n", size, size / 1024); + + System.out.printf("prepare data time is %.6f s%n", totalPrepareTimeSec); + System.out.printf("writing data time is %.6f s%n", totalWriteTimeSec); + + long totalPoints = + (long) BenchMarkConf.TABLET_NUM + * BenchMarkConf.TAG1_NUM + * BenchMarkConf.TAG2_NUM + * BenchMarkConf.TIMESTAMP_PER_TAG + * column_names.size(); + double writingSpeed = totalPoints / totalTimeSec; + System.out.printf("writing speed is %d points/s%n", (long) writingSpeed); + + System.out.printf("total time is %.6f s%n", totalTimeSec); + System.out.println("===================="); + + Integer row = 0; + long read_start = System.nanoTime(); + try (ITsFileReader reader = new TsFileReaderBuilder().file(f).build()) { + ResultSet resultSet = reader.query("TestTable", column_names, Long.MIN_VALUE, Long.MAX_VALUE); + while (resultSet.next()) { + row++; + } + } + System.out.println("row is " + row); + long read_end = System.nanoTime(); + double totalReadTimeSec = (read_end - read_start) / 1_000_000_000.0; + System.out.printf("read time is %.6f s%n", totalReadTimeSec); + double readSpeed = row * column_names.size() / totalReadTimeSec; + System.out.printf("read speed is %.6f points/s %n", readSpeed); + } +} diff --git a/java/bench_mark/src/main/java/org/apache/tsfile/BenchMarkConf.java b/java/bench_mark/src/main/java/org/apache/tsfile/BenchMarkConf.java new file mode 100644 index 000000000..9ba26555a --- /dev/null +++ b/java/bench_mark/src/main/java/org/apache/tsfile/BenchMarkConf.java @@ -0,0 +1,82 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.tsfile; + +import org.apache.tsfile.enums.TSDataType; + +import java.util.Arrays; +import java.util.List; + +public class BenchMarkConf { + public static final int TABLET_NUM = 1000; + public static final int TAG1_NUM = 1; + public static final int TAG2_NUM = 10; + public static final int TIMESTAMP_PER_TAG = 1000; + public static final List FIELD_TYPE_VECTOR = Arrays.asList(1, 1, 1, 1, 1); + + public static TSDataType getTsDataType(int index) { + switch (index) { + case 0: + return TSDataType.INT32; + case 1: + return TSDataType.INT64; + case 2: + return TSDataType.FLOAT; + case 3: + return TSDataType.DOUBLE; + case 4: + return TSDataType.BOOLEAN; + } + return TSDataType.UNKNOWN; + } + + public static final List DATA_TYPES_NAME = + Arrays.asList("INT32", "INT64", "FLOAT", "DOUBLE", "BOOLEAN"); + + public static void printConfig() { + int columnNum = 0; + for (int count : FIELD_TYPE_VECTOR) { + columnNum += count; + } + + System.out.println("TsFile benchmark For Java"); + System.out.println("Schema Configuration:"); + System.out.println("Tag Column num: " + 2); + System.out.printf( + "TAG1 num: %d TAG2 num: %d%n%n", BenchMarkConf.TAG1_NUM, BenchMarkConf.TAG2_NUM); + + System.out.println("Field Column and types: "); + for (int i = 0; i < 5; i++) { + System.out.printf("%sx%d ", DATA_TYPES_NAME.get(i), BenchMarkConf.FIELD_TYPE_VECTOR.get(i)); + } + + System.out.printf("%nTablet num: %d%n", BenchMarkConf.TABLET_NUM); + System.out.printf("Tablet row num per tag: %d%n", BenchMarkConf.TIMESTAMP_PER_TAG); + + long totalPoints = + (long) BenchMarkConf.TABLET_NUM + * BenchMarkConf.TAG1_NUM + * BenchMarkConf.TAG2_NUM + * BenchMarkConf.TIMESTAMP_PER_TAG + * columnNum; + System.out.println("Total points is " + totalPoints); + System.out.println("======"); + } +} diff --git a/java/bench_mark/src/main/java/org/apache/tsfile/MemoryMonitor.java b/java/bench_mark/src/main/java/org/apache/tsfile/MemoryMonitor.java new file mode 100644 index 000000000..8829c1a5f --- /dev/null +++ b/java/bench_mark/src/main/java/org/apache/tsfile/MemoryMonitor.java @@ -0,0 +1,71 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.tsfile; + +import oshi.SystemInfo; +import oshi.hardware.GlobalMemory; +import oshi.software.os.OSProcess; +import oshi.software.os.OperatingSystem; + +import java.io.BufferedWriter; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.nio.file.StandardOpenOption; + +public class MemoryMonitor { + private static final String CSV_HEADER = "iter,memory_usage(kb)\n"; + private static final String CSV_FILE = "/tmp/memory_usage_java.csv"; + private BufferedWriter writer; + private int iter = 0; + + public MemoryMonitor() throws IOException { + writer = + Files.newBufferedWriter( + Paths.get(CSV_FILE), StandardOpenOption.CREATE, StandardOpenOption.APPEND); + writer.write(CSV_HEADER); + } + + public void recordMemoryUsage() throws IOException { + long memory = get_memory_usage(); + String line = String.format("%d,%d\n", iter++, memory); + writer.write(line); + writer.flush(); + } + + public long get_memory_usage() { + SystemInfo si = new SystemInfo(); + OperatingSystem os = si.getOperatingSystem(); + GlobalMemory memory = si.getHardware().getMemory(); + OSProcess currentProcess = os.getProcess(os.getProcessId()); + long residentSetSize = currentProcess.getResidentSetSize(); + return residentSetSize / 1024; + } + + public void close() { + try { + if (writer != null) { + writer.close(); + } + } catch (IOException e) { + e.printStackTrace(); + } + } +} diff --git a/java/pom.xml b/java/pom.xml index 8c6be19be..87435a663 100644 --- a/java/pom.xml +++ b/java/pom.xml @@ -35,6 +35,7 @@ tsfile examples tools + bench_mark diff --git a/python/bench_mark/bench_mark.py b/python/bench_mark/bench_mark.py new file mode 100644 index 000000000..1fc02e951 --- /dev/null +++ b/python/bench_mark/bench_mark.py @@ -0,0 +1,185 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# +import os +from time import perf_counter + +from tqdm import tqdm +import psutil +import csv +from tsfile import TSDataType, ColumnCategory +from tsfile import TableSchema, ColumnSchema +from tsfile import Tablet +from tsfile import TsFileTableWriter, TsFileReader + + +bench_mark_conf = { + "tablet_num": 1000, + "tag1_num": 1, + "tag2_num": 10, + "timestamp_per_tag": 1000, + "field_type_vector": [1, 1, 1, 1, 1], +} + +type_list = [TSDataType.INT32, TSDataType.INT64, TSDataType.FLOAT, TSDataType.DOUBLE, TSDataType.BOOLEAN] + + +def print_config(): + data_types_name = ["INT64", "INT32", "FLOAT", "DOUBLE", "BOOLEAN"] + print("=====================") + print("TsFile benchmark For Python") + print("Schema Configuration:") + print(f"Tag Column num: {2}") + print(f"TAG1 num: {bench_mark_conf['tag1_num']} TAG2 num: {bench_mark_conf['tag2_num']}\n") + + print("Filed Column and types: ") + column_num = 0 + for i in range(5): + print(f"{data_types_name[i]}x{bench_mark_conf['field_type_vector'][i]} ", end="") + column_num += bench_mark_conf['field_type_vector'][i] + + print("\n") + print(f"Tablet num: {bench_mark_conf['tablet_num']}") + print(f"Tablet row num per tag: {bench_mark_conf['timestamp_per_tag']}") + + total_points = (bench_mark_conf['tablet_num'] * + bench_mark_conf['tag1_num'] * + bench_mark_conf['tag2_num'] * + bench_mark_conf['timestamp_per_tag'] * + column_num) + print(f"Total points is {total_points}") + print("======") + +column_name = [] + +def get_memory_usage_kb(): + process = psutil.Process(os.getpid()) + return process.memory_info().rss // 1024 + +def bench_mark_write(): + csv_file = "memory_usage_python.csv" + + csv_writer = csv.writer(open(csv_file, "w")) + csv_writer.writerow(["iter_num", "memory_usage(kb)"]) + iter_num = 0 + print_config() + column_schema_list = [] + column_datat_type = [] + column_schema_list.append(ColumnSchema("TAG1", TSDataType.STRING, ColumnCategory.TAG)) + column_name.append("TAG1") + column_datat_type.append(TSDataType.STRING) + column_schema_list.append(ColumnSchema("TAG2", TSDataType.STRING, ColumnCategory.TAG)) + column_name.append("TAG2") + column_datat_type.append(TSDataType.STRING) + + + i = 2 + for count, type in zip(bench_mark_conf["field_type_vector"], type_list): + for _ in range(count): + column_schema_list.append(ColumnSchema("FIELD" + str(i), type, ColumnCategory.FIELD)) + column_name.append("FIELD" + str(i)) + column_datat_type.append(type) + i = i + 1 + + timestamp = 0 + table_schema = TableSchema("TestTable", column_schema_list) + start = perf_counter() + prepare_time = 0 + writing_time = 0 + csv_writer.writerow([iter_num, get_memory_usage_kb()]) + iter_num += 1 + with TsFileTableWriter("tsfile_table_write_bench_mark.tsfile", table_schema) as writer: + csv_writer.writerow([iter_num, get_memory_usage_kb()]) + iter_num += 1 + for i in tqdm(range(bench_mark_conf["tablet_num"]), desc="Tablets"): + csv_writer.writerow([iter_num, get_memory_usage_kb()]) + iter_num += 1 + row_num = 0 + prepare_start = perf_counter() + tablet = Tablet(column_name, column_datat_type, + bench_mark_conf["timestamp_per_tag"] * bench_mark_conf["tag1_num"] * + bench_mark_conf["tag2_num"]) + + for j in range(bench_mark_conf["tag1_num"]): + for k in range(bench_mark_conf["tag2_num"]): + for row in range(bench_mark_conf["timestamp_per_tag"]): + tablet.add_timestamp(row_num, timestamp + row) + tablet.add_value_by_index(0, row_num, "tag1_" + str(j)) + tablet.add_value_by_index(1, row_num, "tag2_" + str(k)) + for col in range(2, len(column_name)): + if column_datat_type[col] == TSDataType.INT32: + tablet.add_value_by_index(col, row_num, timestamp) + elif column_datat_type[col] == TSDataType.INT64: + tablet.add_value_by_index(col, row_num, timestamp) + elif column_datat_type[col] == TSDataType.FLOAT: + tablet.add_value_by_index(col, row_num, timestamp * 1.1) + elif column_datat_type[col] == TSDataType.DOUBLE: + tablet.add_value_by_index(col, row_num, timestamp * 1.1) + elif column_datat_type[col] == TSDataType.BOOLEAN: + tablet.add_value_by_index(col, row_num, timestamp % 2 == 0) + row_num = row_num + 1 + + prepare_time += perf_counter() - prepare_start + write_start = perf_counter() + csv_writer.writerow([iter_num, get_memory_usage_kb()]) + iter_num += 1 + writer.write_table(tablet) + writing_time += perf_counter() - write_start + timestamp = timestamp + bench_mark_conf["timestamp_per_tag"] + csv_writer.writerow([iter_num, get_memory_usage_kb()]) + iter_num += 1 + + csv_writer.writerow([iter_num, get_memory_usage_kb()]) + iter_num += 1 + end = perf_counter() + total_time = end - start + size = os.path.getsize("tsfile_table_write_bench_mark.tsfile") + + total_points = bench_mark_conf["tablet_num"] * bench_mark_conf["tag1_num"] * bench_mark_conf["tag2_num"] * \ + bench_mark_conf["timestamp_per_tag"] * len(column_name) + + print("finish bench mark for python") + print(f"tsfile size is {size} bytes ~ {size // 1024}KB") + + print(f"prepare data time is {prepare_time:.6f} s") + print(f"writing data time is {writing_time:.6f} s") + print(f" total_time is {total_time} s") + writing_speed = int(total_points / (prepare_time + writing_time)) + print(f"writing speed is {writing_speed} points/s") + + total_time_seconds = (end - start) + print(f"total time is {total_time_seconds:.6f} s") + +def bench_mark_read(): + start = perf_counter() + row = 0 + with TsFileReader("tsfile_table_write_bench_mark.tsfile") as reader: + result = reader.query_table("TestTable", column_name) + first = True + while result.next(): + row = row + 1 + + end = perf_counter() + total_time = end - start + reading_speed = int(row * len(column_name) / total_time) + print("total row is ", row) + print(f"reading data time is {total_time} s") + print(f"reading data speed is {reading_speed} points/s") + + +bench_mark_write() +bench_mark_read() diff --git a/python/bench_mark/memory_usage_python.csv b/python/bench_mark/memory_usage_python.csv new file mode 100644 index 000000000..e5c10a0a7 --- /dev/null +++ b/python/bench_mark/memory_usage_python.csv @@ -0,0 +1,3004 @@ +iter_num,memory_usage(kb) +0,71952 +1,72064 +2,72752 +3,74832 +4,76944 +5,76944 +6,77520 +7,77936 +8,77936 +9,78928 +10,79328 +11,79328 +12,79392 +13,80016 +14,80016 +15,80048 +16,80512 +17,80512 +18,80528 +19,80864 +20,80864 +21,80864 +22,81200 +23,81200 +24,81296 +25,81648 +26,81648 +27,81648 +28,82064 +29,82064 +30,82080 +31,84160 +32,84160 +33,84240 +34,84240 +35,84240 +36,84320 +37,84368 +38,84368 +39,84464 +40,84880 +41,84880 +42,84992 +43,85232 +44,85232 +45,85264 +46,85616 +47,85632 +48,85632 +49,85968 +50,85968 +51,85968 +52,86320 +53,86320 +54,86320 +55,86320 +56,86320 +57,86320 +58,86688 +59,86688 +60,86688 +61,93200 +62,93200 +63,93280 +64,93664 +65,93664 +66,93664 +67,94032 +68,94032 +69,94032 +70,94384 +71,94384 +72,94384 +73,94384 +74,94384 +75,94416 +76,94416 +77,94416 +78,94416 +79,94416 +80,94416 +81,94416 +82,94416 +83,94416 +84,94416 +85,94416 +86,94416 +87,94448 +88,94448 +89,94448 +90,94464 +91,97072 +92,97072 +93,97136 +94,97136 +95,97136 +96,97136 +97,97136 +98,97136 +99,97136 +100,97136 +101,97136 +102,97136 +103,97136 +104,97136 +105,97136 +106,97136 +107,97136 +108,97168 +109,97472 +110,97472 +111,97472 +112,97472 +113,97472 +114,97472 +115,98288 +116,98288 +117,98368 +118,97920 +119,97920 +120,96720 +121,97984 +122,97984 +123,88496 +124,88016 +125,88016 +126,78208 +127,77568 +128,77568 +129,77664 +130,77936 +131,77936 +132,77936 +133,77968 +134,77968 +135,77968 +136,78016 +137,78016 +138,78016 +139,78272 +140,78272 +141,78352 +142,78672 +143,78672 +144,78704 +145,79072 +146,79072 +147,79104 +148,79440 +149,79440 +150,79472 +151,81904 +152,81904 +153,81968 +154,81968 +155,81968 +156,81968 +157,82016 +158,82016 +159,82048 +160,82048 +161,82048 +162,82128 +163,82288 +164,82288 +165,82288 +166,82352 +167,82352 +168,82368 +169,82720 +170,82720 +171,82720 +172,83088 +173,83088 +174,83088 +175,83456 +176,83456 +177,83456 +178,83456 +179,83456 +180,83456 +181,85632 +182,85632 +183,85664 +184,86032 +185,86032 +186,86032 +187,86384 +188,86384 +189,86400 +190,86784 +191,86784 +192,86784 +193,86784 +194,86784 +195,86800 +196,87136 +197,87136 +198,87184 +199,87184 +200,87184 +201,87184 +202,87184 +203,87184 +204,87216 +205,87952 +206,87952 +207,87984 +208,88336 +209,88336 +210,88336 +211,91200 +212,91200 +213,91232 +214,91232 +215,91232 +216,91248 +217,91248 +218,91248 +219,91248 +220,91584 +221,91584 +222,91616 +223,91936 +224,91936 +225,91936 +226,92288 +227,92288 +228,92288 +229,92288 +230,92288 +231,92288 +232,92288 +233,92288 +234,92288 +235,92288 +236,92288 +237,92288 +238,92288 +239,92288 +240,92288 +241,93792 +242,93792 +243,93824 +244,94160 +245,94160 +246,94160 +247,94528 +248,94528 +249,94544 +250,94896 +251,94896 +252,94896 +253,95264 +254,95264 +255,95280 +256,95632 +257,95632 +258,95648 +259,96000 +260,96000 +261,96000 +262,96352 +263,96352 +264,96352 +265,96352 +266,96352 +267,96384 +268,96752 +269,96752 +270,96752 +271,97616 +272,97616 +273,97648 +274,97648 +275,97648 +276,97680 +277,98016 +278,98016 +279,98176 +280,98560 +281,98560 +282,98560 +283,98560 +284,98560 +285,98576 +286,98576 +287,98576 +288,98576 +289,98576 +290,98576 +291,98576 +292,98576 +293,98576 +294,98576 +295,98880 +296,98880 +297,98880 +298,99296 +299,99296 +300,99296 +301,101440 +302,101440 +303,101472 +304,101840 +305,101840 +306,101840 +307,102192 +308,102192 +309,102224 +310,102592 +311,102592 +312,102592 +313,102944 +314,102944 +315,102944 +316,103312 +317,103312 +318,103312 +319,103312 +320,103312 +321,103328 +322,103584 +323,103584 +324,103584 +325,103584 +326,103584 +327,103584 +328,103584 +329,103584 +330,103584 +331,105776 +332,105776 +333,105776 +334,105776 +335,105776 +336,105792 +337,105792 +338,105792 +339,105824 +340,105824 +341,105824 +342,105824 +343,105824 +344,105824 +345,105824 +346,105824 +347,105824 +348,105824 +349,105824 +350,105824 +351,105904 +352,106256 +353,106256 +354,106256 +355,106256 +356,106256 +357,106288 +358,106640 +359,106640 +360,106640 +361,107824 +362,107824 +363,107856 +364,108144 +365,108144 +366,108144 +367,108496 +368,108496 +369,108496 +370,108848 +371,108848 +372,108848 +373,109200 +374,109200 +375,109200 +376,109584 +377,109584 +378,109584 +379,109584 +380,109584 +381,109584 +382,109936 +383,109936 +384,109936 +385,110304 +386,110304 +387,110304 +388,110656 +389,110656 +390,110656 +391,113616 +392,113616 +393,113648 +394,113648 +395,113648 +396,113648 +397,113648 +398,113648 +399,113648 +400,113648 +401,113648 +402,113648 +403,113648 +404,113648 +405,113600 +406,113632 +407,113632 +408,113632 +409,113648 +410,113648 +411,113680 +412,113680 +413,113680 +414,113680 +415,113680 +416,113680 +417,113680 +418,113680 +419,113680 +420,113680 +421,115872 +422,115872 +423,115904 +424,115904 +425,115904 +426,115904 +427,116272 +428,116272 +429,116272 +430,116272 +431,116272 +432,116272 +433,116272 +434,116272 +435,116272 +436,116512 +437,116512 +438,116512 +439,116864 +440,116864 +441,116864 +442,117232 +443,117232 +444,117248 +445,117632 +446,117632 +447,117632 +448,117968 +449,117968 +450,117968 +451,120896 +452,120896 +453,120928 +454,120928 +455,120928 +456,120960 +457,120960 +458,120960 +459,120960 +460,121312 +461,121312 +462,121312 +463,121664 +464,121664 +465,121664 +466,121968 +467,121968 +468,122000 +469,122352 +470,122352 +471,122352 +472,122704 +473,122704 +474,122704 +475,123088 +476,123088 +477,123088 +478,123440 +479,123440 +480,123440 +481,125200 +482,125200 +483,125232 +484,125248 +485,125248 +486,125280 +487,125280 +488,125280 +489,125296 +490,125296 +491,125296 +492,125328 +493,125328 +494,125328 +495,125328 +496,125328 +497,125328 +498,125328 +499,125328 +500,125328 +501,125360 +502,125712 +503,125712 +504,125712 +505,126064 +506,126064 +507,126064 +508,126432 +509,126432 +510,126432 +511,129008 +512,129008 +513,129024 +514,129024 +515,129024 +516,125680 +517,126048 +518,126048 +519,123344 +520,122544 +521,122544 +522,114224 +523,114624 +524,114624 +525,106960 +526,106960 +527,106960 +528,106960 +529,107312 +530,107312 +531,107312 +532,107664 +533,107664 +534,106400 +535,106400 +536,106400 +537,106432 +538,106432 +539,106432 +540,106432 +541,108416 +542,108416 +543,108464 +544,108832 +545,108832 +546,108848 +547,109216 +548,109216 +549,109216 +550,109216 +551,109216 +552,109216 +553,105808 +554,105808 +555,105840 +556,105872 +557,105872 +558,105888 +559,105888 +560,105888 +561,105920 +562,105920 +563,105920 +564,105920 +565,106256 +566,106256 +567,103376 +568,103728 +569,103728 +570,103728 +571,106608 +572,106608 +573,106624 +574,106976 +575,106976 +576,106976 +577,107344 +578,107344 +579,107344 +580,107696 +581,107696 +582,107696 +583,107696 +584,107696 +585,107728 +586,107728 +587,107728 +588,107728 +589,107728 +590,107728 +591,107744 +592,108112 +593,108112 +594,108112 +595,108480 +596,108480 +597,108480 +598,108848 +599,108848 +600,108848 +601,110416 +602,110416 +603,110448 +604,110736 +605,110736 +606,110736 +607,110736 +608,110736 +609,110736 +610,110736 +611,110736 +612,110736 +613,111088 +614,111088 +615,111120 +616,111472 +617,111472 +618,111472 +619,111824 +620,111824 +621,111824 +622,112224 +623,112224 +624,112224 +625,112224 +626,112224 +627,112224 +628,112576 +629,112576 +630,112576 +631,114080 +632,114080 +633,114304 +634,114304 +635,114304 +636,114304 +637,114720 +638,114720 +639,114880 +640,114912 +641,114912 +642,114912 +643,115232 +644,115232 +645,115232 +646,115600 +647,115600 +648,115648 +649,115648 +650,115648 +651,115648 +652,115648 +653,115648 +654,115648 +655,115648 +656,115648 +657,115648 +658,115648 +659,115648 +660,115648 +661,118576 +662,118576 +663,118608 +664,118608 +665,118608 +666,118608 +667,118608 +668,118608 +669,118608 +670,118624 +671,118624 +672,118624 +673,118960 +674,118960 +675,118992 +676,119344 +677,119344 +678,119344 +679,119696 +680,119696 +681,119696 +682,120064 +683,120064 +684,120096 +685,120464 +686,120464 +687,120464 +688,120816 +689,120816 +690,120816 +691,121376 +692,121376 +693,121408 +694,121664 +695,121664 +696,121664 +697,122016 +698,122016 +699,122016 +700,122384 +701,122384 +702,122384 +703,122704 +704,122704 +705,122736 +706,123104 +707,123104 +708,123104 +709,123440 +710,123440 +711,123440 +712,123440 +713,123440 +714,123440 +715,123472 +716,123472 +717,123472 +718,123840 +719,123840 +720,123840 +721,126384 +722,126384 +723,126416 +724,126752 +725,126752 +726,126752 +727,127104 +728,127104 +729,127104 +730,127472 +731,127472 +732,127472 +733,127472 +734,127472 +735,127472 +736,127472 +737,127472 +738,127488 +739,127488 +740,127488 +741,127488 +742,127488 +743,127488 +744,127488 +745,127488 +746,127488 +747,127488 +748,127488 +749,127488 +750,127488 +751,128944 +752,128944 +753,128976 +754,128976 +755,128976 +756,129008 +757,129008 +758,129008 +759,129008 +760,129008 +761,129008 +762,129008 +763,129328 +764,129328 +765,129328 +766,129696 +767,129696 +768,129696 +769,130032 +770,130032 +771,130032 +772,130368 +773,130368 +774,130368 +775,130736 +776,130736 +777,130736 +778,131088 +779,131088 +780,131088 +781,133664 +782,133664 +783,133696 +784,134032 +785,134032 +786,134032 +787,134032 +788,134032 +789,134032 +790,134400 +791,134400 +792,134400 +793,134752 +794,134752 +795,134752 +796,135120 +797,135120 +798,135120 +799,135456 +800,135456 +801,135456 +802,135824 +803,135824 +804,135824 +805,136176 +806,136176 +807,136176 +808,136176 +809,136176 +810,136176 +811,137376 +812,137376 +813,137408 +814,137408 +815,137408 +816,137408 +817,137408 +818,137408 +819,137408 +820,137408 +821,137408 +822,137408 +823,137408 +824,137408 +825,137408 +826,137408 +827,137408 +828,137408 +829,137408 +830,137408 +831,137408 +832,137712 +833,137712 +834,137712 +835,138064 +836,138064 +837,138064 +838,138432 +839,138432 +840,138464 +841,140624 +842,140624 +843,140656 +844,141024 +845,141024 +846,141024 +847,141376 +848,141376 +849,141376 +850,141744 +851,141744 +852,141744 +853,142096 +854,142096 +855,142096 +856,142464 +857,142464 +858,142464 +859,142720 +860,142720 +861,142720 +862,143072 +863,143072 +864,143072 +865,143072 +866,143072 +867,143104 +868,143104 +869,143104 +870,143104 +871,143440 +872,143440 +873,143472 +874,143840 +875,143840 +876,143840 +877,144192 +878,144192 +879,144192 +880,144192 +881,144192 +882,144224 +883,144224 +884,144224 +885,144240 +886,144576 +887,144576 +888,144576 +889,144912 +890,144912 +891,144912 +892,144928 +893,144928 +894,144928 +895,145280 +896,145280 +897,145280 +898,145632 +899,145632 +900,145632 +901,147232 +902,147232 +903,147264 +904,147264 +905,147264 +906,147264 +907,147264 +908,147264 +909,147296 +910,147296 +911,147296 +912,147296 +913,147616 +914,147616 +915,147616 +916,147616 +917,147616 +918,147616 +919,147616 +920,147616 +921,147616 +922,147616 +923,147616 +924,147616 +925,147616 +926,147616 +927,147616 +928,147616 +929,147616 +930,147616 +931,149376 +932,149376 +933,149408 +934,149408 +935,149408 +936,149440 +937,149808 +938,149808 +939,149808 +940,150096 +941,150096 +942,150096 +943,150448 +944,150448 +945,150448 +946,150816 +947,150816 +948,150816 +949,150816 +950,150816 +951,150848 +952,151200 +953,151200 +954,151200 +955,151568 +956,151568 +957,151568 +958,151920 +959,151920 +960,151920 +961,154176 +962,154176 +963,154192 +964,154208 +965,154208 +966,154240 +967,154240 +968,154240 +969,154240 +970,154240 +971,154240 +972,154240 +973,154240 +974,154240 +975,154240 +976,154576 +977,154576 +978,154576 +979,154912 +980,154912 +981,154912 +982,155280 +983,155280 +984,155280 +985,155280 +986,155280 +987,155280 +988,155280 +989,155280 +990,155280 +991,157808 +992,157808 +993,157840 +994,158176 +995,158176 +996,158176 +997,158544 +998,158544 +999,158544 +1000,158544 +1001,158544 +1002,158544 +1003,158864 +1004,158864 +1005,158864 +1006,159216 +1007,159216 +1008,159216 +1009,159568 +1010,159568 +1011,159568 +1012,159920 +1013,159920 +1014,159920 +1015,160288 +1016,160288 +1017,160288 +1018,160640 +1019,160640 +1020,160640 +1021,162128 +1022,162128 +1023,162144 +1024,162144 +1025,162144 +1026,162144 +1027,162144 +1028,162144 +1029,162144 +1030,162496 +1031,162496 +1032,162496 +1033,162848 +1034,162848 +1035,162848 +1036,163216 +1037,163216 +1038,163216 +1039,163216 +1040,163216 +1041,163216 +1042,163216 +1043,163216 +1044,163248 +1045,163248 +1046,163248 +1047,163248 +1048,163248 +1049,163248 +1050,163248 +1051,164720 +1052,164720 +1053,164752 +1054,165088 +1055,165088 +1056,165088 +1057,165088 +1058,165088 +1059,165120 +1060,165120 +1061,165120 +1062,165152 +1063,165152 +1064,165152 +1065,165152 +1066,165152 +1067,165152 +1068,165152 +1069,165152 +1070,165152 +1071,165152 +1072,165456 +1073,165456 +1074,165456 +1075,165456 +1076,165456 +1077,165456 +1078,165456 +1079,165456 +1080,165456 +1081,166848 +1082,166848 +1083,166880 +1084,167232 +1085,167232 +1086,167232 +1087,167600 +1088,167600 +1089,167600 +1090,167600 +1091,167600 +1092,167632 +1093,167632 +1094,167632 +1095,160960 +1096,161312 +1097,161312 +1098,161312 +1099,161648 +1100,161648 +1101,161648 +1102,162032 +1103,162032 +1104,162032 +1105,162384 +1106,162384 +1107,162384 +1108,162752 +1109,162752 +1110,162752 +1111,165696 +1112,165696 +1113,165728 +1114,165728 +1115,165728 +1116,165728 +1117,165728 +1118,165728 +1119,165728 +1120,165728 +1121,165728 +1122,165728 +1123,165728 +1124,165728 +1125,165728 +1126,166080 +1127,166080 +1128,166080 +1129,166080 +1130,166080 +1131,166080 +1132,166416 +1133,166416 +1134,166416 +1135,166768 +1136,166768 +1137,166768 +1138,167136 +1139,167136 +1140,167136 +1141,169664 +1142,169664 +1143,169648 +1144,169664 +1145,169664 +1146,169680 +1147,170016 +1148,170016 +1149,169904 +1150,170256 +1151,170256 +1152,166912 +1153,163808 +1154,163808 +1155,158528 +1156,159552 +1157,159552 +1158,159552 +1159,159552 +1160,159552 +1161,159552 +1162,159552 +1163,159552 +1164,159584 +1165,159584 +1166,159584 +1167,159584 +1168,159584 +1169,159584 +1170,159584 +1171,160912 +1172,160912 +1173,160912 +1174,160912 +1175,160912 +1176,160912 +1177,160960 +1178,160960 +1179,160992 +1180,160992 +1181,160992 +1182,161072 +1183,161424 +1184,161424 +1185,161424 +1186,161776 +1187,161776 +1188,161776 +1189,162128 +1190,162128 +1191,162128 +1192,162208 +1193,162208 +1194,162272 +1195,162624 +1196,162624 +1197,162624 +1198,162992 +1199,162992 +1200,163008 +1201,165552 +1202,165552 +1203,165584 +1204,165584 +1205,165584 +1206,165616 +1207,165616 +1208,165616 +1209,165616 +1210,165616 +1211,165616 +1212,165616 +1213,165840 +1214,165840 +1215,165840 +1216,166224 +1217,166224 +1218,166224 +1219,166544 +1220,166544 +1221,166544 +1222,166544 +1223,166544 +1224,166544 +1225,166896 +1226,166896 +1227,166896 +1228,167264 +1229,167264 +1230,167264 +1231,168432 +1232,168432 +1233,168464 +1234,168736 +1235,168736 +1236,168736 +1237,168736 +1238,168736 +1239,168768 +1240,168768 +1241,168768 +1242,168768 +1243,168768 +1244,168768 +1245,168768 +1246,169120 +1247,169120 +1248,169120 +1249,169456 +1250,169456 +1251,169456 +1252,169840 +1253,169840 +1254,169840 +1255,169840 +1256,169840 +1257,169856 +1258,169856 +1259,169856 +1260,169856 +1261,171392 +1262,171392 +1263,171408 +1264,171776 +1265,171776 +1266,171776 +1267,172144 +1268,172144 +1269,172144 +1270,172160 +1271,172160 +1272,172192 +1273,172192 +1274,172192 +1275,172192 +1276,172336 +1277,172336 +1278,172336 +1279,172336 +1280,172336 +1281,140192 +1282,140192 +1283,140192 +1284,132144 +1285,132512 +1286,132512 +1287,128880 +1288,129248 +1289,129248 +1290,129248 +1291,132560 +1292,132560 +1293,132592 +1294,132592 +1295,132592 +1296,132624 +1297,129392 +1298,129312 +1299,126704 +1300,126704 +1301,126704 +1302,126704 +1303,127024 +1304,127024 +1305,127024 +1306,127392 +1307,127392 +1308,121152 +1309,121184 +1310,121184 +1311,117872 +1312,118224 +1313,118224 +1314,118224 +1315,118592 +1316,118592 +1317,118592 +1318,118592 +1319,118592 +1320,111872 +1321,111872 +1322,111872 +1323,111904 +1324,112176 +1325,112176 +1326,112176 +1327,112448 +1328,112448 +1329,112928 +1330,113696 +1331,113696 +1332,113936 +1333,114368 +1334,114368 +1335,114416 +1336,114848 +1337,114848 +1338,114864 +1339,115216 +1340,115216 +1341,115216 +1342,115216 +1343,115216 +1344,115264 +1345,115632 +1346,115632 +1347,115632 +1348,115632 +1349,115632 +1350,115632 +1351,117072 +1352,117072 +1353,117104 +1354,117456 +1355,117456 +1356,117456 +1357,117840 +1358,117840 +1359,117840 +1360,118192 +1361,118192 +1362,118192 +1363,118560 +1364,118560 +1365,118560 +1366,118912 +1367,118912 +1368,118944 +1369,119296 +1370,119296 +1371,119296 +1372,119296 +1373,119296 +1374,119328 +1375,119328 +1376,119328 +1377,119328 +1378,119328 +1379,119328 +1380,119360 +1381,122080 +1382,122080 +1383,122112 +1384,122112 +1385,122112 +1386,122112 +1387,122448 +1388,122448 +1389,122448 +1390,122800 +1391,122800 +1392,122800 +1393,123168 +1394,123168 +1395,123168 +1396,123520 +1397,123520 +1398,123520 +1399,123520 +1400,123520 +1401,123520 +1402,123904 +1403,123904 +1404,123904 +1405,124256 +1406,124256 +1407,124256 +1408,124256 +1409,124256 +1410,124272 +1411,125712 +1412,125712 +1413,125744 +1414,125744 +1415,125744 +1416,125744 +1417,126096 +1418,126096 +1419,126096 +1420,126448 +1421,126448 +1422,126448 +1423,126816 +1424,126816 +1425,126816 +1426,127168 +1427,127168 +1428,127168 +1429,127520 +1430,127520 +1431,127552 +1432,127904 +1433,127904 +1434,127920 +1435,128272 +1436,128272 +1437,128272 +1438,128624 +1439,128624 +1440,128624 +1441,131584 +1442,131584 +1443,131616 +1444,131632 +1445,131632 +1446,131632 +1447,131632 +1448,131632 +1449,131664 +1450,131664 +1451,131664 +1452,131664 +1453,131664 +1454,131664 +1455,131664 +1456,131664 +1457,131664 +1458,131664 +1459,131664 +1460,131664 +1461,131664 +1462,131664 +1463,131664 +1464,131664 +1465,131664 +1466,131664 +1467,131664 +1468,131664 +1469,131664 +1470,131664 +1471,133168 +1472,133168 +1473,130560 +1474,128144 +1475,128096 +1476,121616 +1477,121632 +1478,121632 +1479,121632 +1480,121792 +1481,121792 +1482,121792 +1483,121792 +1484,121792 +1485,121792 +1486,121792 +1487,121792 +1488,121792 +1489,121792 +1490,121792 +1491,121792 +1492,122320 +1493,122320 +1494,122336 +1495,122336 +1496,122336 +1497,122336 +1498,122336 +1499,122336 +1500,122336 +1501,123472 +1502,123472 +1503,123504 +1504,123840 +1505,123840 +1506,123840 +1507,124208 +1508,124208 +1509,124272 +1510,124624 +1511,124624 +1512,124624 +1513,124992 +1514,124992 +1515,124992 +1516,125344 +1517,125344 +1518,125344 +1519,125696 +1520,125696 +1521,125696 +1522,126064 +1523,126064 +1524,126064 +1525,126368 +1526,126368 +1527,126400 +1528,126400 +1529,126400 +1530,126400 +1531,127584 +1532,127584 +1533,127616 +1534,127904 +1535,127904 +1536,127904 +1537,128256 +1538,128256 +1539,128256 +1540,128448 +1541,128448 +1542,128448 +1543,128832 +1544,128832 +1545,128832 +1546,129200 +1547,129200 +1548,129200 +1549,129536 +1550,129536 +1551,129536 +1552,129904 +1553,129904 +1554,129920 +1555,130272 +1556,130272 +1557,130272 +1558,130656 +1559,130656 +1560,130688 +1561,133920 +1562,133920 +1563,133952 +1564,134304 +1565,134304 +1566,134320 +1567,134320 +1568,134320 +1569,134336 +1570,134336 +1571,134336 +1572,134336 +1573,134336 +1574,134336 +1575,134336 +1576,134336 +1577,134336 +1578,134336 +1579,134640 +1580,134640 +1581,134640 +1582,135008 +1583,135008 +1584,135008 +1585,135360 +1586,135360 +1587,135392 +1588,135760 +1589,135760 +1590,135760 +1591,137616 +1592,137616 +1593,137648 +1594,137952 +1595,137952 +1596,137952 +1597,137952 +1598,137952 +1599,137968 +1600,138336 +1601,138336 +1602,138336 +1603,138688 +1604,138688 +1605,138688 +1606,138720 +1607,138720 +1608,138720 +1609,138720 +1610,138720 +1611,138720 +1612,138720 +1613,138720 +1614,138720 +1615,138720 +1616,138720 +1617,138720 +1618,138720 +1619,138720 +1620,138720 +1621,140288 +1622,140288 +1623,140320 +1624,140672 +1625,140672 +1626,140672 +1627,141024 +1628,141024 +1629,141024 +1630,141392 +1631,141392 +1632,141392 +1633,141408 +1634,141408 +1635,141408 +1636,141408 +1637,141408 +1638,141424 +1639,141424 +1640,141424 +1641,141424 +1642,141424 +1643,141424 +1644,141456 +1645,141760 +1646,141760 +1647,141760 +1648,142128 +1649,142128 +1650,142128 +1651,144016 +1652,144016 +1653,144048 +1654,144352 +1655,144352 +1656,144352 +1657,144720 +1658,144720 +1659,144720 +1660,145072 +1661,145072 +1662,145072 +1663,145440 +1664,145440 +1665,145440 +1666,145440 +1667,145440 +1668,145472 +1669,145472 +1670,145472 +1671,145472 +1672,145472 +1673,145472 +1674,145472 +1675,145792 +1676,145792 +1677,140992 +1678,142032 +1679,142032 +1680,142032 +1681,144672 +1682,144672 +1683,144704 +1684,145040 +1685,145040 +1686,145040 +1687,145040 +1688,145040 +1689,145056 +1690,145056 +1691,145056 +1692,145056 +1693,145056 +1694,145056 +1695,145056 +1696,145056 +1697,145056 +1698,145056 +1699,145056 +1700,145056 +1701,145056 +1702,145056 +1703,145056 +1704,145056 +1705,145056 +1706,145056 +1707,145056 +1708,145408 +1709,145408 +1710,145408 +1711,148272 +1712,148272 +1713,148304 +1714,148656 +1715,148656 +1716,148656 +1717,149024 +1718,149024 +1719,149024 +1720,149376 +1721,149376 +1722,149376 +1723,149376 +1724,149376 +1725,149376 +1726,142000 +1727,142000 +1728,142000 +1729,142000 +1730,142000 +1731,142000 +1732,142000 +1733,142000 +1734,142000 +1735,142000 +1736,142000 +1737,142000 +1738,142000 +1739,142000 +1740,142000 +1741,142000 +1742,142000 +1743,142000 +1744,142000 +1745,142000 +1746,142000 +1747,142000 +1748,142000 +1749,142016 +1750,142016 +1751,142016 +1752,142080 +1753,142096 +1754,142096 +1755,142096 +1756,144064 +1757,144064 +1758,144144 +1759,144144 +1760,144144 +1761,144144 +1762,144176 +1763,144176 +1764,144176 +1765,144176 +1766,144176 +1767,144176 +1768,144176 +1769,135984 +1770,135984 +1771,135984 +1772,135984 +1773,135984 +1774,135984 +1775,135984 +1776,135984 +1777,135984 +1778,135984 +1779,135984 +1780,135984 +1781,135984 +1782,135984 +1783,135984 +1784,135984 +1785,135984 +1786,136656 +1787,136656 +1788,136672 +1789,137040 +1790,137040 +1791,137040 +1792,137408 +1793,137408 +1794,137408 +1795,137408 +1796,137408 +1797,137408 +1798,137568 +1799,137568 +1800,137568 +1801,137568 +1802,137568 +1803,137568 +1804,137568 +1805,137568 +1806,137568 +1807,137568 +1808,137568 +1809,137568 +1810,137648 +1811,137648 +1812,137648 +1813,137664 +1814,137664 +1815,137664 +1816,137664 +1817,137664 +1818,137664 +1819,137664 +1820,137664 +1821,137664 +1822,137664 +1823,137664 +1824,129296 +1825,129328 +1826,129328 +1827,129392 +1828,129392 +1829,129392 +1830,129392 +1831,129392 +1832,129392 +1833,129392 +1834,129392 +1835,129392 +1836,129392 +1837,129392 +1838,129392 +1839,129408 +1840,129424 +1841,129424 +1842,129440 +1843,129440 +1844,129440 +1845,129440 +1846,129440 +1847,129440 +1848,129440 +1849,129440 +1850,129440 +1851,129440 +1852,129552 +1853,129552 +1854,129712 +1855,129744 +1856,129744 +1857,129776 +1858,129776 +1859,129776 +1860,129776 +1861,129776 +1862,129776 +1863,129792 +1864,129792 +1865,129792 +1866,129792 +1867,129792 +1868,129792 +1869,129792 +1870,129792 +1871,129792 +1872,129792 +1873,129792 +1874,129792 +1875,129792 +1876,129792 +1877,129792 +1878,129792 +1879,129792 +1880,129792 +1881,129792 +1882,129792 +1883,129792 +1884,129792 +1885,129840 +1886,129840 +1887,129856 +1888,129856 +1889,129856 +1890,129856 +1891,129856 +1892,129856 +1893,129856 +1894,129856 +1895,129856 +1896,129856 +1897,129856 +1898,129856 +1899,129856 +1900,129856 +1901,129856 +1902,129856 +1903,129856 +1904,129856 +1905,129856 +1906,129856 +1907,129856 +1908,129856 +1909,129856 +1910,129856 +1911,129856 +1912,129856 +1913,129856 +1914,129856 +1915,129856 +1916,129856 +1917,129856 +1918,129856 +1919,129856 +1920,129856 +1921,129856 +1922,129856 +1923,129856 +1924,129856 +1925,129856 +1926,129856 +1927,129856 +1928,129856 +1929,129856 +1930,129856 +1931,129856 +1932,129856 +1933,129856 +1934,129856 +1935,129856 +1936,129856 +1937,129856 +1938,129856 +1939,129856 +1940,129856 +1941,129856 +1942,129856 +1943,129856 +1944,129856 +1945,129856 +1946,129856 +1947,129856 +1948,129856 +1949,129856 +1950,129856 +1951,129856 +1952,129856 +1953,129856 +1954,129856 +1955,129856 +1956,129856 +1957,129856 +1958,129856 +1959,129856 +1960,129856 +1961,129856 +1962,129856 +1963,129856 +1964,129856 +1965,129856 +1966,129856 +1967,129856 +1968,129856 +1969,129856 +1970,129856 +1971,129856 +1972,129856 +1973,129856 +1974,129856 +1975,129856 +1976,129856 +1977,129856 +1978,129856 +1979,129856 +1980,129856 +1981,129856 +1982,129856 +1983,129856 +1984,129856 +1985,129856 +1986,129856 +1987,129856 +1988,129856 +1989,129856 +1990,129856 +1991,129856 +1992,129856 +1993,129856 +1994,129856 +1995,129856 +1996,129856 +1997,129856 +1998,129856 +1999,129856 +2000,129856 +2001,129856 +2002,129856 +2003,129856 +2004,129856 +2005,129856 +2006,129856 +2007,129856 +2008,129856 +2009,129856 +2010,129856 +2011,129856 +2012,129856 +2013,129856 +2014,129856 +2015,129856 +2016,129856 +2017,129856 +2018,129856 +2019,129856 +2020,129856 +2021,129856 +2022,129856 +2023,129856 +2024,129856 +2025,129856 +2026,129856 +2027,129856 +2028,129856 +2029,129856 +2030,129856 +2031,129856 +2032,129856 +2033,129856 +2034,129808 +2035,129856 +2036,129856 +2037,129856 +2038,129856 +2039,129856 +2040,129856 +2041,129856 +2042,129856 +2043,129856 +2044,129856 +2045,129856 +2046,129856 +2047,129856 +2048,129856 +2049,129856 +2050,129856 +2051,129856 +2052,129856 +2053,129856 +2054,129856 +2055,129856 +2056,129856 +2057,129856 +2058,129856 +2059,129856 +2060,129856 +2061,129856 +2062,129856 +2063,129856 +2064,129856 +2065,129856 +2066,129856 +2067,129856 +2068,130064 +2069,130064 +2070,130064 +2071,130416 +2072,130416 +2073,130416 +2074,130768 +2075,130768 +2076,130784 +2077,131136 +2078,131152 +2079,131152 +2080,131520 +2081,131520 +2082,131552 +2083,131552 +2084,131552 +2085,131552 +2086,131552 +2087,131552 +2088,131552 +2089,131552 +2090,131552 +2091,131552 +2092,131552 +2093,131552 +2094,131552 +2095,131552 +2096,131552 +2097,131584 +2098,131584 +2099,131584 +2100,131584 +2101,131584 +2102,131584 +2103,131616 +2104,131616 +2105,131616 +2106,131616 +2107,131616 +2108,131616 +2109,131616 +2110,131648 +2111,131648 +2112,131648 +2113,131648 +2114,131648 +2115,131648 +2116,131952 +2117,131952 +2118,131984 +2119,131984 +2120,131984 +2121,131984 +2122,131984 +2123,131984 +2124,131984 +2125,131984 +2126,131984 +2127,131984 +2128,131984 +2129,131984 +2130,131984 +2131,131984 +2132,131984 +2133,131984 +2134,131984 +2135,131984 +2136,131984 +2137,131984 +2138,131984 +2139,131984 +2140,131984 +2141,131984 +2142,131984 +2143,131984 +2144,131984 +2145,131984 +2146,131984 +2147,131984 +2148,131984 +2149,131984 +2150,131984 +2151,131984 +2152,132240 +2153,132240 +2154,132256 +2155,132256 +2156,132256 +2157,132256 +2158,132256 +2159,132256 +2160,132256 +2161,132256 +2162,132256 +2163,132256 +2164,132256 +2165,132256 +2166,132256 +2167,132256 +2168,132256 +2169,132256 +2170,132256 +2171,132256 +2172,132256 +2173,132624 +2174,132624 +2175,132624 +2176,132624 +2177,132624 +2178,132624 +2179,132624 +2180,132624 +2181,132624 +2182,132624 +2183,132624 +2184,132624 +2185,132624 +2186,132624 +2187,132656 +2188,132656 +2189,132656 +2190,132656 +2191,132656 +2192,132656 +2193,132656 +2194,132656 +2195,132656 +2196,132656 +2197,132656 +2198,132656 +2199,132656 +2200,132656 +2201,132656 +2202,132656 +2203,132656 +2204,132656 +2205,132656 +2206,132656 +2207,132656 +2208,132656 +2209,132656 +2210,132656 +2211,132656 +2212,132656 +2213,132656 +2214,132656 +2215,132656 +2216,132656 +2217,132656 +2218,132656 +2219,132656 +2220,132656 +2221,132992 +2222,132992 +2223,132992 +2224,133344 +2225,133344 +2226,133344 +2227,133696 +2228,133696 +2229,133696 +2230,133696 +2231,133696 +2232,133696 +2233,133696 +2234,133696 +2235,133696 +2236,133696 +2237,133696 +2238,133696 +2239,133696 +2240,133696 +2241,133696 +2242,133696 +2243,133696 +2244,133696 +2245,133696 +2246,133696 +2247,133728 +2248,133728 +2249,133728 +2250,133728 +2251,133728 +2252,133728 +2253,133728 +2254,133728 +2255,133728 +2256,133728 +2257,133728 +2258,133728 +2259,133760 +2260,134080 +2261,134080 +2262,134080 +2263,134080 +2264,134080 +2265,134080 +2266,135616 +2267,135616 +2268,135648 +2269,135952 +2270,135952 +2271,135952 +2272,136304 +2273,136304 +2274,136304 +2275,136672 +2276,136672 +2277,136672 +2278,136672 +2279,136672 +2280,136672 +2281,136672 +2282,136672 +2283,136672 +2284,136672 +2285,136672 +2286,136672 +2287,136672 +2288,136672 +2289,136672 +2290,136672 +2291,136672 +2292,136672 +2293,136672 +2294,136672 +2295,136672 +2296,137216 +2297,137216 +2298,137216 +2299,137216 +2300,137216 +2301,137216 +2302,137216 +2303,137216 +2304,137232 +2305,137232 +2306,137232 +2307,137232 +2308,137232 +2309,137232 +2310,137232 +2311,137232 +2312,137232 +2313,137232 +2314,137232 +2315,137232 +2316,137232 +2317,137232 +2318,137232 +2319,137232 +2320,137232 +2321,137232 +2322,137232 +2323,137232 +2324,137232 +2325,137232 +2326,137232 +2327,137232 +2328,137232 +2329,137232 +2330,137232 +2331,137232 +2332,137232 +2333,137232 +2334,137232 +2335,137232 +2336,137232 +2337,137232 +2338,137232 +2339,137232 +2340,137232 +2341,137232 +2342,137232 +2343,137232 +2344,137232 +2345,137232 +2346,137232 +2347,137232 +2348,137232 +2349,137232 +2350,137232 +2351,137232 +2352,137232 +2353,137232 +2354,137232 +2355,137232 +2356,139728 +2357,139728 +2358,139760 +2359,140128 +2360,140128 +2361,140128 +2362,140480 +2363,140480 +2364,140480 +2365,140848 +2366,140848 +2367,140848 +2368,141200 +2369,141200 +2370,141200 +2371,141216 +2372,141216 +2373,141216 +2374,141216 +2375,141216 +2376,141216 +2377,141216 +2378,141216 +2379,141216 +2380,141216 +2381,141216 +2382,141216 +2383,141216 +2384,141216 +2385,141216 +2386,141216 +2387,141216 +2388,141216 +2389,141216 +2390,141216 +2391,141216 +2392,141216 +2393,141216 +2394,141216 +2395,141216 +2396,141216 +2397,141216 +2398,141216 +2399,141216 +2400,141216 +2401,141216 +2402,141216 +2403,141216 +2404,141216 +2405,141216 +2406,141216 +2407,141216 +2408,141216 +2409,141216 +2410,141216 +2411,141216 +2412,141216 +2413,141216 +2414,141216 +2415,141216 +2416,141616 +2417,141616 +2418,141648 +2419,142000 +2420,142000 +2421,142000 +2422,142368 +2423,142368 +2424,142368 +2425,142368 +2426,142368 +2427,142368 +2428,142368 +2429,142368 +2430,141072 +2431,141440 +2432,141440 +2433,141440 +2434,141776 +2435,141776 +2436,141776 +2437,142144 +2438,142144 +2439,141584 +2440,141936 +2441,141936 +2442,141936 +2443,141952 +2444,141952 +2445,141968 +2446,144112 +2447,144112 +2448,144128 +2449,144496 +2450,144496 +2451,144496 +2452,144864 +2453,144864 +2454,144864 +2455,144864 +2456,144864 +2457,144864 +2458,144864 +2459,144864 +2460,144864 +2461,145232 +2462,145232 +2463,145232 +2464,145568 +2465,145568 +2466,145568 +2467,145568 +2468,145568 +2469,145568 +2470,145936 +2471,145936 +2472,145936 +2473,146272 +2474,146272 +2475,146304 +2476,147856 +2477,147856 +2478,147872 +2479,148208 +2480,148208 +2481,148208 +2482,148560 +2483,148560 +2484,148560 +2485,148912 +2486,148912 +2487,148912 +2488,149280 +2489,149280 +2490,149280 +2491,149632 +2492,149632 +2493,149632 +2494,149984 +2495,149984 +2496,149984 +2497,149984 +2498,149984 +2499,149984 +2500,149984 +2501,149984 +2502,150016 +2503,150016 +2504,150016 +2505,150048 +2506,151552 +2507,151552 +2508,151568 +2509,151872 +2510,151872 +2511,151904 +2512,151904 +2513,151904 +2514,151904 +2515,151904 +2516,151904 +2517,151904 +2518,151904 +2519,151904 +2520,151904 +2521,151904 +2522,151904 +2523,151904 +2524,151904 +2525,151904 +2526,151904 +2527,151904 +2528,151904 +2529,151904 +2530,152240 +2531,152240 +2532,152240 +2533,152608 +2534,152608 +2535,152608 +2536,155536 +2537,155536 +2538,155568 +2539,155920 +2540,155920 +2541,155920 +2542,156272 +2543,156272 +2544,156272 +2545,156640 +2546,156640 +2547,156640 +2548,156992 +2549,156992 +2550,157024 +2551,157392 +2552,157392 +2553,157392 +2554,157392 +2555,157392 +2556,157392 +2557,157392 +2558,157392 +2559,157392 +2560,157392 +2561,157392 +2562,157392 +2563,157392 +2564,157392 +2565,157392 +2566,157392 +2567,157392 +2568,157392 +2569,157392 +2570,157392 +2571,157392 +2572,157408 +2573,157408 +2574,157424 +2575,157424 +2576,157424 +2577,157424 +2578,157424 +2579,157424 +2580,157424 +2581,157424 +2582,157424 +2583,157424 +2584,157424 +2585,157424 +2586,157424 +2587,157424 +2588,157424 +2589,157376 +2590,157376 +2591,157376 +2592,157376 +2593,157376 +2594,157376 +2595,157376 +2596,159120 +2597,159120 +2598,159152 +2599,159168 +2600,159168 +2601,159168 +2602,159168 +2603,159168 +2604,159168 +2605,159168 +2606,159168 +2607,159168 +2608,159168 +2609,159168 +2610,159168 +2611,159600 +2612,159600 +2613,159728 +2614,159744 +2615,159744 +2616,159712 +2617,160048 +2618,160048 +2619,160048 +2620,160400 +2621,160400 +2622,160400 +2623,160768 +2624,160768 +2625,160768 +2626,162352 +2627,162352 +2628,162368 +2629,162672 +2630,162672 +2631,162672 +2632,162992 +2633,162992 +2634,162992 +2635,162992 +2636,162992 +2637,163008 +2638,163024 +2639,163024 +2640,163024 +2641,163360 +2642,163360 +2643,163392 +2644,163728 +2645,163728 +2646,163728 +2647,164080 +2648,164080 +2649,164080 +2650,164448 +2651,164448 +2652,164448 +2653,164800 +2654,164800 +2655,164800 +2656,166288 +2657,166288 +2658,166288 +2659,166288 +2660,166288 +2661,166288 +2662,166288 +2663,166288 +2664,166288 +2665,166608 +2666,166608 +2667,166608 +2668,166608 +2669,166608 +2670,166608 +2671,166608 +2672,166608 +2673,166608 +2674,166608 +2675,166608 +2676,166608 +2677,166608 +2678,166608 +2679,166624 +2680,166992 +2681,166992 +2682,166992 +2683,167360 +2684,167360 +2685,167360 +2686,169936 +2687,169936 +2688,169968 +2689,170304 +2690,170304 +2691,170304 +2692,170672 +2693,170672 +2694,170672 +2695,170672 +2696,170672 +2697,170672 +2698,170672 +2699,170672 +2700,170672 +2701,170672 +2702,170672 +2703,170672 +2704,170672 +2705,170672 +2706,170672 +2707,170672 +2708,170672 +2709,170672 +2710,170672 +2711,170672 +2712,170672 +2713,171008 +2714,171008 +2715,171008 +2716,172848 +2717,172848 +2718,172880 +2719,173200 +2720,173200 +2721,173200 +2722,173568 +2723,173568 +2724,173568 +2725,173568 +2726,173568 +2727,173600 +2728,173600 +2729,173600 +2730,173600 +2731,173952 +2732,173952 +2733,173952 +2734,173952 +2735,173952 +2736,173952 +2737,173952 +2738,173952 +2739,173952 +2740,173952 +2741,173952 +2742,173952 +2743,173952 +2744,173952 +2745,173952 +2746,175776 +2747,175776 +2748,175824 +2749,175824 +2750,175824 +2751,175856 +2752,176160 +2753,176160 +2754,176192 +2755,176560 +2756,176560 +2757,176560 +2758,176912 +2759,176912 +2760,176912 +2761,176912 +2762,176912 +2763,176944 +2764,176944 +2765,176944 +2766,176944 +2767,176944 +2768,176944 +2769,176944 +2770,176944 +2771,176944 +2772,176976 +2773,177280 +2774,177280 +2775,177280 +2776,179824 +2777,179824 +2778,179856 +2779,180192 +2780,180192 +2781,180032 +2782,180384 +2783,180384 +2784,180384 +2785,180752 +2786,180752 +2787,180752 +2788,180752 +2789,180752 +2790,180752 +2791,180752 +2792,180752 +2793,180752 +2794,180752 +2795,180752 +2796,180784 +2797,180944 +2798,180944 +2799,180944 +2800,180944 +2801,180944 +2802,180944 +2803,180944 +2804,180944 +2805,180944 +2806,183792 +2807,183792 +2808,183824 +2809,184192 +2810,184192 +2811,184192 +2812,184544 +2813,184544 +2814,184544 +2815,184912 +2816,184912 +2817,184912 +2818,184912 +2819,184912 +2820,184912 +2821,184912 +2822,184912 +2823,184912 +2824,185264 +2825,185264 +2826,185264 +2827,185632 +2828,185632 +2829,185632 +2830,185632 +2831,185632 +2832,185632 +2833,185632 +2834,185632 +2835,185632 +2836,188192 +2837,188192 +2838,188256 +2839,188256 +2840,188256 +2841,187280 +2842,187280 +2843,187280 +2844,187280 +2845,187280 +2846,187280 +2847,187280 +2848,187280 +2849,187280 +2850,187280 +2851,187600 +2852,187600 +2853,187600 +2854,187936 +2855,187936 +2856,187936 +2857,188256 +2858,188256 +2859,188256 +2860,188272 +2861,188272 +2862,188288 +2863,188288 +2864,188288 +2865,188288 +2866,188768 +2867,188768 +2868,188800 +2869,189120 +2870,189120 +2871,189120 +2872,189488 +2873,189488 +2874,189488 +2875,189488 +2876,189488 +2877,189488 +2878,189840 +2879,189840 +2880,189840 +2881,190208 +2882,190208 +2883,190208 +2884,190544 +2885,190544 +2886,190544 +2887,190912 +2888,190912 +2889,190912 +2890,191168 +2891,191168 +2892,191168 +2893,191520 +2894,191520 +2895,191520 +2896,194864 +2897,194864 +2898,194880 +2899,194880 +2900,194880 +2901,194880 +2902,194880 +2903,194880 +2904,194880 +2905,194880 +2906,194880 +2907,194880 +2908,195200 +2909,195200 +2910,195200 +2911,195568 +2912,195568 +2913,195568 +2914,195904 +2915,195904 +2916,195904 +2917,196272 +2918,196272 +2919,196272 +2920,196560 +2921,196560 +2922,196560 +2923,196560 +2924,196560 +2925,196560 +2926,199072 +2927,199072 +2928,199104 +2929,199456 +2930,199456 +2931,199456 +2932,199488 +2933,199488 +2934,199520 +2935,199888 +2936,199888 +2937,199888 +2938,200240 +2939,200240 +2940,200240 +2941,200608 +2942,200608 +2943,200608 +2944,200944 +2945,200944 +2946,200944 +2947,201312 +2948,201312 +2949,201312 +2950,201680 +2951,201680 +2952,201680 +2953,201680 +2954,201680 +2955,201712 +2956,202800 +2957,202800 +2958,202832 +2959,203200 +2960,203200 +2961,203200 +2962,203552 +2963,203552 +2964,203568 +2965,203568 +2966,203568 +2967,203600 +2968,203600 +2969,203600 +2970,198560 +2971,198576 +2972,198576 +2973,198576 +2974,198576 +2975,198576 +2976,198576 +2977,198576 +2978,198576 +2979,198576 +2980,198576 +2981,198576 +2982,198576 +2983,198592 +2984,198592 +2985,198592 +2986,201488 +2987,201488 +2988,201504 +2989,201856 +2990,201856 +2991,199968 +2992,199984 +2993,199984 +2994,200000 +2995,200048 +2996,200048 +2997,200048 +2998,200048 +2999,200048 +3000,200128 +3001,200496 +3002,135552 diff --git a/python/requirements.txt b/python/requirements.txt index 9e6c929ec..ea2241724 100644 --- a/python/requirements.txt +++ b/python/requirements.txt @@ -22,4 +22,5 @@ numpy==1.26.4 pandas==2.2.2 setuptools==70.0.0 wheel==0.45.1 - +tqdm +psutil diff --git a/python/setup.py b/python/setup.py index 6edeea0b9..4f4e0e4f8 100644 --- a/python/setup.py +++ b/python/setup.py @@ -16,17 +16,19 @@ # under the License. # -from setuptools import setup, Extension -from setuptools.command.build_ext import build_ext -from Cython.Build import cythonize -import numpy as np +import os import platform import shutil -import os -version = "2.1.0.dev0" +import numpy as np +from Cython.Build import cythonize +from setuptools import setup, Extension +from setuptools.command.build_ext import build_ext + +version = "2.1.0.dev" system = platform.system() + def copy_tsfile_lib(source_dir, target_dir, suffix): lib_file_name = f"libtsfile.{suffix}" source = os.path.join(source_dir, lib_file_name) @@ -51,6 +53,7 @@ def copy_tsfile_header(source, target): if os.path.exists(source): shutil.copyfile(source, target) + project_dir = os.path.dirname(os.path.abspath(__file__)) ## Copy C wrapper header. @@ -72,8 +75,7 @@ def copy_tsfile_header(source, target): else: copy_tsfile_lib(tsfile_shared_source_dir, tsfile_shared_dir, "dll") -tsfile_include_dir=os.path.join(project_dir, "tsfile") - +tsfile_include_dir = os.path.join(project_dir, "tsfile") ext_modules_tsfile = [ # utils: from python to c or c to python. @@ -141,7 +143,10 @@ def finalize_options(self): author='"Apache TsFile"', packages=["tsfile"], license="Apache 2.0", - ext_modules=cythonize(ext_modules_tsfile), + ext_modules=cythonize( + ext_modules_tsfile + ), + cmdclass={"build_ext": BuildExt}, include_dirs=[np.get_include()], package_dir={"tsfile": "./tsfile"}, diff --git a/python/tsfile/tablet.py b/python/tsfile/tablet.py index 2935db09d..52e7389c4 100644 --- a/python/tsfile/tablet.py +++ b/python/tsfile/tablet.py @@ -137,7 +137,8 @@ def add_value_by_index(self, col_index: int, row_index: int, value: Union[int, f if not isinstance(value, expected_type.to_py_type()): raise TypeError(f"Expected {expected_type.to_py_type()} got {type(value)}") - self._check_numeric_range(value, expected_type) + if expected_type in (TSDataType.INT32, TSDataType.INT64, TSDataType.FLOAT, TSDataType.DOUBLE): + self._check_numeric_range(value, expected_type) self.data_list[col_index][row_index] = value From cd4ff885fcd93653b69a5060371d28abdc0be2f3 Mon Sep 17 00:00:00 2001 From: shuolin_l Date: Thu, 17 Apr 2025 17:42:33 +0800 Subject: [PATCH 2/3] add win benchmark. --- cpp/bench_mark/CMakeLists.txt | 5 +++++ cpp/bench_mark/src/bench_mark_utils.cc | 11 ++++++++--- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/cpp/bench_mark/CMakeLists.txt b/cpp/bench_mark/CMakeLists.txt index 36f8dac97..7d7e96c53 100644 --- a/cpp/bench_mark/CMakeLists.txt +++ b/cpp/bench_mark/CMakeLists.txt @@ -50,4 +50,9 @@ add_executable(bench_mark src/bench_mark_c.cc src/bench_mark.cc src/bench_mark_utils.cc) + +if (WIN32) + target_link_libraries(bench_mark Psapi) +endif() + target_link_libraries(bench_mark tsfile) diff --git a/cpp/bench_mark/src/bench_mark_utils.cc b/cpp/bench_mark/src/bench_mark_utils.cc index 841f8c0c8..c4b4562f1 100644 --- a/cpp/bench_mark/src/bench_mark_utils.cc +++ b/cpp/bench_mark/src/bench_mark_utils.cc @@ -18,13 +18,19 @@ */ #include "bench_mark_utils.h" - +#ifndef _WIN32 #include +#endif #include #include #include +#ifdef _WIN32 +#include +#include +#endif + #ifdef __APPLE__ #include #include @@ -77,8 +83,6 @@ void print_progress_bar(int current, int total, int barWidth) { int get_memory_usage() { #ifdef _WIN32 -#include -#include PROCESS_MEMORY_COUNTERS pmc; if (GetProcessMemoryInfo(GetCurrentProcess(), &pmc, sizeof(pmc))) { return pmc.WorkingSetSize / 1024 ; @@ -100,6 +104,7 @@ int get_memory_usage() { } } } + return 0; #elif defined(__APPLE__) task_basic_info_data_t info; From 7a579d8c52d92a7a07fff3569defd95b535f83c1 Mon Sep 17 00:00:00 2001 From: shuolin_l Date: Thu, 17 Apr 2025 17:46:06 +0800 Subject: [PATCH 3/3] remove file. --- python/bench_mark/memory_usage_python.csv | 3004 --------------------- 1 file changed, 3004 deletions(-) delete mode 100644 python/bench_mark/memory_usage_python.csv diff --git a/python/bench_mark/memory_usage_python.csv b/python/bench_mark/memory_usage_python.csv deleted file mode 100644 index e5c10a0a7..000000000 --- a/python/bench_mark/memory_usage_python.csv +++ /dev/null @@ -1,3004 +0,0 @@ -iter_num,memory_usage(kb) -0,71952 -1,72064 -2,72752 -3,74832 -4,76944 -5,76944 -6,77520 -7,77936 -8,77936 -9,78928 -10,79328 -11,79328 -12,79392 -13,80016 -14,80016 -15,80048 -16,80512 -17,80512 -18,80528 -19,80864 -20,80864 -21,80864 -22,81200 -23,81200 -24,81296 -25,81648 -26,81648 -27,81648 -28,82064 -29,82064 -30,82080 -31,84160 -32,84160 -33,84240 -34,84240 -35,84240 -36,84320 -37,84368 -38,84368 -39,84464 -40,84880 -41,84880 -42,84992 -43,85232 -44,85232 -45,85264 -46,85616 -47,85632 -48,85632 -49,85968 -50,85968 -51,85968 -52,86320 -53,86320 -54,86320 -55,86320 -56,86320 -57,86320 -58,86688 -59,86688 -60,86688 -61,93200 -62,93200 -63,93280 -64,93664 -65,93664 -66,93664 -67,94032 -68,94032 -69,94032 -70,94384 -71,94384 -72,94384 -73,94384 -74,94384 -75,94416 -76,94416 -77,94416 -78,94416 -79,94416 -80,94416 -81,94416 -82,94416 -83,94416 -84,94416 -85,94416 -86,94416 -87,94448 -88,94448 -89,94448 -90,94464 -91,97072 -92,97072 -93,97136 -94,97136 -95,97136 -96,97136 -97,97136 -98,97136 -99,97136 -100,97136 -101,97136 -102,97136 -103,97136 -104,97136 -105,97136 -106,97136 -107,97136 -108,97168 -109,97472 -110,97472 -111,97472 -112,97472 -113,97472 -114,97472 -115,98288 -116,98288 -117,98368 -118,97920 -119,97920 -120,96720 -121,97984 -122,97984 -123,88496 -124,88016 -125,88016 -126,78208 -127,77568 -128,77568 -129,77664 -130,77936 -131,77936 -132,77936 -133,77968 -134,77968 -135,77968 -136,78016 -137,78016 -138,78016 -139,78272 -140,78272 -141,78352 -142,78672 -143,78672 -144,78704 -145,79072 -146,79072 -147,79104 -148,79440 -149,79440 -150,79472 -151,81904 -152,81904 -153,81968 -154,81968 -155,81968 -156,81968 -157,82016 -158,82016 -159,82048 -160,82048 -161,82048 -162,82128 -163,82288 -164,82288 -165,82288 -166,82352 -167,82352 -168,82368 -169,82720 -170,82720 -171,82720 -172,83088 -173,83088 -174,83088 -175,83456 -176,83456 -177,83456 -178,83456 -179,83456 -180,83456 -181,85632 -182,85632 -183,85664 -184,86032 -185,86032 -186,86032 -187,86384 -188,86384 -189,86400 -190,86784 -191,86784 -192,86784 -193,86784 -194,86784 -195,86800 -196,87136 -197,87136 -198,87184 -199,87184 -200,87184 -201,87184 -202,87184 -203,87184 -204,87216 -205,87952 -206,87952 -207,87984 -208,88336 -209,88336 -210,88336 -211,91200 -212,91200 -213,91232 -214,91232 -215,91232 -216,91248 -217,91248 -218,91248 -219,91248 -220,91584 -221,91584 -222,91616 -223,91936 -224,91936 -225,91936 -226,92288 -227,92288 -228,92288 -229,92288 -230,92288 -231,92288 -232,92288 -233,92288 -234,92288 -235,92288 -236,92288 -237,92288 -238,92288 -239,92288 -240,92288 -241,93792 -242,93792 -243,93824 -244,94160 -245,94160 -246,94160 -247,94528 -248,94528 -249,94544 -250,94896 -251,94896 -252,94896 -253,95264 -254,95264 -255,95280 -256,95632 -257,95632 -258,95648 -259,96000 -260,96000 -261,96000 -262,96352 -263,96352 -264,96352 -265,96352 -266,96352 -267,96384 -268,96752 -269,96752 -270,96752 -271,97616 -272,97616 -273,97648 -274,97648 -275,97648 -276,97680 -277,98016 -278,98016 -279,98176 -280,98560 -281,98560 -282,98560 -283,98560 -284,98560 -285,98576 -286,98576 -287,98576 -288,98576 -289,98576 -290,98576 -291,98576 -292,98576 -293,98576 -294,98576 -295,98880 -296,98880 -297,98880 -298,99296 -299,99296 -300,99296 -301,101440 -302,101440 -303,101472 -304,101840 -305,101840 -306,101840 -307,102192 -308,102192 -309,102224 -310,102592 -311,102592 -312,102592 -313,102944 -314,102944 -315,102944 -316,103312 -317,103312 -318,103312 -319,103312 -320,103312 -321,103328 -322,103584 -323,103584 -324,103584 -325,103584 -326,103584 -327,103584 -328,103584 -329,103584 -330,103584 -331,105776 -332,105776 -333,105776 -334,105776 -335,105776 -336,105792 -337,105792 -338,105792 -339,105824 -340,105824 -341,105824 -342,105824 -343,105824 -344,105824 -345,105824 -346,105824 -347,105824 -348,105824 -349,105824 -350,105824 -351,105904 -352,106256 -353,106256 -354,106256 -355,106256 -356,106256 -357,106288 -358,106640 -359,106640 -360,106640 -361,107824 -362,107824 -363,107856 -364,108144 -365,108144 -366,108144 -367,108496 -368,108496 -369,108496 -370,108848 -371,108848 -372,108848 -373,109200 -374,109200 -375,109200 -376,109584 -377,109584 -378,109584 -379,109584 -380,109584 -381,109584 -382,109936 -383,109936 -384,109936 -385,110304 -386,110304 -387,110304 -388,110656 -389,110656 -390,110656 -391,113616 -392,113616 -393,113648 -394,113648 -395,113648 -396,113648 -397,113648 -398,113648 -399,113648 -400,113648 -401,113648 -402,113648 -403,113648 -404,113648 -405,113600 -406,113632 -407,113632 -408,113632 -409,113648 -410,113648 -411,113680 -412,113680 -413,113680 -414,113680 -415,113680 -416,113680 -417,113680 -418,113680 -419,113680 -420,113680 -421,115872 -422,115872 -423,115904 -424,115904 -425,115904 -426,115904 -427,116272 -428,116272 -429,116272 -430,116272 -431,116272 -432,116272 -433,116272 -434,116272 -435,116272 -436,116512 -437,116512 -438,116512 -439,116864 -440,116864 -441,116864 -442,117232 -443,117232 -444,117248 -445,117632 -446,117632 -447,117632 -448,117968 -449,117968 -450,117968 -451,120896 -452,120896 -453,120928 -454,120928 -455,120928 -456,120960 -457,120960 -458,120960 -459,120960 -460,121312 -461,121312 -462,121312 -463,121664 -464,121664 -465,121664 -466,121968 -467,121968 -468,122000 -469,122352 -470,122352 -471,122352 -472,122704 -473,122704 -474,122704 -475,123088 -476,123088 -477,123088 -478,123440 -479,123440 -480,123440 -481,125200 -482,125200 -483,125232 -484,125248 -485,125248 -486,125280 -487,125280 -488,125280 -489,125296 -490,125296 -491,125296 -492,125328 -493,125328 -494,125328 -495,125328 -496,125328 -497,125328 -498,125328 -499,125328 -500,125328 -501,125360 -502,125712 -503,125712 -504,125712 -505,126064 -506,126064 -507,126064 -508,126432 -509,126432 -510,126432 -511,129008 -512,129008 -513,129024 -514,129024 -515,129024 -516,125680 -517,126048 -518,126048 -519,123344 -520,122544 -521,122544 -522,114224 -523,114624 -524,114624 -525,106960 -526,106960 -527,106960 -528,106960 -529,107312 -530,107312 -531,107312 -532,107664 -533,107664 -534,106400 -535,106400 -536,106400 -537,106432 -538,106432 -539,106432 -540,106432 -541,108416 -542,108416 -543,108464 -544,108832 -545,108832 -546,108848 -547,109216 -548,109216 -549,109216 -550,109216 -551,109216 -552,109216 -553,105808 -554,105808 -555,105840 -556,105872 -557,105872 -558,105888 -559,105888 -560,105888 -561,105920 -562,105920 -563,105920 -564,105920 -565,106256 -566,106256 -567,103376 -568,103728 -569,103728 -570,103728 -571,106608 -572,106608 -573,106624 -574,106976 -575,106976 -576,106976 -577,107344 -578,107344 -579,107344 -580,107696 -581,107696 -582,107696 -583,107696 -584,107696 -585,107728 -586,107728 -587,107728 -588,107728 -589,107728 -590,107728 -591,107744 -592,108112 -593,108112 -594,108112 -595,108480 -596,108480 -597,108480 -598,108848 -599,108848 -600,108848 -601,110416 -602,110416 -603,110448 -604,110736 -605,110736 -606,110736 -607,110736 -608,110736 -609,110736 -610,110736 -611,110736 -612,110736 -613,111088 -614,111088 -615,111120 -616,111472 -617,111472 -618,111472 -619,111824 -620,111824 -621,111824 -622,112224 -623,112224 -624,112224 -625,112224 -626,112224 -627,112224 -628,112576 -629,112576 -630,112576 -631,114080 -632,114080 -633,114304 -634,114304 -635,114304 -636,114304 -637,114720 -638,114720 -639,114880 -640,114912 -641,114912 -642,114912 -643,115232 -644,115232 -645,115232 -646,115600 -647,115600 -648,115648 -649,115648 -650,115648 -651,115648 -652,115648 -653,115648 -654,115648 -655,115648 -656,115648 -657,115648 -658,115648 -659,115648 -660,115648 -661,118576 -662,118576 -663,118608 -664,118608 -665,118608 -666,118608 -667,118608 -668,118608 -669,118608 -670,118624 -671,118624 -672,118624 -673,118960 -674,118960 -675,118992 -676,119344 -677,119344 -678,119344 -679,119696 -680,119696 -681,119696 -682,120064 -683,120064 -684,120096 -685,120464 -686,120464 -687,120464 -688,120816 -689,120816 -690,120816 -691,121376 -692,121376 -693,121408 -694,121664 -695,121664 -696,121664 -697,122016 -698,122016 -699,122016 -700,122384 -701,122384 -702,122384 -703,122704 -704,122704 -705,122736 -706,123104 -707,123104 -708,123104 -709,123440 -710,123440 -711,123440 -712,123440 -713,123440 -714,123440 -715,123472 -716,123472 -717,123472 -718,123840 -719,123840 -720,123840 -721,126384 -722,126384 -723,126416 -724,126752 -725,126752 -726,126752 -727,127104 -728,127104 -729,127104 -730,127472 -731,127472 -732,127472 -733,127472 -734,127472 -735,127472 -736,127472 -737,127472 -738,127488 -739,127488 -740,127488 -741,127488 -742,127488 -743,127488 -744,127488 -745,127488 -746,127488 -747,127488 -748,127488 -749,127488 -750,127488 -751,128944 -752,128944 -753,128976 -754,128976 -755,128976 -756,129008 -757,129008 -758,129008 -759,129008 -760,129008 -761,129008 -762,129008 -763,129328 -764,129328 -765,129328 -766,129696 -767,129696 -768,129696 -769,130032 -770,130032 -771,130032 -772,130368 -773,130368 -774,130368 -775,130736 -776,130736 -777,130736 -778,131088 -779,131088 -780,131088 -781,133664 -782,133664 -783,133696 -784,134032 -785,134032 -786,134032 -787,134032 -788,134032 -789,134032 -790,134400 -791,134400 -792,134400 -793,134752 -794,134752 -795,134752 -796,135120 -797,135120 -798,135120 -799,135456 -800,135456 -801,135456 -802,135824 -803,135824 -804,135824 -805,136176 -806,136176 -807,136176 -808,136176 -809,136176 -810,136176 -811,137376 -812,137376 -813,137408 -814,137408 -815,137408 -816,137408 -817,137408 -818,137408 -819,137408 -820,137408 -821,137408 -822,137408 -823,137408 -824,137408 -825,137408 -826,137408 -827,137408 -828,137408 -829,137408 -830,137408 -831,137408 -832,137712 -833,137712 -834,137712 -835,138064 -836,138064 -837,138064 -838,138432 -839,138432 -840,138464 -841,140624 -842,140624 -843,140656 -844,141024 -845,141024 -846,141024 -847,141376 -848,141376 -849,141376 -850,141744 -851,141744 -852,141744 -853,142096 -854,142096 -855,142096 -856,142464 -857,142464 -858,142464 -859,142720 -860,142720 -861,142720 -862,143072 -863,143072 -864,143072 -865,143072 -866,143072 -867,143104 -868,143104 -869,143104 -870,143104 -871,143440 -872,143440 -873,143472 -874,143840 -875,143840 -876,143840 -877,144192 -878,144192 -879,144192 -880,144192 -881,144192 -882,144224 -883,144224 -884,144224 -885,144240 -886,144576 -887,144576 -888,144576 -889,144912 -890,144912 -891,144912 -892,144928 -893,144928 -894,144928 -895,145280 -896,145280 -897,145280 -898,145632 -899,145632 -900,145632 -901,147232 -902,147232 -903,147264 -904,147264 -905,147264 -906,147264 -907,147264 -908,147264 -909,147296 -910,147296 -911,147296 -912,147296 -913,147616 -914,147616 -915,147616 -916,147616 -917,147616 -918,147616 -919,147616 -920,147616 -921,147616 -922,147616 -923,147616 -924,147616 -925,147616 -926,147616 -927,147616 -928,147616 -929,147616 -930,147616 -931,149376 -932,149376 -933,149408 -934,149408 -935,149408 -936,149440 -937,149808 -938,149808 -939,149808 -940,150096 -941,150096 -942,150096 -943,150448 -944,150448 -945,150448 -946,150816 -947,150816 -948,150816 -949,150816 -950,150816 -951,150848 -952,151200 -953,151200 -954,151200 -955,151568 -956,151568 -957,151568 -958,151920 -959,151920 -960,151920 -961,154176 -962,154176 -963,154192 -964,154208 -965,154208 -966,154240 -967,154240 -968,154240 -969,154240 -970,154240 -971,154240 -972,154240 -973,154240 -974,154240 -975,154240 -976,154576 -977,154576 -978,154576 -979,154912 -980,154912 -981,154912 -982,155280 -983,155280 -984,155280 -985,155280 -986,155280 -987,155280 -988,155280 -989,155280 -990,155280 -991,157808 -992,157808 -993,157840 -994,158176 -995,158176 -996,158176 -997,158544 -998,158544 -999,158544 -1000,158544 -1001,158544 -1002,158544 -1003,158864 -1004,158864 -1005,158864 -1006,159216 -1007,159216 -1008,159216 -1009,159568 -1010,159568 -1011,159568 -1012,159920 -1013,159920 -1014,159920 -1015,160288 -1016,160288 -1017,160288 -1018,160640 -1019,160640 -1020,160640 -1021,162128 -1022,162128 -1023,162144 -1024,162144 -1025,162144 -1026,162144 -1027,162144 -1028,162144 -1029,162144 -1030,162496 -1031,162496 -1032,162496 -1033,162848 -1034,162848 -1035,162848 -1036,163216 -1037,163216 -1038,163216 -1039,163216 -1040,163216 -1041,163216 -1042,163216 -1043,163216 -1044,163248 -1045,163248 -1046,163248 -1047,163248 -1048,163248 -1049,163248 -1050,163248 -1051,164720 -1052,164720 -1053,164752 -1054,165088 -1055,165088 -1056,165088 -1057,165088 -1058,165088 -1059,165120 -1060,165120 -1061,165120 -1062,165152 -1063,165152 -1064,165152 -1065,165152 -1066,165152 -1067,165152 -1068,165152 -1069,165152 -1070,165152 -1071,165152 -1072,165456 -1073,165456 -1074,165456 -1075,165456 -1076,165456 -1077,165456 -1078,165456 -1079,165456 -1080,165456 -1081,166848 -1082,166848 -1083,166880 -1084,167232 -1085,167232 -1086,167232 -1087,167600 -1088,167600 -1089,167600 -1090,167600 -1091,167600 -1092,167632 -1093,167632 -1094,167632 -1095,160960 -1096,161312 -1097,161312 -1098,161312 -1099,161648 -1100,161648 -1101,161648 -1102,162032 -1103,162032 -1104,162032 -1105,162384 -1106,162384 -1107,162384 -1108,162752 -1109,162752 -1110,162752 -1111,165696 -1112,165696 -1113,165728 -1114,165728 -1115,165728 -1116,165728 -1117,165728 -1118,165728 -1119,165728 -1120,165728 -1121,165728 -1122,165728 -1123,165728 -1124,165728 -1125,165728 -1126,166080 -1127,166080 -1128,166080 -1129,166080 -1130,166080 -1131,166080 -1132,166416 -1133,166416 -1134,166416 -1135,166768 -1136,166768 -1137,166768 -1138,167136 -1139,167136 -1140,167136 -1141,169664 -1142,169664 -1143,169648 -1144,169664 -1145,169664 -1146,169680 -1147,170016 -1148,170016 -1149,169904 -1150,170256 -1151,170256 -1152,166912 -1153,163808 -1154,163808 -1155,158528 -1156,159552 -1157,159552 -1158,159552 -1159,159552 -1160,159552 -1161,159552 -1162,159552 -1163,159552 -1164,159584 -1165,159584 -1166,159584 -1167,159584 -1168,159584 -1169,159584 -1170,159584 -1171,160912 -1172,160912 -1173,160912 -1174,160912 -1175,160912 -1176,160912 -1177,160960 -1178,160960 -1179,160992 -1180,160992 -1181,160992 -1182,161072 -1183,161424 -1184,161424 -1185,161424 -1186,161776 -1187,161776 -1188,161776 -1189,162128 -1190,162128 -1191,162128 -1192,162208 -1193,162208 -1194,162272 -1195,162624 -1196,162624 -1197,162624 -1198,162992 -1199,162992 -1200,163008 -1201,165552 -1202,165552 -1203,165584 -1204,165584 -1205,165584 -1206,165616 -1207,165616 -1208,165616 -1209,165616 -1210,165616 -1211,165616 -1212,165616 -1213,165840 -1214,165840 -1215,165840 -1216,166224 -1217,166224 -1218,166224 -1219,166544 -1220,166544 -1221,166544 -1222,166544 -1223,166544 -1224,166544 -1225,166896 -1226,166896 -1227,166896 -1228,167264 -1229,167264 -1230,167264 -1231,168432 -1232,168432 -1233,168464 -1234,168736 -1235,168736 -1236,168736 -1237,168736 -1238,168736 -1239,168768 -1240,168768 -1241,168768 -1242,168768 -1243,168768 -1244,168768 -1245,168768 -1246,169120 -1247,169120 -1248,169120 -1249,169456 -1250,169456 -1251,169456 -1252,169840 -1253,169840 -1254,169840 -1255,169840 -1256,169840 -1257,169856 -1258,169856 -1259,169856 -1260,169856 -1261,171392 -1262,171392 -1263,171408 -1264,171776 -1265,171776 -1266,171776 -1267,172144 -1268,172144 -1269,172144 -1270,172160 -1271,172160 -1272,172192 -1273,172192 -1274,172192 -1275,172192 -1276,172336 -1277,172336 -1278,172336 -1279,172336 -1280,172336 -1281,140192 -1282,140192 -1283,140192 -1284,132144 -1285,132512 -1286,132512 -1287,128880 -1288,129248 -1289,129248 -1290,129248 -1291,132560 -1292,132560 -1293,132592 -1294,132592 -1295,132592 -1296,132624 -1297,129392 -1298,129312 -1299,126704 -1300,126704 -1301,126704 -1302,126704 -1303,127024 -1304,127024 -1305,127024 -1306,127392 -1307,127392 -1308,121152 -1309,121184 -1310,121184 -1311,117872 -1312,118224 -1313,118224 -1314,118224 -1315,118592 -1316,118592 -1317,118592 -1318,118592 -1319,118592 -1320,111872 -1321,111872 -1322,111872 -1323,111904 -1324,112176 -1325,112176 -1326,112176 -1327,112448 -1328,112448 -1329,112928 -1330,113696 -1331,113696 -1332,113936 -1333,114368 -1334,114368 -1335,114416 -1336,114848 -1337,114848 -1338,114864 -1339,115216 -1340,115216 -1341,115216 -1342,115216 -1343,115216 -1344,115264 -1345,115632 -1346,115632 -1347,115632 -1348,115632 -1349,115632 -1350,115632 -1351,117072 -1352,117072 -1353,117104 -1354,117456 -1355,117456 -1356,117456 -1357,117840 -1358,117840 -1359,117840 -1360,118192 -1361,118192 -1362,118192 -1363,118560 -1364,118560 -1365,118560 -1366,118912 -1367,118912 -1368,118944 -1369,119296 -1370,119296 -1371,119296 -1372,119296 -1373,119296 -1374,119328 -1375,119328 -1376,119328 -1377,119328 -1378,119328 -1379,119328 -1380,119360 -1381,122080 -1382,122080 -1383,122112 -1384,122112 -1385,122112 -1386,122112 -1387,122448 -1388,122448 -1389,122448 -1390,122800 -1391,122800 -1392,122800 -1393,123168 -1394,123168 -1395,123168 -1396,123520 -1397,123520 -1398,123520 -1399,123520 -1400,123520 -1401,123520 -1402,123904 -1403,123904 -1404,123904 -1405,124256 -1406,124256 -1407,124256 -1408,124256 -1409,124256 -1410,124272 -1411,125712 -1412,125712 -1413,125744 -1414,125744 -1415,125744 -1416,125744 -1417,126096 -1418,126096 -1419,126096 -1420,126448 -1421,126448 -1422,126448 -1423,126816 -1424,126816 -1425,126816 -1426,127168 -1427,127168 -1428,127168 -1429,127520 -1430,127520 -1431,127552 -1432,127904 -1433,127904 -1434,127920 -1435,128272 -1436,128272 -1437,128272 -1438,128624 -1439,128624 -1440,128624 -1441,131584 -1442,131584 -1443,131616 -1444,131632 -1445,131632 -1446,131632 -1447,131632 -1448,131632 -1449,131664 -1450,131664 -1451,131664 -1452,131664 -1453,131664 -1454,131664 -1455,131664 -1456,131664 -1457,131664 -1458,131664 -1459,131664 -1460,131664 -1461,131664 -1462,131664 -1463,131664 -1464,131664 -1465,131664 -1466,131664 -1467,131664 -1468,131664 -1469,131664 -1470,131664 -1471,133168 -1472,133168 -1473,130560 -1474,128144 -1475,128096 -1476,121616 -1477,121632 -1478,121632 -1479,121632 -1480,121792 -1481,121792 -1482,121792 -1483,121792 -1484,121792 -1485,121792 -1486,121792 -1487,121792 -1488,121792 -1489,121792 -1490,121792 -1491,121792 -1492,122320 -1493,122320 -1494,122336 -1495,122336 -1496,122336 -1497,122336 -1498,122336 -1499,122336 -1500,122336 -1501,123472 -1502,123472 -1503,123504 -1504,123840 -1505,123840 -1506,123840 -1507,124208 -1508,124208 -1509,124272 -1510,124624 -1511,124624 -1512,124624 -1513,124992 -1514,124992 -1515,124992 -1516,125344 -1517,125344 -1518,125344 -1519,125696 -1520,125696 -1521,125696 -1522,126064 -1523,126064 -1524,126064 -1525,126368 -1526,126368 -1527,126400 -1528,126400 -1529,126400 -1530,126400 -1531,127584 -1532,127584 -1533,127616 -1534,127904 -1535,127904 -1536,127904 -1537,128256 -1538,128256 -1539,128256 -1540,128448 -1541,128448 -1542,128448 -1543,128832 -1544,128832 -1545,128832 -1546,129200 -1547,129200 -1548,129200 -1549,129536 -1550,129536 -1551,129536 -1552,129904 -1553,129904 -1554,129920 -1555,130272 -1556,130272 -1557,130272 -1558,130656 -1559,130656 -1560,130688 -1561,133920 -1562,133920 -1563,133952 -1564,134304 -1565,134304 -1566,134320 -1567,134320 -1568,134320 -1569,134336 -1570,134336 -1571,134336 -1572,134336 -1573,134336 -1574,134336 -1575,134336 -1576,134336 -1577,134336 -1578,134336 -1579,134640 -1580,134640 -1581,134640 -1582,135008 -1583,135008 -1584,135008 -1585,135360 -1586,135360 -1587,135392 -1588,135760 -1589,135760 -1590,135760 -1591,137616 -1592,137616 -1593,137648 -1594,137952 -1595,137952 -1596,137952 -1597,137952 -1598,137952 -1599,137968 -1600,138336 -1601,138336 -1602,138336 -1603,138688 -1604,138688 -1605,138688 -1606,138720 -1607,138720 -1608,138720 -1609,138720 -1610,138720 -1611,138720 -1612,138720 -1613,138720 -1614,138720 -1615,138720 -1616,138720 -1617,138720 -1618,138720 -1619,138720 -1620,138720 -1621,140288 -1622,140288 -1623,140320 -1624,140672 -1625,140672 -1626,140672 -1627,141024 -1628,141024 -1629,141024 -1630,141392 -1631,141392 -1632,141392 -1633,141408 -1634,141408 -1635,141408 -1636,141408 -1637,141408 -1638,141424 -1639,141424 -1640,141424 -1641,141424 -1642,141424 -1643,141424 -1644,141456 -1645,141760 -1646,141760 -1647,141760 -1648,142128 -1649,142128 -1650,142128 -1651,144016 -1652,144016 -1653,144048 -1654,144352 -1655,144352 -1656,144352 -1657,144720 -1658,144720 -1659,144720 -1660,145072 -1661,145072 -1662,145072 -1663,145440 -1664,145440 -1665,145440 -1666,145440 -1667,145440 -1668,145472 -1669,145472 -1670,145472 -1671,145472 -1672,145472 -1673,145472 -1674,145472 -1675,145792 -1676,145792 -1677,140992 -1678,142032 -1679,142032 -1680,142032 -1681,144672 -1682,144672 -1683,144704 -1684,145040 -1685,145040 -1686,145040 -1687,145040 -1688,145040 -1689,145056 -1690,145056 -1691,145056 -1692,145056 -1693,145056 -1694,145056 -1695,145056 -1696,145056 -1697,145056 -1698,145056 -1699,145056 -1700,145056 -1701,145056 -1702,145056 -1703,145056 -1704,145056 -1705,145056 -1706,145056 -1707,145056 -1708,145408 -1709,145408 -1710,145408 -1711,148272 -1712,148272 -1713,148304 -1714,148656 -1715,148656 -1716,148656 -1717,149024 -1718,149024 -1719,149024 -1720,149376 -1721,149376 -1722,149376 -1723,149376 -1724,149376 -1725,149376 -1726,142000 -1727,142000 -1728,142000 -1729,142000 -1730,142000 -1731,142000 -1732,142000 -1733,142000 -1734,142000 -1735,142000 -1736,142000 -1737,142000 -1738,142000 -1739,142000 -1740,142000 -1741,142000 -1742,142000 -1743,142000 -1744,142000 -1745,142000 -1746,142000 -1747,142000 -1748,142000 -1749,142016 -1750,142016 -1751,142016 -1752,142080 -1753,142096 -1754,142096 -1755,142096 -1756,144064 -1757,144064 -1758,144144 -1759,144144 -1760,144144 -1761,144144 -1762,144176 -1763,144176 -1764,144176 -1765,144176 -1766,144176 -1767,144176 -1768,144176 -1769,135984 -1770,135984 -1771,135984 -1772,135984 -1773,135984 -1774,135984 -1775,135984 -1776,135984 -1777,135984 -1778,135984 -1779,135984 -1780,135984 -1781,135984 -1782,135984 -1783,135984 -1784,135984 -1785,135984 -1786,136656 -1787,136656 -1788,136672 -1789,137040 -1790,137040 -1791,137040 -1792,137408 -1793,137408 -1794,137408 -1795,137408 -1796,137408 -1797,137408 -1798,137568 -1799,137568 -1800,137568 -1801,137568 -1802,137568 -1803,137568 -1804,137568 -1805,137568 -1806,137568 -1807,137568 -1808,137568 -1809,137568 -1810,137648 -1811,137648 -1812,137648 -1813,137664 -1814,137664 -1815,137664 -1816,137664 -1817,137664 -1818,137664 -1819,137664 -1820,137664 -1821,137664 -1822,137664 -1823,137664 -1824,129296 -1825,129328 -1826,129328 -1827,129392 -1828,129392 -1829,129392 -1830,129392 -1831,129392 -1832,129392 -1833,129392 -1834,129392 -1835,129392 -1836,129392 -1837,129392 -1838,129392 -1839,129408 -1840,129424 -1841,129424 -1842,129440 -1843,129440 -1844,129440 -1845,129440 -1846,129440 -1847,129440 -1848,129440 -1849,129440 -1850,129440 -1851,129440 -1852,129552 -1853,129552 -1854,129712 -1855,129744 -1856,129744 -1857,129776 -1858,129776 -1859,129776 -1860,129776 -1861,129776 -1862,129776 -1863,129792 -1864,129792 -1865,129792 -1866,129792 -1867,129792 -1868,129792 -1869,129792 -1870,129792 -1871,129792 -1872,129792 -1873,129792 -1874,129792 -1875,129792 -1876,129792 -1877,129792 -1878,129792 -1879,129792 -1880,129792 -1881,129792 -1882,129792 -1883,129792 -1884,129792 -1885,129840 -1886,129840 -1887,129856 -1888,129856 -1889,129856 -1890,129856 -1891,129856 -1892,129856 -1893,129856 -1894,129856 -1895,129856 -1896,129856 -1897,129856 -1898,129856 -1899,129856 -1900,129856 -1901,129856 -1902,129856 -1903,129856 -1904,129856 -1905,129856 -1906,129856 -1907,129856 -1908,129856 -1909,129856 -1910,129856 -1911,129856 -1912,129856 -1913,129856 -1914,129856 -1915,129856 -1916,129856 -1917,129856 -1918,129856 -1919,129856 -1920,129856 -1921,129856 -1922,129856 -1923,129856 -1924,129856 -1925,129856 -1926,129856 -1927,129856 -1928,129856 -1929,129856 -1930,129856 -1931,129856 -1932,129856 -1933,129856 -1934,129856 -1935,129856 -1936,129856 -1937,129856 -1938,129856 -1939,129856 -1940,129856 -1941,129856 -1942,129856 -1943,129856 -1944,129856 -1945,129856 -1946,129856 -1947,129856 -1948,129856 -1949,129856 -1950,129856 -1951,129856 -1952,129856 -1953,129856 -1954,129856 -1955,129856 -1956,129856 -1957,129856 -1958,129856 -1959,129856 -1960,129856 -1961,129856 -1962,129856 -1963,129856 -1964,129856 -1965,129856 -1966,129856 -1967,129856 -1968,129856 -1969,129856 -1970,129856 -1971,129856 -1972,129856 -1973,129856 -1974,129856 -1975,129856 -1976,129856 -1977,129856 -1978,129856 -1979,129856 -1980,129856 -1981,129856 -1982,129856 -1983,129856 -1984,129856 -1985,129856 -1986,129856 -1987,129856 -1988,129856 -1989,129856 -1990,129856 -1991,129856 -1992,129856 -1993,129856 -1994,129856 -1995,129856 -1996,129856 -1997,129856 -1998,129856 -1999,129856 -2000,129856 -2001,129856 -2002,129856 -2003,129856 -2004,129856 -2005,129856 -2006,129856 -2007,129856 -2008,129856 -2009,129856 -2010,129856 -2011,129856 -2012,129856 -2013,129856 -2014,129856 -2015,129856 -2016,129856 -2017,129856 -2018,129856 -2019,129856 -2020,129856 -2021,129856 -2022,129856 -2023,129856 -2024,129856 -2025,129856 -2026,129856 -2027,129856 -2028,129856 -2029,129856 -2030,129856 -2031,129856 -2032,129856 -2033,129856 -2034,129808 -2035,129856 -2036,129856 -2037,129856 -2038,129856 -2039,129856 -2040,129856 -2041,129856 -2042,129856 -2043,129856 -2044,129856 -2045,129856 -2046,129856 -2047,129856 -2048,129856 -2049,129856 -2050,129856 -2051,129856 -2052,129856 -2053,129856 -2054,129856 -2055,129856 -2056,129856 -2057,129856 -2058,129856 -2059,129856 -2060,129856 -2061,129856 -2062,129856 -2063,129856 -2064,129856 -2065,129856 -2066,129856 -2067,129856 -2068,130064 -2069,130064 -2070,130064 -2071,130416 -2072,130416 -2073,130416 -2074,130768 -2075,130768 -2076,130784 -2077,131136 -2078,131152 -2079,131152 -2080,131520 -2081,131520 -2082,131552 -2083,131552 -2084,131552 -2085,131552 -2086,131552 -2087,131552 -2088,131552 -2089,131552 -2090,131552 -2091,131552 -2092,131552 -2093,131552 -2094,131552 -2095,131552 -2096,131552 -2097,131584 -2098,131584 -2099,131584 -2100,131584 -2101,131584 -2102,131584 -2103,131616 -2104,131616 -2105,131616 -2106,131616 -2107,131616 -2108,131616 -2109,131616 -2110,131648 -2111,131648 -2112,131648 -2113,131648 -2114,131648 -2115,131648 -2116,131952 -2117,131952 -2118,131984 -2119,131984 -2120,131984 -2121,131984 -2122,131984 -2123,131984 -2124,131984 -2125,131984 -2126,131984 -2127,131984 -2128,131984 -2129,131984 -2130,131984 -2131,131984 -2132,131984 -2133,131984 -2134,131984 -2135,131984 -2136,131984 -2137,131984 -2138,131984 -2139,131984 -2140,131984 -2141,131984 -2142,131984 -2143,131984 -2144,131984 -2145,131984 -2146,131984 -2147,131984 -2148,131984 -2149,131984 -2150,131984 -2151,131984 -2152,132240 -2153,132240 -2154,132256 -2155,132256 -2156,132256 -2157,132256 -2158,132256 -2159,132256 -2160,132256 -2161,132256 -2162,132256 -2163,132256 -2164,132256 -2165,132256 -2166,132256 -2167,132256 -2168,132256 -2169,132256 -2170,132256 -2171,132256 -2172,132256 -2173,132624 -2174,132624 -2175,132624 -2176,132624 -2177,132624 -2178,132624 -2179,132624 -2180,132624 -2181,132624 -2182,132624 -2183,132624 -2184,132624 -2185,132624 -2186,132624 -2187,132656 -2188,132656 -2189,132656 -2190,132656 -2191,132656 -2192,132656 -2193,132656 -2194,132656 -2195,132656 -2196,132656 -2197,132656 -2198,132656 -2199,132656 -2200,132656 -2201,132656 -2202,132656 -2203,132656 -2204,132656 -2205,132656 -2206,132656 -2207,132656 -2208,132656 -2209,132656 -2210,132656 -2211,132656 -2212,132656 -2213,132656 -2214,132656 -2215,132656 -2216,132656 -2217,132656 -2218,132656 -2219,132656 -2220,132656 -2221,132992 -2222,132992 -2223,132992 -2224,133344 -2225,133344 -2226,133344 -2227,133696 -2228,133696 -2229,133696 -2230,133696 -2231,133696 -2232,133696 -2233,133696 -2234,133696 -2235,133696 -2236,133696 -2237,133696 -2238,133696 -2239,133696 -2240,133696 -2241,133696 -2242,133696 -2243,133696 -2244,133696 -2245,133696 -2246,133696 -2247,133728 -2248,133728 -2249,133728 -2250,133728 -2251,133728 -2252,133728 -2253,133728 -2254,133728 -2255,133728 -2256,133728 -2257,133728 -2258,133728 -2259,133760 -2260,134080 -2261,134080 -2262,134080 -2263,134080 -2264,134080 -2265,134080 -2266,135616 -2267,135616 -2268,135648 -2269,135952 -2270,135952 -2271,135952 -2272,136304 -2273,136304 -2274,136304 -2275,136672 -2276,136672 -2277,136672 -2278,136672 -2279,136672 -2280,136672 -2281,136672 -2282,136672 -2283,136672 -2284,136672 -2285,136672 -2286,136672 -2287,136672 -2288,136672 -2289,136672 -2290,136672 -2291,136672 -2292,136672 -2293,136672 -2294,136672 -2295,136672 -2296,137216 -2297,137216 -2298,137216 -2299,137216 -2300,137216 -2301,137216 -2302,137216 -2303,137216 -2304,137232 -2305,137232 -2306,137232 -2307,137232 -2308,137232 -2309,137232 -2310,137232 -2311,137232 -2312,137232 -2313,137232 -2314,137232 -2315,137232 -2316,137232 -2317,137232 -2318,137232 -2319,137232 -2320,137232 -2321,137232 -2322,137232 -2323,137232 -2324,137232 -2325,137232 -2326,137232 -2327,137232 -2328,137232 -2329,137232 -2330,137232 -2331,137232 -2332,137232 -2333,137232 -2334,137232 -2335,137232 -2336,137232 -2337,137232 -2338,137232 -2339,137232 -2340,137232 -2341,137232 -2342,137232 -2343,137232 -2344,137232 -2345,137232 -2346,137232 -2347,137232 -2348,137232 -2349,137232 -2350,137232 -2351,137232 -2352,137232 -2353,137232 -2354,137232 -2355,137232 -2356,139728 -2357,139728 -2358,139760 -2359,140128 -2360,140128 -2361,140128 -2362,140480 -2363,140480 -2364,140480 -2365,140848 -2366,140848 -2367,140848 -2368,141200 -2369,141200 -2370,141200 -2371,141216 -2372,141216 -2373,141216 -2374,141216 -2375,141216 -2376,141216 -2377,141216 -2378,141216 -2379,141216 -2380,141216 -2381,141216 -2382,141216 -2383,141216 -2384,141216 -2385,141216 -2386,141216 -2387,141216 -2388,141216 -2389,141216 -2390,141216 -2391,141216 -2392,141216 -2393,141216 -2394,141216 -2395,141216 -2396,141216 -2397,141216 -2398,141216 -2399,141216 -2400,141216 -2401,141216 -2402,141216 -2403,141216 -2404,141216 -2405,141216 -2406,141216 -2407,141216 -2408,141216 -2409,141216 -2410,141216 -2411,141216 -2412,141216 -2413,141216 -2414,141216 -2415,141216 -2416,141616 -2417,141616 -2418,141648 -2419,142000 -2420,142000 -2421,142000 -2422,142368 -2423,142368 -2424,142368 -2425,142368 -2426,142368 -2427,142368 -2428,142368 -2429,142368 -2430,141072 -2431,141440 -2432,141440 -2433,141440 -2434,141776 -2435,141776 -2436,141776 -2437,142144 -2438,142144 -2439,141584 -2440,141936 -2441,141936 -2442,141936 -2443,141952 -2444,141952 -2445,141968 -2446,144112 -2447,144112 -2448,144128 -2449,144496 -2450,144496 -2451,144496 -2452,144864 -2453,144864 -2454,144864 -2455,144864 -2456,144864 -2457,144864 -2458,144864 -2459,144864 -2460,144864 -2461,145232 -2462,145232 -2463,145232 -2464,145568 -2465,145568 -2466,145568 -2467,145568 -2468,145568 -2469,145568 -2470,145936 -2471,145936 -2472,145936 -2473,146272 -2474,146272 -2475,146304 -2476,147856 -2477,147856 -2478,147872 -2479,148208 -2480,148208 -2481,148208 -2482,148560 -2483,148560 -2484,148560 -2485,148912 -2486,148912 -2487,148912 -2488,149280 -2489,149280 -2490,149280 -2491,149632 -2492,149632 -2493,149632 -2494,149984 -2495,149984 -2496,149984 -2497,149984 -2498,149984 -2499,149984 -2500,149984 -2501,149984 -2502,150016 -2503,150016 -2504,150016 -2505,150048 -2506,151552 -2507,151552 -2508,151568 -2509,151872 -2510,151872 -2511,151904 -2512,151904 -2513,151904 -2514,151904 -2515,151904 -2516,151904 -2517,151904 -2518,151904 -2519,151904 -2520,151904 -2521,151904 -2522,151904 -2523,151904 -2524,151904 -2525,151904 -2526,151904 -2527,151904 -2528,151904 -2529,151904 -2530,152240 -2531,152240 -2532,152240 -2533,152608 -2534,152608 -2535,152608 -2536,155536 -2537,155536 -2538,155568 -2539,155920 -2540,155920 -2541,155920 -2542,156272 -2543,156272 -2544,156272 -2545,156640 -2546,156640 -2547,156640 -2548,156992 -2549,156992 -2550,157024 -2551,157392 -2552,157392 -2553,157392 -2554,157392 -2555,157392 -2556,157392 -2557,157392 -2558,157392 -2559,157392 -2560,157392 -2561,157392 -2562,157392 -2563,157392 -2564,157392 -2565,157392 -2566,157392 -2567,157392 -2568,157392 -2569,157392 -2570,157392 -2571,157392 -2572,157408 -2573,157408 -2574,157424 -2575,157424 -2576,157424 -2577,157424 -2578,157424 -2579,157424 -2580,157424 -2581,157424 -2582,157424 -2583,157424 -2584,157424 -2585,157424 -2586,157424 -2587,157424 -2588,157424 -2589,157376 -2590,157376 -2591,157376 -2592,157376 -2593,157376 -2594,157376 -2595,157376 -2596,159120 -2597,159120 -2598,159152 -2599,159168 -2600,159168 -2601,159168 -2602,159168 -2603,159168 -2604,159168 -2605,159168 -2606,159168 -2607,159168 -2608,159168 -2609,159168 -2610,159168 -2611,159600 -2612,159600 -2613,159728 -2614,159744 -2615,159744 -2616,159712 -2617,160048 -2618,160048 -2619,160048 -2620,160400 -2621,160400 -2622,160400 -2623,160768 -2624,160768 -2625,160768 -2626,162352 -2627,162352 -2628,162368 -2629,162672 -2630,162672 -2631,162672 -2632,162992 -2633,162992 -2634,162992 -2635,162992 -2636,162992 -2637,163008 -2638,163024 -2639,163024 -2640,163024 -2641,163360 -2642,163360 -2643,163392 -2644,163728 -2645,163728 -2646,163728 -2647,164080 -2648,164080 -2649,164080 -2650,164448 -2651,164448 -2652,164448 -2653,164800 -2654,164800 -2655,164800 -2656,166288 -2657,166288 -2658,166288 -2659,166288 -2660,166288 -2661,166288 -2662,166288 -2663,166288 -2664,166288 -2665,166608 -2666,166608 -2667,166608 -2668,166608 -2669,166608 -2670,166608 -2671,166608 -2672,166608 -2673,166608 -2674,166608 -2675,166608 -2676,166608 -2677,166608 -2678,166608 -2679,166624 -2680,166992 -2681,166992 -2682,166992 -2683,167360 -2684,167360 -2685,167360 -2686,169936 -2687,169936 -2688,169968 -2689,170304 -2690,170304 -2691,170304 -2692,170672 -2693,170672 -2694,170672 -2695,170672 -2696,170672 -2697,170672 -2698,170672 -2699,170672 -2700,170672 -2701,170672 -2702,170672 -2703,170672 -2704,170672 -2705,170672 -2706,170672 -2707,170672 -2708,170672 -2709,170672 -2710,170672 -2711,170672 -2712,170672 -2713,171008 -2714,171008 -2715,171008 -2716,172848 -2717,172848 -2718,172880 -2719,173200 -2720,173200 -2721,173200 -2722,173568 -2723,173568 -2724,173568 -2725,173568 -2726,173568 -2727,173600 -2728,173600 -2729,173600 -2730,173600 -2731,173952 -2732,173952 -2733,173952 -2734,173952 -2735,173952 -2736,173952 -2737,173952 -2738,173952 -2739,173952 -2740,173952 -2741,173952 -2742,173952 -2743,173952 -2744,173952 -2745,173952 -2746,175776 -2747,175776 -2748,175824 -2749,175824 -2750,175824 -2751,175856 -2752,176160 -2753,176160 -2754,176192 -2755,176560 -2756,176560 -2757,176560 -2758,176912 -2759,176912 -2760,176912 -2761,176912 -2762,176912 -2763,176944 -2764,176944 -2765,176944 -2766,176944 -2767,176944 -2768,176944 -2769,176944 -2770,176944 -2771,176944 -2772,176976 -2773,177280 -2774,177280 -2775,177280 -2776,179824 -2777,179824 -2778,179856 -2779,180192 -2780,180192 -2781,180032 -2782,180384 -2783,180384 -2784,180384 -2785,180752 -2786,180752 -2787,180752 -2788,180752 -2789,180752 -2790,180752 -2791,180752 -2792,180752 -2793,180752 -2794,180752 -2795,180752 -2796,180784 -2797,180944 -2798,180944 -2799,180944 -2800,180944 -2801,180944 -2802,180944 -2803,180944 -2804,180944 -2805,180944 -2806,183792 -2807,183792 -2808,183824 -2809,184192 -2810,184192 -2811,184192 -2812,184544 -2813,184544 -2814,184544 -2815,184912 -2816,184912 -2817,184912 -2818,184912 -2819,184912 -2820,184912 -2821,184912 -2822,184912 -2823,184912 -2824,185264 -2825,185264 -2826,185264 -2827,185632 -2828,185632 -2829,185632 -2830,185632 -2831,185632 -2832,185632 -2833,185632 -2834,185632 -2835,185632 -2836,188192 -2837,188192 -2838,188256 -2839,188256 -2840,188256 -2841,187280 -2842,187280 -2843,187280 -2844,187280 -2845,187280 -2846,187280 -2847,187280 -2848,187280 -2849,187280 -2850,187280 -2851,187600 -2852,187600 -2853,187600 -2854,187936 -2855,187936 -2856,187936 -2857,188256 -2858,188256 -2859,188256 -2860,188272 -2861,188272 -2862,188288 -2863,188288 -2864,188288 -2865,188288 -2866,188768 -2867,188768 -2868,188800 -2869,189120 -2870,189120 -2871,189120 -2872,189488 -2873,189488 -2874,189488 -2875,189488 -2876,189488 -2877,189488 -2878,189840 -2879,189840 -2880,189840 -2881,190208 -2882,190208 -2883,190208 -2884,190544 -2885,190544 -2886,190544 -2887,190912 -2888,190912 -2889,190912 -2890,191168 -2891,191168 -2892,191168 -2893,191520 -2894,191520 -2895,191520 -2896,194864 -2897,194864 -2898,194880 -2899,194880 -2900,194880 -2901,194880 -2902,194880 -2903,194880 -2904,194880 -2905,194880 -2906,194880 -2907,194880 -2908,195200 -2909,195200 -2910,195200 -2911,195568 -2912,195568 -2913,195568 -2914,195904 -2915,195904 -2916,195904 -2917,196272 -2918,196272 -2919,196272 -2920,196560 -2921,196560 -2922,196560 -2923,196560 -2924,196560 -2925,196560 -2926,199072 -2927,199072 -2928,199104 -2929,199456 -2930,199456 -2931,199456 -2932,199488 -2933,199488 -2934,199520 -2935,199888 -2936,199888 -2937,199888 -2938,200240 -2939,200240 -2940,200240 -2941,200608 -2942,200608 -2943,200608 -2944,200944 -2945,200944 -2946,200944 -2947,201312 -2948,201312 -2949,201312 -2950,201680 -2951,201680 -2952,201680 -2953,201680 -2954,201680 -2955,201712 -2956,202800 -2957,202800 -2958,202832 -2959,203200 -2960,203200 -2961,203200 -2962,203552 -2963,203552 -2964,203568 -2965,203568 -2966,203568 -2967,203600 -2968,203600 -2969,203600 -2970,198560 -2971,198576 -2972,198576 -2973,198576 -2974,198576 -2975,198576 -2976,198576 -2977,198576 -2978,198576 -2979,198576 -2980,198576 -2981,198576 -2982,198576 -2983,198592 -2984,198592 -2985,198592 -2986,201488 -2987,201488 -2988,201504 -2989,201856 -2990,201856 -2991,199968 -2992,199984 -2993,199984 -2994,200000 -2995,200048 -2996,200048 -2997,200048 -2998,200048 -2999,200048 -3000,200128 -3001,200496 -3002,135552