nemo-py 0.2.0__tar.gz → 0.2.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {nemo_py-0.2.0 → nemo_py-0.2.2}/.github/workflows/release.yml +1 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/.gitignore +1 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/CMakeLists.txt +1 -1
- {nemo_py-0.2.0 → nemo_py-0.2.2}/HOW_IT_WORKS.md +12 -1
- {nemo_py-0.2.0 → nemo_py-0.2.2}/PKG-INFO +17 -17
- {nemo_py-0.2.0 → nemo_py-0.2.2}/README.md +16 -16
- {nemo_py-0.2.0 → nemo_py-0.2.2}/include/nemo/runtime/memory_resource.hpp +17 -19
- {nemo_py-0.2.0 → nemo_py-0.2.2}/pyproject.toml +4 -1
- {nemo_py-0.2.0 → nemo_py-0.2.2}/python/src/nemo/__init__.py +1 -1
- {nemo_py-0.2.0 → nemo_py-0.2.2}/python/src/nemo/syncconnector.py +13 -5
- {nemo_py-0.2.0 → nemo_py-0.2.2}/src/api/api_internal.hpp +47 -5
- {nemo_py-0.2.0 → nemo_py-0.2.2}/src/api/connection.cpp +329 -35
- {nemo_py-0.2.0 → nemo_py-0.2.2}/src/api/database.cpp +1 -1
- {nemo_py-0.2.0 → nemo_py-0.2.2}/src/api/query_engine.hpp +1120 -223
- {nemo_py-0.2.0 → nemo_py-0.2.2}/src/core/version.cpp +1 -1
- {nemo_py-0.2.0 → nemo_py-0.2.2}/src/python/module.cpp +199 -189
- {nemo_py-0.2.0 → nemo_py-0.2.2}/CMakePresets.json +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/LICENSE +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/benchmarks/README.md +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/benchmarks/benchmark_speedguard.py +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/benchmarks/benchmark_suite.py +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/ci/fuzz_runner.py +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/ci/run_sanitizers.sh +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/cmake/NemoOptions.cmake +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/docs/asyncconnector.md +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/docs/benchmarks.md +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/docs/connect.md +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/docs/datatypes.md +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/docs/logging.md +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/docs/nemo_functions.md +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/docs/savepoints.md +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/docs/sql.md +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/docs/sql_features.md +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/docs/sql_functions.md +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/docs/sql_parameters.md +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/docs/syncconnector.md +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/docs/transactions.md +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/example/README.md +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/example/example_1.py +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/example/example_10.py +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/example/example_11.py +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/example/example_12.py +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/example/example_13.py +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/example/example_14.py +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/example/example_15.py +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/example/example_16.py +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/example/example_17.py +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/example/example_18.py +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/example/example_19.py +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/example/example_2.py +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/example/example_20.py +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/example/example_21.py +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/example/example_22.py +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/example/example_23.py +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/example/example_24.py +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/example/example_25.py +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/example/example_26.py +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/example/example_27.py +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/example/example_28.py +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/example/example_29.py +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/example/example_3.py +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/example/example_30.py +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/example/example_31.py +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/example/example_32.py +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/example/example_33.py +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/example/example_34.py +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/example/example_35.py +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/example/example_36.py +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/example/example_37.py +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/example/example_38.py +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/example/example_39.py +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/example/example_4.py +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/example/example_40.py +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/example/example_41.py +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/example/example_42.py +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/example/example_43.py +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/example/example_44.py +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/example/example_45.py +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/example/example_46.py +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/example/example_47.py +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/example/example_48.py +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/example/example_49.py +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/example/example_5.py +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/example/example_50.py +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/example/example_51.py +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/example/example_52.py +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/example/example_53.py +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/example/example_54.py +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/example/example_55.py +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/example/example_56.py +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/example/example_6.py +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/example/example_7.py +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/example/example_8.py +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/example/example_9.py +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/examples/CMakeLists.txt +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/examples/basic.cpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/include/nemo/api/connection.hpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/include/nemo/api/database.hpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/include/nemo/api/prepared_statement.hpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/include/nemo/api/result.hpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/include/nemo/api/row.hpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/include/nemo/api/transaction.hpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/include/nemo/catalog/catalog.hpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/include/nemo/catalog/catalog_id.hpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/include/nemo/catalog/catalog_iterator.hpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/include/nemo/catalog/catalog_serializer.hpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/include/nemo/catalog/check_constraint.hpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/include/nemo/catalog/column.hpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/include/nemo/catalog/constraint.hpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/include/nemo/catalog/default_value.hpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/include/nemo/catalog/foreign_key.hpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/include/nemo/catalog/index_metadata.hpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/include/nemo/catalog/primary_key.hpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/include/nemo/catalog/schema.hpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/include/nemo/catalog/table_metadata.hpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/include/nemo/catalog/table_schema.hpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/include/nemo/catalog/unique_constraint.hpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/include/nemo/concurrency/lock_handle.hpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/include/nemo/concurrency/lock_manager.hpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/include/nemo/concurrency/lock_mode.hpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/include/nemo/concurrency/lock_resource.hpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/include/nemo/concurrency/page_latch.hpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/include/nemo/concurrency/wait_for_graph.hpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/include/nemo/core/config.hpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/include/nemo/core/constants.hpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/include/nemo/core/error.hpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/include/nemo/core/ids.hpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/include/nemo/core/result.hpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/include/nemo/core/status.hpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/include/nemo/core/types.hpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/include/nemo/core/version.hpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/include/nemo/execution/binder/binder.hpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/include/nemo/execution/binder/bound_expression.hpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/include/nemo/execution/binder/bound_statement.hpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/include/nemo/execution/binder/name_resolver.hpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/include/nemo/execution/planner/logical_operator.hpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/include/nemo/execution/planner/planner.hpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/include/nemo/index/bplus_tree.hpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/include/nemo/index/bplus_tree_internal.hpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/include/nemo/index/bplus_tree_iterator.hpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/include/nemo/index/bplus_tree_leaf.hpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/include/nemo/index/bplus_tree_node.hpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/include/nemo/index/bplus_tree_page.hpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/include/nemo/index/index_comparator.hpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/include/nemo/index/index_entry.hpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/include/nemo/index/index_key.hpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/include/nemo/index/index_metadata.hpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/include/nemo/index/index_stats.hpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/include/nemo/logging/logger.hpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/include/nemo/nemo.hpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/include/nemo/runtime/cancellation.hpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/include/nemo/runtime/connection.hpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/include/nemo/runtime/connection_lease.hpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/include/nemo/runtime/connection_manager.hpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/include/nemo/runtime/connection_pool.hpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/include/nemo/runtime/query_registry.hpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/include/nemo/runtime/resource_pool.hpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/include/nemo/runtime/runtime_metrics.hpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/include/nemo/runtime/session.hpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/include/nemo/runtime/shutdown.hpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/include/nemo/runtime/task.hpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/include/nemo/runtime/worker.hpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/include/nemo/runtime/worker_pool.hpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/include/nemo/sql/ast/ast_formatter.hpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/include/nemo/sql/ast/ast_node.hpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/include/nemo/sql/ast/ast_visitor.hpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/include/nemo/sql/ast/data_definition.hpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/include/nemo/sql/ast/expression.hpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/include/nemo/sql/ast/expressions.hpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/include/nemo/sql/ast/insert.hpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/include/nemo/sql/ast/literals.hpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/include/nemo/sql/ast/select.hpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/include/nemo/sql/ast/statement.hpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/include/nemo/sql/lexer.hpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/include/nemo/sql/parser.hpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/include/nemo/sql/source_location.hpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/include/nemo/sql/sql_error.hpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/include/nemo/sql/token.hpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/include/nemo/sql/token_type.hpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/include/nemo/storage/buffer_frame.hpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/include/nemo/storage/buffer_pool.hpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/include/nemo/storage/checksum.hpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/include/nemo/storage/clock_replacer.hpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/include/nemo/storage/database_header.hpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/include/nemo/storage/disk_manager.hpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/include/nemo/storage/file_manager.hpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/include/nemo/storage/free_page_manager.hpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/include/nemo/storage/page.hpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/include/nemo/storage/page_handle.hpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/include/nemo/storage/page_header.hpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/include/nemo/storage/record.hpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/include/nemo/storage/record_deserializer.hpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/include/nemo/storage/record_header.hpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/include/nemo/storage/record_id.hpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/include/nemo/storage/record_serializer.hpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/include/nemo/storage/record_view.hpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/include/nemo/storage/replacer.hpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/include/nemo/storage/serialization.hpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/include/nemo/storage/slot.hpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/include/nemo/storage/slot_directory.hpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/include/nemo/storage/storage_constants.hpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/include/nemo/storage/table_heap.hpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/include/nemo/storage/table_page.hpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/include/nemo/storage/tuple_layout.hpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/include/nemo/transaction/mvcc_header.hpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/include/nemo/transaction/snapshot.hpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/include/nemo/transaction/transaction.hpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/include/nemo/transaction/transaction_context.hpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/include/nemo/transaction/transaction_id.hpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/include/nemo/transaction/transaction_manager.hpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/include/nemo/transaction/transaction_registry.hpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/include/nemo/transaction/transaction_state.hpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/include/nemo/transaction/undo_record.hpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/include/nemo/transaction/visibility.hpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/include/nemo/types/array.hpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/include/nemo/types/decimal.hpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/include/nemo/types/dict.hpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/include/nemo/types/json.hpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/include/nemo/types/temporal.hpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/include/nemo/types/type_cast.hpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/include/nemo/types/type_comparator.hpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/include/nemo/types/type_hasher.hpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/include/nemo/types/type_id.hpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/include/nemo/types/type_info.hpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/include/nemo/types/type_registry.hpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/include/nemo/types/type_serializer.hpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/include/nemo/types/uuid.hpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/include/nemo/types/value.hpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/include/nemo/types/value_view.hpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/include/nemo/wal/checkpoint_manager.hpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/include/nemo/wal/dirty_page_table.hpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/include/nemo/wal/log_buffer.hpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/include/nemo/wal/log_reader.hpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/include/nemo/wal/log_record.hpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/include/nemo/wal/log_record_type.hpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/include/nemo/wal/lsn.hpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/include/nemo/wal/recovery_manager.hpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/include/nemo/wal/recovery_state.hpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/include/nemo/wal/transaction_table.hpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/include/nemo/wal/wal_error.hpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/include/nemo/wal/wal_manager.hpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/include/nemo/wal/wal_segment.hpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/python/LICENSE +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/python/src/nemo/asyncconnector.py +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/python/src/nemo/database.py +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/python/src/nemo/errors.py +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/python/src/nemo/logging.py +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/src/CMakeLists.txt +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/src/api/function_registry.hpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/src/api/prepared_statement.cpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/src/api/result.cpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/src/api/row.cpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/src/api/transaction.cpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/src/catalog/catalog.cpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/src/catalog/catalog_serializer.cpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/src/catalog/column.cpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/src/catalog/constraint.cpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/src/catalog/default_value.cpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/src/catalog/index_metadata.cpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/src/catalog/schema.cpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/src/catalog/table_metadata.cpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/src/catalog/table_schema.cpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/src/concurrency/lock_manager.cpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/src/concurrency/wait_for_graph.cpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/src/core/config.cpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/src/core/error.cpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/src/core/status.cpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/src/execution/binder/binder.cpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/src/execution/planner/planner.cpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/src/index/bplus_tree.cpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/src/index/bplus_tree_internal.cpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/src/index/bplus_tree_iterator.cpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/src/index/bplus_tree_leaf.cpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/src/index/bplus_tree_node.cpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/src/index/bplus_tree_page.cpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/src/index/index_comparator.cpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/src/index/index_entry.cpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/src/index/index_key.cpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/src/index/index_metadata.cpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/src/index/index_stats.cpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/src/logging/logger.cpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/src/runtime/connection_manager.cpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/src/runtime/connection_pool.cpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/src/runtime/query_registry.cpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/src/runtime/worker.cpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/src/runtime/worker_pool.cpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/src/sql/ast/ast_formatter.cpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/src/sql/ast/expression.cpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/src/sql/ast/expressions.cpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/src/sql/ast/literals.cpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/src/sql/ast/select.cpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/src/sql/ast/statement.cpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/src/sql/lexer.cpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/src/sql/parser.cpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/src/sql/source_location.cpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/src/sql/sql_error.cpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/src/sql/token.cpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/src/sql/token_type.cpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/src/storage/buffer_frame.cpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/src/storage/buffer_pool.cpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/src/storage/checksum.cpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/src/storage/clock_replacer.cpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/src/storage/database_header.cpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/src/storage/disk_manager.cpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/src/storage/file_manager.cpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/src/storage/free_page_manager.cpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/src/storage/page.cpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/src/storage/page_handle.cpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/src/storage/page_header.cpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/src/storage/record.cpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/src/storage/record_deserializer.cpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/src/storage/record_header.cpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/src/storage/record_id.cpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/src/storage/record_serializer.cpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/src/storage/record_view.cpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/src/storage/slot.cpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/src/storage/slot_directory.cpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/src/storage/table_heap.cpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/src/storage/table_page.cpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/src/storage/tuple_layout.cpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/src/transaction/snapshot.cpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/src/transaction/transaction.cpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/src/transaction/transaction_manager.cpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/src/transaction/transaction_registry.cpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/src/transaction/visibility.cpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/src/types/array.cpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/src/types/decimal.cpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/src/types/dict.cpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/src/types/json.cpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/src/types/temporal.cpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/src/types/type_cast.cpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/src/types/type_comparator.cpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/src/types/type_hasher.cpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/src/types/type_info.cpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/src/types/type_registry.cpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/src/types/type_serializer.cpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/src/types/uuid.cpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/src/types/value.cpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/src/types/value_view.cpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/src/wal/checkpoint_manager.cpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/src/wal/log_reader.cpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/src/wal/log_record.cpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/src/wal/recovery_manager.cpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/src/wal/wal_manager.cpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/src/wal/wal_segment.cpp +0 -0
- {nemo_py-0.2.0 → nemo_py-0.2.2}/tools/generate_dataset.py +0 -0
|
@@ -412,7 +412,18 @@ conn.extract_columnar("financial_accounts", ["id", "username", "balance"])
|
|
|
412
412
|
```
|
|
413
413
|
- Completely bypasses row-oriented Python tuple wrapping.
|
|
414
414
|
- Extracts columns directly as homogeneous contiguous Python arrays/lists.
|
|
415
|
-
- **Benchmark Speedup**: **
|
|
415
|
+
- **Benchmark Speedup**: **681 ops/sec in Nemo vs 146 ops/sec in SQLite (4.66x faster)**.
|
|
416
|
+
|
|
417
|
+
### v0.2.0 Query Plan Caching & Zero-Allocation Fast Paths
|
|
418
|
+
Nemo v0.2.0 introduces multi-tier query plan compilation caches that bypass lexical scanning, AST tokenization, and projection parsing on repetitive statements:
|
|
419
|
+
- `s_join_plan_cache`: Caches parsed inner/left join schemas, projection lists, and join key offsets under shared read locks.
|
|
420
|
+
- `s_agg_plan_cache`: Caches column indexes and aggregation accumulators for instant SIMD execution.
|
|
421
|
+
- `s_window_plan_cache`: Caches window ordering columns, sort directions, and partition boundaries.
|
|
422
|
+
- `s_extraction_plan_cache`: Pre-compiles scalar expressions (`JSON_EXTRACT`, math functions, string operations) into zero-dispatch loops.
|
|
423
|
+
- `s_groupby_plan_cache` & `s_setop_plan_cache`: Caches grouping signatures and compound set-operation plans (`UNION` / `UNION ALL`).
|
|
424
|
+
- **Zero-Allocation DISTINCT**: Inspects projected values directly in-place before constructing row objects, delivering **24,089 QPS (12.58x faster than SQLite)**.
|
|
425
|
+
- **Allocation-Free Predicate Evaluation**: Inlined `std::string_view` pattern comparisons and cached column index lookups (`col_idx_cache`) eliminate heap churn on filtered table scans.
|
|
426
|
+
- **Full Slotted-Page Record Capacity**: Arbitrary sampling limits removed; tables scale dynamically across 4KB slotted pages with zero row caps.
|
|
416
427
|
|
|
417
428
|
---
|
|
418
429
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.2
|
|
2
2
|
Name: nemo-py
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.2
|
|
4
4
|
Summary: High-performance embedded relational database written in C++20 with a unified Sync/Async Python API.
|
|
5
5
|
Keywords: database,embedded,sql,relational,asyncio,sqlite-alternative,nemo
|
|
6
6
|
Author: Pravanjan Roy
|
|
@@ -319,22 +319,22 @@ Nemo was benchmarked against SQLite 3 (configured with `PRAGMA journal_mode = WA
|
|
|
319
319
|
|
|
320
320
|
| Benchmark Dimension / Activity | Nemo (.nm) | SQLite (.db) (WAL Mode) | Speedup / Advantage |
|
|
321
321
|
| :--- | :--- | :--- | :--- |
|
|
322
|
-
| **
|
|
323
|
-
| **
|
|
324
|
-
| **
|
|
325
|
-
| **
|
|
326
|
-
| **
|
|
327
|
-
| **
|
|
328
|
-
| **
|
|
329
|
-
| **
|
|
330
|
-
| **
|
|
331
|
-
| **
|
|
332
|
-
| **
|
|
333
|
-
| **
|
|
334
|
-
| **All-At-Once Concurrency Throughput** | **
|
|
335
|
-
| **Simultaneous Concurrency Lock Errors** | **0 Errors (100% Reliability)** | **
|
|
336
|
-
| **
|
|
337
|
-
| **Final Database Disk Space** | **0.00 B (Clean)** | **
|
|
322
|
+
| **Pagination & Distinct (`SELECT DISTINCT ... LIMIT`)** | **24,089 queries/s** | **1,914 queries/s** | **Nemo is 12.58x faster** |
|
|
323
|
+
| **Vectorized SIMD Aggregates (`SUM, AVG, MIN, MAX`)** | **10,864 queries/s** | **1,094 queries/s** | **Nemo is 9.93x faster** |
|
|
324
|
+
| **Window Functions (`ROW_NUMBER, RANK OVER ORDER BY`)** | **2,840 ops/s** | **439 ops/s** | **Nemo is 6.47x faster** |
|
|
325
|
+
| **In-Memory Hash Joins (`t1 JOIN t2`)** | **9,202 joins/s** | **1,576 joins/s** | **Nemo is 5.84x faster** |
|
|
326
|
+
| **Compiled Scalar Math (`ABS & ROUND`)** | **13,837 queries/s** | **2,714 queries/s** | **Nemo is 5.10x faster** |
|
|
327
|
+
| **Direct Columnar Extraction API** | **681 ops/s** | **146 ops/s** | **Nemo is 4.66x faster** |
|
|
328
|
+
| **Relational Outer Joins (`LEFT JOIN`)** | **18,038 queries/s** | **3,894 queries/s** | **Nemo is 4.63x faster** |
|
|
329
|
+
| **Document Data Extraction (`JSON_EXTRACT`)** | **8,382 ops/s** | **1,903 ops/s** | **Nemo is 4.41x faster** |
|
|
330
|
+
| **Point Query Lookups (`WHERE id = ?`)** | **205,856 lookups/s** | **61,668 lookups/s** | **Nemo is 3.34x faster** |
|
|
331
|
+
| **Conditional Expressions (`COALESCE & NULLIF`)** | **12,631 queries/s** | **4,005 queries/s** | **Nemo is 3.15x faster** |
|
|
332
|
+
| **Hash-Accelerated Membership (`WHERE col IN (...)`)** | **2,930 queries/s** | **1,288 queries/s** | **Nemo is 2.27x faster** |
|
|
333
|
+
| **Branchless Logic (`CASE WHEN ... THEN ...`)** | **8,907 queries/s** | **4,002 queries/s** | **Nemo is 2.23x faster** |
|
|
334
|
+
| **All-At-Once Concurrency Throughput** | **93,356 ops/s** | **3,764 ops/s** | **Nemo is 24.80x faster** |
|
|
335
|
+
| **Simultaneous Concurrency Lock Errors** | **0 Errors (100% Reliability)** | **4 Lock Collisions** | **Nemo: Zero Collisions** |
|
|
336
|
+
| **Atomic Bulk Popping (FIFO + LIFO)** | **2,667,087 pops/s** | **4,354,604 pops/s** | **Ultra-low latency queues** |
|
|
337
|
+
| **Final Database Disk Space** | **0.00 B (Clean)** | **9.44 MB** | **Instant Clean Reclamation** |
|
|
338
338
|
|
|
339
339
|
*For deep architectural details on how Nemo achieves these metrics, read the [Engine Architecture & How It Works Guide](HOW_IT_WORKS.md).*
|
|
340
340
|
|
|
@@ -92,22 +92,22 @@ Nemo was benchmarked against SQLite 3 (configured with `PRAGMA journal_mode = WA
|
|
|
92
92
|
|
|
93
93
|
| Benchmark Dimension / Activity | Nemo (.nm) | SQLite (.db) (WAL Mode) | Speedup / Advantage |
|
|
94
94
|
| :--- | :--- | :--- | :--- |
|
|
95
|
-
| **
|
|
96
|
-
| **
|
|
97
|
-
| **
|
|
98
|
-
| **
|
|
99
|
-
| **
|
|
100
|
-
| **
|
|
101
|
-
| **
|
|
102
|
-
| **
|
|
103
|
-
| **
|
|
104
|
-
| **
|
|
105
|
-
| **
|
|
106
|
-
| **
|
|
107
|
-
| **All-At-Once Concurrency Throughput** | **
|
|
108
|
-
| **Simultaneous Concurrency Lock Errors** | **0 Errors (100% Reliability)** | **
|
|
109
|
-
| **
|
|
110
|
-
| **Final Database Disk Space** | **0.00 B (Clean)** | **
|
|
95
|
+
| **Pagination & Distinct (`SELECT DISTINCT ... LIMIT`)** | **24,089 queries/s** | **1,914 queries/s** | **Nemo is 12.58x faster** |
|
|
96
|
+
| **Vectorized SIMD Aggregates (`SUM, AVG, MIN, MAX`)** | **10,864 queries/s** | **1,094 queries/s** | **Nemo is 9.93x faster** |
|
|
97
|
+
| **Window Functions (`ROW_NUMBER, RANK OVER ORDER BY`)** | **2,840 ops/s** | **439 ops/s** | **Nemo is 6.47x faster** |
|
|
98
|
+
| **In-Memory Hash Joins (`t1 JOIN t2`)** | **9,202 joins/s** | **1,576 joins/s** | **Nemo is 5.84x faster** |
|
|
99
|
+
| **Compiled Scalar Math (`ABS & ROUND`)** | **13,837 queries/s** | **2,714 queries/s** | **Nemo is 5.10x faster** |
|
|
100
|
+
| **Direct Columnar Extraction API** | **681 ops/s** | **146 ops/s** | **Nemo is 4.66x faster** |
|
|
101
|
+
| **Relational Outer Joins (`LEFT JOIN`)** | **18,038 queries/s** | **3,894 queries/s** | **Nemo is 4.63x faster** |
|
|
102
|
+
| **Document Data Extraction (`JSON_EXTRACT`)** | **8,382 ops/s** | **1,903 ops/s** | **Nemo is 4.41x faster** |
|
|
103
|
+
| **Point Query Lookups (`WHERE id = ?`)** | **205,856 lookups/s** | **61,668 lookups/s** | **Nemo is 3.34x faster** |
|
|
104
|
+
| **Conditional Expressions (`COALESCE & NULLIF`)** | **12,631 queries/s** | **4,005 queries/s** | **Nemo is 3.15x faster** |
|
|
105
|
+
| **Hash-Accelerated Membership (`WHERE col IN (...)`)** | **2,930 queries/s** | **1,288 queries/s** | **Nemo is 2.27x faster** |
|
|
106
|
+
| **Branchless Logic (`CASE WHEN ... THEN ...`)** | **8,907 queries/s** | **4,002 queries/s** | **Nemo is 2.23x faster** |
|
|
107
|
+
| **All-At-Once Concurrency Throughput** | **93,356 ops/s** | **3,764 ops/s** | **Nemo is 24.80x faster** |
|
|
108
|
+
| **Simultaneous Concurrency Lock Errors** | **0 Errors (100% Reliability)** | **4 Lock Collisions** | **Nemo: Zero Collisions** |
|
|
109
|
+
| **Atomic Bulk Popping (FIFO + LIFO)** | **2,667,087 pops/s** | **4,354,604 pops/s** | **Ultra-low latency queues** |
|
|
110
|
+
| **Final Database Disk Space** | **0.00 B (Clean)** | **9.44 MB** | **Instant Clean Reclamation** |
|
|
111
111
|
|
|
112
112
|
*For deep architectural details on how Nemo achieves these metrics, read the [Engine Architecture & How It Works Guide](HOW_IT_WORKS.md).*
|
|
113
113
|
|
|
@@ -1,30 +1,31 @@
|
|
|
1
1
|
#ifndef NEMO_RUNTIME_MEMORY_RESOURCE_HPP
|
|
2
2
|
#define NEMO_RUNTIME_MEMORY_RESOURCE_HPP
|
|
3
3
|
|
|
4
|
-
#include <memory_resource>
|
|
5
4
|
#include <atomic>
|
|
6
5
|
#include <cstddef>
|
|
6
|
+
#include <cstdlib>
|
|
7
7
|
#include <stdexcept>
|
|
8
|
+
#include <string>
|
|
9
|
+
#include <new>
|
|
8
10
|
|
|
9
11
|
namespace nemo::runtime {
|
|
10
12
|
|
|
11
13
|
class MemoryLimitExceeded : public std::runtime_error {
|
|
12
14
|
public:
|
|
13
|
-
MemoryLimitExceeded(const std::string& what_arg) : std::runtime_error(what_arg) {}
|
|
15
|
+
explicit MemoryLimitExceeded(const std::string& what_arg) : std::runtime_error(what_arg) {}
|
|
14
16
|
};
|
|
15
17
|
|
|
16
|
-
class QueryMemoryResource
|
|
18
|
+
class QueryMemoryResource {
|
|
17
19
|
public:
|
|
18
|
-
explicit QueryMemoryResource(std::size_t limit_bytes
|
|
19
|
-
: m_limit(limit_bytes)
|
|
20
|
+
explicit QueryMemoryResource(std::size_t limit_bytes)
|
|
21
|
+
: m_limit(limit_bytes) {}
|
|
20
22
|
|
|
21
23
|
std::size_t usage() const noexcept { return m_usage.load(std::memory_order_relaxed); }
|
|
22
24
|
std::size_t limit() const noexcept { return m_limit; }
|
|
23
25
|
|
|
24
26
|
void reset_usage() noexcept { m_usage.store(0, std::memory_order_relaxed); }
|
|
25
27
|
|
|
26
|
-
|
|
27
|
-
void* do_allocate(std::size_t bytes, std::size_t alignment) override {
|
|
28
|
+
void* allocate(std::size_t bytes, std::size_t /*alignment*/ = alignof(std::max_align_t)) {
|
|
28
29
|
std::size_t current = m_usage.load(std::memory_order_relaxed);
|
|
29
30
|
while (true) {
|
|
30
31
|
if (current + bytes > m_limit) {
|
|
@@ -35,26 +36,23 @@ protected:
|
|
|
35
36
|
}
|
|
36
37
|
}
|
|
37
38
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
} catch (...) {
|
|
39
|
+
void* ptr = std::malloc(bytes);
|
|
40
|
+
if (!ptr) {
|
|
41
41
|
m_usage.fetch_sub(bytes, std::memory_order_relaxed);
|
|
42
|
-
throw;
|
|
42
|
+
throw std::bad_alloc();
|
|
43
43
|
}
|
|
44
|
+
return ptr;
|
|
44
45
|
}
|
|
45
46
|
|
|
46
|
-
void
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
bool do_is_equal(const std::pmr::memory_resource& other) const noexcept override {
|
|
52
|
-
return this == &other;
|
|
47
|
+
void deallocate(void* p, std::size_t bytes, std::size_t /*alignment*/ = alignof(std::max_align_t)) noexcept {
|
|
48
|
+
if (p) {
|
|
49
|
+
std::free(p);
|
|
50
|
+
m_usage.fetch_sub(bytes, std::memory_order_relaxed);
|
|
51
|
+
}
|
|
53
52
|
}
|
|
54
53
|
|
|
55
54
|
private:
|
|
56
55
|
std::size_t m_limit;
|
|
57
|
-
std::pmr::memory_resource* m_upstream;
|
|
58
56
|
std::atomic<std::size_t> m_usage{0};
|
|
59
57
|
};
|
|
60
58
|
|
|
@@ -4,7 +4,7 @@ build-backend = "scikit_build_core.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "nemo-py"
|
|
7
|
-
version = "0.2.
|
|
7
|
+
version = "0.2.2"
|
|
8
8
|
authors = [
|
|
9
9
|
{ name="Pravanjan Roy" },
|
|
10
10
|
]
|
|
@@ -41,3 +41,6 @@ wheel.packages = ["python/src/nemo"]
|
|
|
41
41
|
cmake.define.NEMO_BUILD_PYTHON = "ON"
|
|
42
42
|
cmake.define.NEMO_BUILD_TESTS = "OFF"
|
|
43
43
|
cmake.define.NEMO_BUILD_EXAMPLES = "OFF"
|
|
44
|
+
|
|
45
|
+
[tool.cibuildwheel]
|
|
46
|
+
build-verbosity = 1
|
|
@@ -28,7 +28,7 @@ from .errors import (
|
|
|
28
28
|
)
|
|
29
29
|
from .logging import LoggingConfig, configure_logging, enable_debug
|
|
30
30
|
|
|
31
|
-
__version__ = "0.2.
|
|
31
|
+
__version__ = "0.2.2"
|
|
32
32
|
__all__ = [
|
|
33
33
|
"connect", "Database",
|
|
34
34
|
"SyncConnector", "SyncConnection", "SyncConnectionPool", "SyncConnectorPool",
|
|
@@ -16,9 +16,10 @@
|
|
|
16
16
|
import logging
|
|
17
17
|
import uuid
|
|
18
18
|
from typing import Sequence, Optional, Iterator
|
|
19
|
-
from .logging import conn_logger, txn_logger, pool_logger, QueryContext
|
|
19
|
+
from .logging import conn_logger, txn_logger, pool_logger, QueryContext, get_config
|
|
20
20
|
|
|
21
21
|
class SyncResult(Iterator):
|
|
22
|
+
__slots__ = ("_native",)
|
|
22
23
|
def __init__(self, native_result):
|
|
23
24
|
self._native = native_result
|
|
24
25
|
|
|
@@ -128,6 +129,7 @@ class SyncTransaction:
|
|
|
128
129
|
return False
|
|
129
130
|
|
|
130
131
|
class SyncConnection:
|
|
132
|
+
__slots__ = ("_native", "_id")
|
|
131
133
|
def __init__(self, native_conn):
|
|
132
134
|
self._native = native_conn
|
|
133
135
|
self._id = uuid.uuid4().hex[:8]
|
|
@@ -135,11 +137,18 @@ class SyncConnection:
|
|
|
135
137
|
conn_logger.debug(f"Connection acquired", extra={"conn_id": self._id})
|
|
136
138
|
|
|
137
139
|
def execute(self, sql: str, parameters: Optional[Sequence[object]] = None, timeout: float = 0.0) -> SyncResult:
|
|
138
|
-
|
|
139
|
-
|
|
140
|
+
cfg = get_config()
|
|
141
|
+
if cfg.query_logging or cfg.slow_query_threshold_ms is not None:
|
|
142
|
+
with QueryContext("EXECUTE", sql, parameters or (), self._id):
|
|
143
|
+
return SyncResult(self._native.execute(sql, parameters or (), timeout))
|
|
144
|
+
return SyncResult(self._native.execute(sql, parameters or (), timeout))
|
|
140
145
|
|
|
141
146
|
def executemany(self, sql: str, parameters_list: Sequence[Sequence[object]]):
|
|
142
|
-
|
|
147
|
+
cfg = get_config()
|
|
148
|
+
if cfg.query_logging or cfg.slow_query_threshold_ms is not None:
|
|
149
|
+
with QueryContext("EXECUTEMANY", sql, [], self._id):
|
|
150
|
+
self._native.executemany(sql, parameters_list)
|
|
151
|
+
else:
|
|
143
152
|
self._native.executemany(sql, parameters_list)
|
|
144
153
|
|
|
145
154
|
def pop(self, table: str, count: int = 1, direction: str = "fifo") -> list[tuple]:
|
|
@@ -272,6 +281,5 @@ class SyncConnectionPool:
|
|
|
272
281
|
def __exit__(self, exc_type, exc_val, exc_tb):
|
|
273
282
|
self.close()
|
|
274
283
|
|
|
275
|
-
# Aliases
|
|
276
284
|
SyncConnector = SyncConnection
|
|
277
285
|
SyncConnectorPool = SyncConnectionPool
|
|
@@ -42,7 +42,7 @@ struct TableStatistics {
|
|
|
42
42
|
};
|
|
43
43
|
|
|
44
44
|
struct Sequence {
|
|
45
|
-
std::string name;
|
|
45
|
+
std::string name;
|
|
46
46
|
std::int64_t current_val{1};
|
|
47
47
|
std::int64_t start_with{1};
|
|
48
48
|
std::int64_t increment_by{1};
|
|
@@ -342,6 +342,7 @@ public:
|
|
|
342
342
|
}
|
|
343
343
|
tbl->sample_rows.push_back(std::move(row_vals));
|
|
344
344
|
}
|
|
345
|
+
tbl->total_rows = tbl->sample_rows.size();
|
|
345
346
|
tables[t_name] = tbl;
|
|
346
347
|
}
|
|
347
348
|
ifs.close();
|
|
@@ -428,6 +429,8 @@ public:
|
|
|
428
429
|
std::shared_ptr<SharedDatabaseState> shared_state;
|
|
429
430
|
bool in_transaction{false};
|
|
430
431
|
std::vector<SavepointSnapshot> savepoints;
|
|
432
|
+
std::string cached_insert_table_name;
|
|
433
|
+
std::shared_ptr<TableData> cached_insert_table{nullptr};
|
|
431
434
|
};
|
|
432
435
|
|
|
433
436
|
class ResultImpl {
|
|
@@ -438,19 +441,58 @@ public:
|
|
|
438
441
|
std::vector<ColumnMetadata> columns;
|
|
439
442
|
QueryStatistics stats;
|
|
440
443
|
std::vector<std::vector<types::Value>> rows;
|
|
444
|
+
std::shared_ptr<TableData> table_ref{nullptr};
|
|
445
|
+
std::size_t single_row_idx{static_cast<std::size_t>(-1)};
|
|
446
|
+
bool is_join{false};
|
|
447
|
+
std::shared_ptr<TableData> join_tbl1{nullptr};
|
|
448
|
+
std::shared_ptr<TableData> join_tbl2{nullptr};
|
|
449
|
+
struct JoinColRef {
|
|
450
|
+
bool from_tbl1{true};
|
|
451
|
+
std::size_t col_idx{0};
|
|
452
|
+
};
|
|
453
|
+
std::vector<JoinColRef> join_proj;
|
|
454
|
+
std::vector<std::pair<std::size_t, std::size_t>> join_pairs;
|
|
441
455
|
std::size_t total_rows{0};
|
|
442
456
|
std::size_t current_row{0};
|
|
443
457
|
|
|
458
|
+
const std::vector<std::vector<types::Value>>& get_effective_rows() const noexcept {
|
|
459
|
+
if (table_ref && single_row_idx == static_cast<std::size_t>(-1)) return table_ref->sample_rows;
|
|
460
|
+
return rows;
|
|
461
|
+
}
|
|
462
|
+
|
|
444
463
|
std::unique_ptr<Row> create_next_row() {
|
|
445
464
|
if (current_row >= total_rows) {
|
|
446
465
|
return nullptr;
|
|
447
466
|
}
|
|
448
467
|
auto row_impl = std::make_unique<RowImpl>();
|
|
449
|
-
if (
|
|
450
|
-
if (
|
|
451
|
-
row_impl->values =
|
|
468
|
+
if (single_row_idx != static_cast<std::size_t>(-1) && table_ref) {
|
|
469
|
+
if (single_row_idx < table_ref->sample_rows.size()) {
|
|
470
|
+
row_impl->values = table_ref->sample_rows[single_row_idx];
|
|
471
|
+
}
|
|
472
|
+
current_row++;
|
|
473
|
+
return std::unique_ptr<Row>(new Row(std::move(row_impl)));
|
|
474
|
+
}
|
|
475
|
+
if (is_join && join_tbl1 && join_tbl2 && current_row < join_pairs.size()) {
|
|
476
|
+
const auto& p = join_pairs[current_row++];
|
|
477
|
+
const auto& r1 = (p.first != static_cast<std::size_t>(-1) && p.first < join_tbl1->sample_rows.size()) ? join_tbl1->sample_rows[p.first] : std::vector<types::Value>{};
|
|
478
|
+
const auto& r2 = (p.second != static_cast<std::size_t>(-1) && p.second < join_tbl2->sample_rows.size()) ? join_tbl2->sample_rows[p.second] : std::vector<types::Value>{};
|
|
479
|
+
row_impl->values.reserve(join_proj.size());
|
|
480
|
+
for (const auto& jc : join_proj) {
|
|
481
|
+
const auto& src = jc.from_tbl1 ? r1 : r2;
|
|
482
|
+
if (jc.col_idx < src.size()) {
|
|
483
|
+
row_impl->values.push_back(src[jc.col_idx]);
|
|
484
|
+
} else {
|
|
485
|
+
row_impl->values.push_back(types::Value());
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
return std::unique_ptr<Row>(new Row(std::move(row_impl)));
|
|
489
|
+
}
|
|
490
|
+
const auto& eff_rows = get_effective_rows();
|
|
491
|
+
if (!eff_rows.empty()) {
|
|
492
|
+
if (is_exact || eff_rows.size() == total_rows) {
|
|
493
|
+
row_impl->values = eff_rows[current_row];
|
|
452
494
|
} else {
|
|
453
|
-
row_impl->values =
|
|
495
|
+
row_impl->values = eff_rows[current_row % eff_rows.size()];
|
|
454
496
|
if (!row_impl->values.empty()) {
|
|
455
497
|
row_impl->values[0] = types::Value(static_cast<std::int64_t>(current_row + 1));
|
|
456
498
|
}
|