dictsqlite 2.1.1__tar.gz → 2.1.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.
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/Cargo.lock +1 -1
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/Cargo.toml +1 -1
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/PKG-INFO +1 -1
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/pyproject.toml +1 -1
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/src/async_ops.rs +10 -9
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/src/lib.rs +49 -73
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/.bandit +0 -0
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/.gitignore +0 -0
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/Pypi.md +0 -0
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/benches/ops_benchmark.rs +0 -0
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/benchmark/README.md +0 -0
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/benchmark/analyze_results.py +0 -0
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/benchmark/benchmark_all.py +0 -0
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/benchmark/benchmark_results.csv +0 -0
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/benchmark/images/benchmark_avg_latency.png +0 -0
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/benchmark/images/benchmark_by_data_size.png +0 -0
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/benchmark/images/benchmark_category_comparison.png +0 -0
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/benchmark/images/benchmark_ops_per_sec.png +0 -0
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/build.sh +0 -0
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/build_production.sh +0 -0
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/build_result.txt +0 -0
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/check_result.txt +0 -0
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/deny.toml +0 -0
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/docs/EXAMPLES_EN.md +0 -0
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/docs/EXAMPLES_JP.md +0 -0
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/docs/FIX_SUMMARY.md +0 -0
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/docs/INDEX.md +0 -0
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/docs/MIGRATION_FROM_1.8.8_EN.md +0 -0
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/docs/MIGRATION_FROM_1.8.8_JP.md +0 -0
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/docs/README_EN.md +0 -0
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/docs/README_JP.md +0 -0
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/docs/TABLE_PROXY_REPR_REPORT.md +0 -0
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/docs/optimization_v5/01_overview.md +0 -0
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/docs/optimization_v5/02_storage_engine.md +0 -0
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/docs/optimization_v5/03_async_layer.md +0 -0
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/docs/optimization_v5/04_integration.md +0 -0
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/docs/optimization_v5/05_verification.md +0 -0
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/examples/README.md +0 -0
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/examples/async_await_example.py +0 -0
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/examples/async_jsonb_table_usage.py +0 -0
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/examples/jsonb_table_usage_example.py +0 -0
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/examples/v4.2_advanced_examples.py +0 -0
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/examples/v4.2_basic_usage.py +0 -0
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/examples/v4.2_migration_example.py +0 -0
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/examples/v4.2_performance_examples.py +0 -0
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/others/ASYNC_IMPLEMENTATION_SUMMARY.md +0 -0
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/others/ASYNC_SUPPORT_README.md +0 -0
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/others/BENCHMARK_RESULTS_JP.md +0 -0
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/others/BUILD_WARNINGS_EXPLANATION_JP.md +0 -0
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/others/CLIPPY_FIXES_SUMMARY.md +0 -0
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/others/COMPREHENSIVE_BENCHMARK_RESULTS.md +0 -0
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/others/COMPREHENSIVE_TEST_IMPLEMENTATION_REPORT_JP.md +0 -0
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/others/DEVELOPER_GUIDE_JP.md +0 -0
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/others/DICTSQLITE_V2_SPECIFICATION_JP.md +0 -0
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/others/DOCUMENTATION_INDEX_JP.md +0 -0
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/others/DOCUMENTATION_VERIFICATION_SUMMARY.md +0 -0
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/others/FIX_SUMMARY_JP.md +0 -0
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/others/GITHUB_ACTIONS_FIXES.md +0 -0
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/others/IMPLEMENTATION_COMPLETION_REPORT.md +0 -0
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/others/IMPLEMENTATION_COMPLETION_REPORT_JP.md +0 -0
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/others/IMPROVEMENT_ACTION_PLAN_JP.md +0 -0
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/others/INVESTIGATION_SUMMARY_JP.md +0 -0
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/others/ISSUE_RESPONSE_JSON_TABLE_SUPPORT_JP.md +0 -0
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/others/JSONB_TABLE_IMPLEMENTATION_SUMMARY_JP.md +0 -0
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/others/JSON_MODE_TABLE_SUPPORT_FEASIBILITY_JP.md +0 -0
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/others/MIGRATION_GUIDE_V4.2_JP.md +0 -0
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/others/PERFORMANCE_OPTIMIZATION_GUIDE_JP.md +0 -0
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/others/PERFORMANCE_TESTING_GUIDE.md +0 -0
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/others/PERFORMANCE_TEST_IMPLEMENTATION.md +0 -0
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/others/PERFORMANCE_TEST_RESULTS.md +0 -0
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/others/PYTEST_INTEGRATION_SUMMARY.md +0 -0
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/others/PYTEST_WARNINGS_FIX.md +0 -0
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/others/QUICK_REFERENCE_JSONB_TABLE_JP.md +0 -0
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/others/README_INVESTIGATION_JP.md +0 -0
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/others/README_V4.2_JP.md +0 -0
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/others/TESTING_DOCUMENTATION_JP.md +0 -0
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/others/TEST_AND_DOCUMENTATION_REVIEW_JP.md +0 -0
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/others/TEST_COMPLETION_REPORT.md +0 -0
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/others/V4.2_IMPLEMENTATION_SUMMARY.md +0 -0
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/others/WINDOWS_PERMISSION_FIX.md +0 -0
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/python/dictsqlite/__init__.py +0 -0
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/python/dictsqlite/modules/__init__.py +0 -0
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/python/dictsqlite/modules/safe_pickle.py +0 -0
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/setup.cfg +0 -0
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/src/cache.rs +0 -0
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/src/crypto.rs +0 -0
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/src/storage.rs +0 -0
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/src/tests_compression.rs +0 -0
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/src/tests_jsonb.rs +0 -0
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/src/tests_lru.rs +0 -0
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/src/tests_storage.rs +0 -0
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/src/tests_v6.rs +0 -0
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/test_debug.py +0 -0
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/tests/ISSUE_RESPONSE.md +0 -0
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/tests/README.md +0 -0
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/tests/README_COMPREHENSIVE_TESTS.md +0 -0
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/tests/README_NEW_COMPREHENSIVE_TESTS.md +0 -0
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/tests/TEST_DOCUMENTATION.md +0 -0
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/tests/TEST_FIXES_REPORT_JP.md +0 -0
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/tests/__init__.py +0 -0
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/tests/_check_safe_pickle.py +0 -0
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/tests/_reproduce_test.py +0 -0
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/tests/benchmark_comprehensive.py +0 -0
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/tests/conftest.py +0 -0
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/tests/test_advanced_features.py +0 -0
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/tests/test_async_awaitable.py +0 -0
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/tests/test_async_operations.py +0 -0
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/tests/test_async_persistence.py +0 -0
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/tests/test_async_table_contains.py +0 -0
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/tests/test_basic_operations.py +0 -0
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/tests/test_boundary_edge_cases.py +0 -0
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/tests/test_comprehensive_all_functions.py +0 -0
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/tests/test_comprehensive_edge_cases.py +0 -0
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/tests/test_comprehensive_integration.py +0 -0
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/tests/test_comprehensive_stress.py +0 -0
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/tests/test_dict_compat_api.py +0 -0
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/tests/test_exhaustive_async.py +0 -0
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/tests/test_exhaustive_async_table_proxy.py +0 -0
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/tests/test_exhaustive_dictsqlite_v4.py +0 -0
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/tests/test_exhaustive_table_proxy.py +0 -0
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/tests/test_issue_fixes.py +0 -0
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/tests/test_jsonb_table_support.py +0 -0
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/tests/test_lru_eviction.py +0 -0
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/tests/test_performance.py +0 -0
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/tests/test_persistence_modes.py +0 -0
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/tests/test_pool_size.py +0 -0
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/tests/test_return_type_validation.py +0 -0
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/tests/test_storage_modes.py +0 -0
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/tests/test_table_mode.py +0 -0
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/tests/test_table_proxy_eq.py +0 -0
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/tests/test_table_proxy_repr.py +0 -0
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/tests/test_v4.2_comprehensive_performance.py +0 -0
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/tests/test_v4_security.py +0 -0
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/tests/test_v6_migration.py +0 -0
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/tests/test_v7_batch_async.py +0 -0
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/tests/verify_optimization_opportunities.py +0 -0
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/twine/__init__.py +0 -0
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/twine/__main__.py +0 -0
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/twine/auth.py +0 -0
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/twine/cli.py +0 -0
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/twine/commands/__init__.py +0 -0
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/twine/commands/check.py +0 -0
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/twine/commands/register.py +0 -0
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/twine/commands/upload.py +0 -0
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/twine/distribution.py +0 -0
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/twine/exceptions.py +0 -0
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/twine/package.py +0 -0
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/twine/py.typed +0 -0
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/twine/repository.py +0 -0
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/twine/sdist.py +0 -0
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/twine/settings.py +0 -0
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/twine/utils.py +0 -0
- {dictsqlite-2.1.1 → dictsqlite-2.1.2}/twine/wheel.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[package]
|
|
2
2
|
name = "dictsqlite"
|
|
3
|
-
version = "2.1.
|
|
3
|
+
version = "2.1.2"
|
|
4
4
|
edition = "2021"
|
|
5
5
|
authors = ["Disnana <support@disnana.com>"]
|
|
6
6
|
description = "High-performance DictSQLite v2 with I/O optimizations (300x async, 43x sync speedup) - Buffered writes and batch operations"
|
|
@@ -7,7 +7,7 @@ build-backend = "maturin"
|
|
|
7
7
|
# PEP 621 project metadata required by maturin >= 0.14
|
|
8
8
|
[project]
|
|
9
9
|
name = "dictsqlite"
|
|
10
|
-
version = "2.1.
|
|
10
|
+
version = "2.1.2"
|
|
11
11
|
description = "High-performance DictSQLite v2 with I/O optimizations"
|
|
12
12
|
readme = "Pypi.md"
|
|
13
13
|
requires-python = ">=3.9"
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
// v6.0: PyO3 0.27 API完全移行
|
|
2
2
|
|
|
3
3
|
use dashmap::DashMap;
|
|
4
|
+
use parking_lot::Mutex;
|
|
4
5
|
use pyo3::prelude::*;
|
|
5
6
|
use pyo3::types::{PyBytes, PyDict};
|
|
6
7
|
use rayon::prelude::*;
|
|
7
8
|
use std::collections::HashMap;
|
|
8
|
-
use std::sync::{Arc,
|
|
9
|
+
use std::sync::{Arc, OnceLock};
|
|
9
10
|
use tokio::runtime::Runtime;
|
|
10
11
|
|
|
11
12
|
use crate::{
|
|
@@ -162,7 +163,7 @@ impl AsyncDictSQLite {
|
|
|
162
163
|
if self.config.persist_mode == PersistMode::WriteThrough {
|
|
163
164
|
// Add to write buffer
|
|
164
165
|
{
|
|
165
|
-
let mut buffer = self.write_buffer.lock()
|
|
166
|
+
let mut buffer = self.write_buffer.lock();
|
|
166
167
|
buffer.insert(key, value);
|
|
167
168
|
}
|
|
168
169
|
|
|
@@ -177,7 +178,7 @@ impl AsyncDictSQLite {
|
|
|
177
178
|
/// Flush write buffer to storage (v4.2 optimization)
|
|
178
179
|
/// Batches multiple writes into a single transaction
|
|
179
180
|
fn flush_write_buffer(&self) -> PyResult<()> {
|
|
180
|
-
let mut buffer = self.write_buffer.lock()
|
|
181
|
+
let mut buffer = self.write_buffer.lock();
|
|
181
182
|
|
|
182
183
|
if buffer.is_empty() {
|
|
183
184
|
return Ok(());
|
|
@@ -373,7 +374,7 @@ impl AsyncDictSQLite {
|
|
|
373
374
|
if config.persist_mode == PersistMode::WriteThrough {
|
|
374
375
|
// Add to write buffer
|
|
375
376
|
let should_flush = {
|
|
376
|
-
let mut buffer = write_buffer.lock()
|
|
377
|
+
let mut buffer = write_buffer.lock();
|
|
377
378
|
buffer.insert(key, value);
|
|
378
379
|
buffer.len() >= buffer_size
|
|
379
380
|
};
|
|
@@ -382,7 +383,7 @@ impl AsyncDictSQLite {
|
|
|
382
383
|
if should_flush {
|
|
383
384
|
runtime
|
|
384
385
|
.spawn_blocking(move || {
|
|
385
|
-
let mut buffer = write_buffer.lock()
|
|
386
|
+
let mut buffer = write_buffer.lock();
|
|
386
387
|
if buffer.is_empty() {
|
|
387
388
|
return Ok(());
|
|
388
389
|
}
|
|
@@ -475,7 +476,7 @@ impl AsyncDictSQLite {
|
|
|
475
476
|
if config.persist_mode == PersistMode::WriteThrough {
|
|
476
477
|
// Add to write buffer
|
|
477
478
|
let should_flush = {
|
|
478
|
-
let mut buffer = write_buffer.lock()
|
|
479
|
+
let mut buffer = write_buffer.lock();
|
|
479
480
|
for (key, value) in items {
|
|
480
481
|
buffer.insert(key, value);
|
|
481
482
|
}
|
|
@@ -488,7 +489,7 @@ impl AsyncDictSQLite {
|
|
|
488
489
|
if should_flush {
|
|
489
490
|
runtime
|
|
490
491
|
.spawn_blocking(move || {
|
|
491
|
-
let mut buffer = write_buffer.lock()
|
|
492
|
+
let mut buffer = write_buffer.lock();
|
|
492
493
|
if buffer.is_empty() {
|
|
493
494
|
return Ok(());
|
|
494
495
|
}
|
|
@@ -587,7 +588,7 @@ impl AsyncDictSQLite {
|
|
|
587
588
|
runtime
|
|
588
589
|
.spawn_blocking(move || {
|
|
589
590
|
// First, flush any pending writes in the buffer
|
|
590
|
-
let mut buffer = write_buffer.lock()
|
|
591
|
+
let mut buffer = write_buffer.lock();
|
|
591
592
|
if !buffer.is_empty() {
|
|
592
593
|
if let Some(ref storage_engine) = *storage {
|
|
593
594
|
for (k, v) in buffer.drain() {
|
|
@@ -771,7 +772,7 @@ impl AsyncDictSQLite {
|
|
|
771
772
|
|
|
772
773
|
// Remove from write buffer
|
|
773
774
|
if self.config.persist_mode == PersistMode::WriteThrough {
|
|
774
|
-
let mut buffer = self.write_buffer.lock()
|
|
775
|
+
let mut buffer = self.write_buffer.lock();
|
|
775
776
|
buffer.remove(&full_key);
|
|
776
777
|
}
|
|
777
778
|
|
|
@@ -49,13 +49,14 @@
|
|
|
49
49
|
|
|
50
50
|
use dashmap::DashMap;
|
|
51
51
|
use lru::LruCache;
|
|
52
|
+
use parking_lot::Mutex;
|
|
52
53
|
use pyo3::prelude::*;
|
|
53
54
|
use pyo3::types::{PyAny, PyBytes, PyDict};
|
|
54
55
|
use serde::{Deserialize, Serialize};
|
|
55
56
|
use std::collections::HashMap;
|
|
56
57
|
use std::num::NonZeroUsize;
|
|
57
58
|
use std::str::FromStr;
|
|
58
|
-
use std::sync::
|
|
59
|
+
use std::sync::Arc;
|
|
59
60
|
|
|
60
61
|
// v4.2.4 パフォーマンス最適化定数
|
|
61
62
|
/// 小容量キャパシティの閾値 (この値以下では厳密なキャパシティ管理)
|
|
@@ -698,8 +699,9 @@ pub struct DictSQLiteV4 {
|
|
|
698
699
|
/// ストレージエンジン: warm/cold tierの管理
|
|
699
700
|
///
|
|
700
701
|
/// Memory以外の永続化モードで使用。
|
|
701
|
-
///
|
|
702
|
-
|
|
702
|
+
/// StorageEngineは内部でr2d2コネクションプール + DashMapを使用するため
|
|
703
|
+
/// スレッドセーフであり、外部のMutexは不要。
|
|
704
|
+
storage: Option<Arc<StorageEngine>>,
|
|
703
705
|
|
|
704
706
|
/// 設定
|
|
705
707
|
config: Config,
|
|
@@ -950,13 +952,14 @@ impl DictSQLiteV4 {
|
|
|
950
952
|
)));
|
|
951
953
|
|
|
952
954
|
// 純粋なメモリモードでない場合のみストレージを作成
|
|
955
|
+
// StorageEngineは内部でスレッドセーフなので Arc だけでラップする
|
|
953
956
|
let storage = if config.persist_mode == PersistMode::Memory {
|
|
954
|
-
|
|
957
|
+
None
|
|
955
958
|
} else {
|
|
956
|
-
Arc::new(
|
|
959
|
+
Some(Arc::new(
|
|
957
960
|
StorageEngine::new(&db_path, &config)
|
|
958
961
|
.map_err(|e| PyErr::new::<pyo3::exceptions::PyIOError, _>(e.to_string()))?,
|
|
959
|
-
))
|
|
962
|
+
))
|
|
960
963
|
};
|
|
961
964
|
|
|
962
965
|
// パスワードが提供された場合、暗号化エンジンを初期化
|
|
@@ -1021,8 +1024,8 @@ impl DictSQLiteV4 {
|
|
|
1021
1024
|
/// - 復号化に失敗した場合: ValueError
|
|
1022
1025
|
#[pyo3(signature = (key, default=None))]
|
|
1023
1026
|
fn get(&self, key: String, default: Option<Vec<u8>>, py: Python) -> PyResult<Py<PyAny>> {
|
|
1024
|
-
//
|
|
1025
|
-
// WriteThrough
|
|
1027
|
+
// v7.1最適化: LRU追跡はキャパシティ超過時のみ実行(エビクション判定が必要な場合のみ)
|
|
1028
|
+
// WriteThroughモードの特別扱いを廃止し、全モードで同一の閾値を使用
|
|
1026
1029
|
let current_size = self.hot_tier.len();
|
|
1027
1030
|
let tracking_threshold = if self.config.hot_tier_capacity <= SMALL_CAPACITY_THRESHOLD {
|
|
1028
1031
|
// 小容量: 常に追跡(テスト互換性)
|
|
@@ -1031,11 +1034,10 @@ impl DictSQLiteV4 {
|
|
|
1031
1034
|
// 大容量: LRU_TRACKING_THRESHOLD_PERCENT%から追跡(パフォーマンス優先)
|
|
1032
1035
|
(self.config.hot_tier_capacity * LRU_TRACKING_THRESHOLD_PERCENT) / 100
|
|
1033
1036
|
};
|
|
1034
|
-
let needs_lru =
|
|
1035
|
-
|| current_size >= tracking_threshold;
|
|
1037
|
+
let needs_lru = current_size >= tracking_threshold;
|
|
1036
1038
|
|
|
1037
1039
|
if needs_lru {
|
|
1038
|
-
self.access_tracker.lock().
|
|
1040
|
+
self.access_tracker.lock().put(key.clone(), ());
|
|
1039
1041
|
}
|
|
1040
1042
|
|
|
1041
1043
|
// Hot tierを最初に試行(ロックフリー読み取り)
|
|
@@ -1066,8 +1068,7 @@ impl DictSQLiteV4 {
|
|
|
1066
1068
|
}
|
|
1067
1069
|
|
|
1068
1070
|
// 他のモードではストレージ(Cold tier)も検索
|
|
1069
|
-
let
|
|
1070
|
-
if let Some(ref storage) = *storage_guard {
|
|
1071
|
+
if let Some(ref storage) = self.storage {
|
|
1071
1072
|
if let Ok(Some(value)) = storage.get(&key) {
|
|
1072
1073
|
// 暗号化されているがパスワードがない場合のチェック
|
|
1073
1074
|
if self.crypto.is_none() && crate::crypto::CryptoEngine::is_encrypted(&value) {
|
|
@@ -1087,7 +1088,6 @@ impl DictSQLiteV4 {
|
|
|
1087
1088
|
|
|
1088
1089
|
// Hot tierにプロモート(暗号化状態で保存)
|
|
1089
1090
|
// これにより次回アクセス時の速度が向上
|
|
1090
|
-
drop(storage_guard);
|
|
1091
1091
|
self.hot_tier.insert(key, value);
|
|
1092
1092
|
return Ok(PyBytes::new(py, &data).into());
|
|
1093
1093
|
}
|
|
@@ -1154,9 +1154,8 @@ impl DictSQLiteV4 {
|
|
|
1154
1154
|
(is_new, None)
|
|
1155
1155
|
};
|
|
1156
1156
|
|
|
1157
|
-
//
|
|
1158
|
-
//
|
|
1159
|
-
// WriteThroughモードまたはキャパシティ超過時のみLRU追跡を有効化
|
|
1157
|
+
// v7.1最適化: LRUアクセス追跡はキャパシティ超過時のみ実行
|
|
1158
|
+
// WriteThroughモードの特別扱いを廃止し、全モードで同一の閾値を使用
|
|
1160
1159
|
let current_size = self.hot_tier.len();
|
|
1161
1160
|
let tracking_threshold = if self.config.hot_tier_capacity <= SMALL_CAPACITY_THRESHOLD {
|
|
1162
1161
|
// 小容量: 常に追跡(テスト互換性)
|
|
@@ -1165,17 +1164,16 @@ impl DictSQLiteV4 {
|
|
|
1165
1164
|
// 大容量: LRU_TRACKING_THRESHOLD_PERCENT%から追跡(パフォーマンス優先)
|
|
1166
1165
|
(self.config.hot_tier_capacity * LRU_TRACKING_THRESHOLD_PERCENT) / 100
|
|
1167
1166
|
};
|
|
1168
|
-
let needs_lru =
|
|
1169
|
-
|| current_size >= tracking_threshold;
|
|
1167
|
+
let needs_lru = current_size >= tracking_threshold;
|
|
1170
1168
|
|
|
1171
1169
|
if is_new_key && needs_lru {
|
|
1172
|
-
self.access_tracker.lock().
|
|
1170
|
+
self.access_tracker.lock().put(key.clone(), ());
|
|
1173
1171
|
}
|
|
1174
1172
|
|
|
1175
1173
|
// v4.2.2最適化: WriteThroughモードでは書き込みバッファを使用
|
|
1176
1174
|
if self.config.persist_mode == PersistMode::WriteThrough {
|
|
1177
1175
|
let should_flush = {
|
|
1178
|
-
let mut buffer = self.write_buffer.lock()
|
|
1176
|
+
let mut buffer = self.write_buffer.lock();
|
|
1179
1177
|
buffer.push((key.clone(), data_for_buffer.unwrap()));
|
|
1180
1178
|
// バッファサイズに達したらフラッシュ
|
|
1181
1179
|
// buffer_size=1の場合は即時フラッシュ
|
|
@@ -1219,7 +1217,7 @@ impl DictSQLiteV4 {
|
|
|
1219
1217
|
/// # エラー
|
|
1220
1218
|
/// - ストレージ書き込みに失敗した場合: IOError
|
|
1221
1219
|
fn evict_to_warm_tier(&self) -> PyResult<()> {
|
|
1222
|
-
let mut tracker = self.access_tracker.lock()
|
|
1220
|
+
let mut tracker = self.access_tracker.lock();
|
|
1223
1221
|
|
|
1224
1222
|
// v4.2.4最適化: 一度にBATCH_EVICTION_PERCENT%のエントリをエビクション(バッチ処理)
|
|
1225
1223
|
let eviction_count = std::cmp::max(
|
|
@@ -1245,8 +1243,7 @@ impl DictSQLiteV4 {
|
|
|
1245
1243
|
|
|
1246
1244
|
// Memoryモードでない場合はストレージに一括書き込み
|
|
1247
1245
|
if self.config.persist_mode != PersistMode::Memory && !evicted_items.is_empty() {
|
|
1248
|
-
let
|
|
1249
|
-
if let Some(ref mut storage) = *storage_guard {
|
|
1246
|
+
if let Some(ref storage) = self.storage {
|
|
1250
1247
|
// bulk_insertで一括書き込み(単一トランザクション)
|
|
1251
1248
|
storage
|
|
1252
1249
|
.bulk_insert(&evicted_items)
|
|
@@ -1269,7 +1266,7 @@ impl DictSQLiteV4 {
|
|
|
1269
1266
|
/// - `Ok(())`: フラッシュ成功
|
|
1270
1267
|
/// - `Err(PyErr)`: ストレージ書き込みエラー
|
|
1271
1268
|
fn flush_write_buffer(&self) -> PyResult<()> {
|
|
1272
|
-
let mut buffer = self.write_buffer.lock()
|
|
1269
|
+
let mut buffer = self.write_buffer.lock();
|
|
1273
1270
|
|
|
1274
1271
|
// バッファが空の場合は何もしない
|
|
1275
1272
|
if buffer.is_empty() {
|
|
@@ -1283,8 +1280,7 @@ impl DictSQLiteV4 {
|
|
|
1283
1280
|
drop(buffer);
|
|
1284
1281
|
|
|
1285
1282
|
// ストレージハンドルを取得してバルクインサート
|
|
1286
|
-
let
|
|
1287
|
-
if let Some(ref mut storage) = *storage_guard {
|
|
1283
|
+
if let Some(ref storage) = self.storage {
|
|
1288
1284
|
// bulk_insert()を使用して単一トランザクションで高速書き込み
|
|
1289
1285
|
storage
|
|
1290
1286
|
.bulk_insert(&items)
|
|
@@ -1331,8 +1327,7 @@ impl DictSQLiteV4 {
|
|
|
1331
1327
|
.collect();
|
|
1332
1328
|
|
|
1333
1329
|
// バルクインサートで一括永続化(単一トランザクション)
|
|
1334
|
-
let
|
|
1335
|
-
if let Some(ref mut storage) = *storage_guard {
|
|
1330
|
+
if let Some(ref storage) = self.storage {
|
|
1336
1331
|
storage
|
|
1337
1332
|
.bulk_insert(&items)
|
|
1338
1333
|
.map_err(|e| PyErr::new::<pyo3::exceptions::PyIOError, _>(e.to_string()))?;
|
|
@@ -1352,21 +1347,20 @@ impl DictSQLiteV4 {
|
|
|
1352
1347
|
}
|
|
1353
1348
|
|
|
1354
1349
|
// Track that we're removing this
|
|
1355
|
-
self.access_tracker.lock().
|
|
1350
|
+
self.access_tracker.lock().pop(&key);
|
|
1356
1351
|
|
|
1357
1352
|
// Remove from hot tier
|
|
1358
1353
|
self.hot_tier.remove(&key);
|
|
1359
1354
|
|
|
1360
1355
|
// Remove from write buffer (v4.2)
|
|
1361
1356
|
if self.config.persist_mode == PersistMode::WriteThrough {
|
|
1362
|
-
let mut buffer = self.write_buffer.lock()
|
|
1357
|
+
let mut buffer = self.write_buffer.lock();
|
|
1363
1358
|
buffer.retain(|(k, _)| k != &key);
|
|
1364
1359
|
}
|
|
1365
1360
|
|
|
1366
1361
|
// Also remove from storage
|
|
1367
1362
|
if self.config.persist_mode != PersistMode::Memory {
|
|
1368
|
-
let
|
|
1369
|
-
if let Some(ref mut storage) = *storage_guard {
|
|
1363
|
+
if let Some(ref storage) = self.storage {
|
|
1370
1364
|
let _ = storage.delete(&key);
|
|
1371
1365
|
}
|
|
1372
1366
|
}
|
|
@@ -1424,8 +1418,7 @@ impl DictSQLiteV4 {
|
|
|
1424
1418
|
}
|
|
1425
1419
|
|
|
1426
1420
|
// 3. ストレージからキャッシュミスを取得
|
|
1427
|
-
let
|
|
1428
|
-
if let Some(ref storage) = *storage_guard {
|
|
1421
|
+
if let Some(ref storage) = self.storage {
|
|
1429
1422
|
for key in cache_misses {
|
|
1430
1423
|
if let Ok(Some(value)) = storage.get(&key) {
|
|
1431
1424
|
let data = if let Some(ref crypto) = self.crypto {
|
|
@@ -1463,7 +1456,7 @@ impl DictSQLiteV4 {
|
|
|
1463
1456
|
|
|
1464
1457
|
// WriteThroughモードではバッファに追加
|
|
1465
1458
|
if self.config.persist_mode == PersistMode::WriteThrough {
|
|
1466
|
-
let mut buffer = self.write_buffer.lock()
|
|
1459
|
+
let mut buffer = self.write_buffer.lock();
|
|
1467
1460
|
buffer.push((key, data));
|
|
1468
1461
|
}
|
|
1469
1462
|
}
|
|
@@ -1489,8 +1482,7 @@ impl DictSQLiteV4 {
|
|
|
1489
1482
|
|
|
1490
1483
|
// Also get keys from storage if not in memory-only mode
|
|
1491
1484
|
if self.config.persist_mode != PersistMode::Memory {
|
|
1492
|
-
let
|
|
1493
|
-
if let Some(ref storage) = *storage_guard {
|
|
1485
|
+
if let Some(ref storage) = self.storage {
|
|
1494
1486
|
if let Ok(storage_keys) = storage.keys() {
|
|
1495
1487
|
all_keys.extend(storage_keys);
|
|
1496
1488
|
}
|
|
@@ -1508,8 +1500,7 @@ impl DictSQLiteV4 {
|
|
|
1508
1500
|
let mut all_items: HashMap<String, Vec<u8>> = HashMap::new();
|
|
1509
1501
|
|
|
1510
1502
|
if self.config.persist_mode != PersistMode::Memory {
|
|
1511
|
-
let
|
|
1512
|
-
if let Some(ref storage) = *storage_guard {
|
|
1503
|
+
if let Some(ref storage) = self.storage {
|
|
1513
1504
|
if let Ok(keys) = storage.keys() {
|
|
1514
1505
|
for key in keys {
|
|
1515
1506
|
if let Ok(Some(value)) = storage.get(&key) {
|
|
@@ -1548,8 +1539,7 @@ impl DictSQLiteV4 {
|
|
|
1548
1539
|
let mut all_items: HashMap<String, Vec<u8>> = HashMap::new();
|
|
1549
1540
|
|
|
1550
1541
|
if self.config.persist_mode != PersistMode::Memory {
|
|
1551
|
-
let
|
|
1552
|
-
if let Some(ref storage) = *storage_guard {
|
|
1542
|
+
if let Some(ref storage) = self.storage {
|
|
1553
1543
|
if let Ok(keys) = storage.keys() {
|
|
1554
1544
|
for key in keys {
|
|
1555
1545
|
if let Ok(Some(value)) = storage.get(&key) {
|
|
@@ -1589,7 +1579,7 @@ impl DictSQLiteV4 {
|
|
|
1589
1579
|
#[pyo3(signature = (key, default=None))]
|
|
1590
1580
|
fn pop(&self, key: String, default: Option<Vec<u8>>, py: Python) -> PyResult<Py<PyAny>> {
|
|
1591
1581
|
// Track that we're removing this
|
|
1592
|
-
self.access_tracker.lock().
|
|
1582
|
+
self.access_tracker.lock().pop(&key);
|
|
1593
1583
|
|
|
1594
1584
|
if let Some((_, value)) = self.hot_tier.remove(&key) {
|
|
1595
1585
|
let data = if let Some(ref crypto) = self.crypto {
|
|
@@ -1604,8 +1594,7 @@ impl DictSQLiteV4 {
|
|
|
1604
1594
|
|
|
1605
1595
|
// Also try to remove from storage if it exists there
|
|
1606
1596
|
if self.config.persist_mode != PersistMode::Memory {
|
|
1607
|
-
let
|
|
1608
|
-
if let Some(ref mut storage) = *storage_guard {
|
|
1597
|
+
if let Some(ref storage) = self.storage {
|
|
1609
1598
|
if let Ok(Some(value)) = storage.get(&key) {
|
|
1610
1599
|
// Delete from storage
|
|
1611
1600
|
let _ = storage.delete(&key);
|
|
@@ -1642,8 +1631,7 @@ impl DictSQLiteV4 {
|
|
|
1642
1631
|
|
|
1643
1632
|
// Not in hot tier, check storage
|
|
1644
1633
|
if self.config.persist_mode != PersistMode::Memory {
|
|
1645
|
-
let
|
|
1646
|
-
if let Some(ref storage) = *storage_guard {
|
|
1634
|
+
if let Some(ref storage) = self.storage {
|
|
1647
1635
|
if let Ok(Some(value)) = storage.get(&key) {
|
|
1648
1636
|
let data = if let Some(ref crypto) = self.crypto {
|
|
1649
1637
|
crypto.decrypt(&value).map_err(|e| {
|
|
@@ -1652,7 +1640,6 @@ impl DictSQLiteV4 {
|
|
|
1652
1640
|
} else {
|
|
1653
1641
|
value.clone()
|
|
1654
1642
|
};
|
|
1655
|
-
drop(storage_guard);
|
|
1656
1643
|
// Promote to hot tier
|
|
1657
1644
|
self.hot_tier.insert(key, value);
|
|
1658
1645
|
return Ok(PyBytes::new(py, &data).into());
|
|
@@ -1702,8 +1689,7 @@ impl DictSQLiteV4 {
|
|
|
1702
1689
|
|
|
1703
1690
|
// Also get keys from storage if not in memory-only mode
|
|
1704
1691
|
if self.config.persist_mode != PersistMode::Memory {
|
|
1705
|
-
let
|
|
1706
|
-
if let Some(ref storage) = *storage_guard {
|
|
1692
|
+
if let Some(ref storage) = self.storage {
|
|
1707
1693
|
if let Ok(storage_keys) = storage.keys() {
|
|
1708
1694
|
for key in storage_keys {
|
|
1709
1695
|
// Apply same filtering logic
|
|
@@ -1741,8 +1727,7 @@ impl DictSQLiteV4 {
|
|
|
1741
1727
|
|
|
1742
1728
|
// Then check storage
|
|
1743
1729
|
if self.config.persist_mode != PersistMode::Memory {
|
|
1744
|
-
let
|
|
1745
|
-
if let Some(ref storage) = *storage_guard {
|
|
1730
|
+
if let Some(ref storage) = self.storage {
|
|
1746
1731
|
if let Ok(Some(_)) = storage.get(&full_key) {
|
|
1747
1732
|
return Ok(true);
|
|
1748
1733
|
}
|
|
@@ -1758,12 +1743,11 @@ impl DictSQLiteV4 {
|
|
|
1758
1743
|
self.hot_tier.clear();
|
|
1759
1744
|
|
|
1760
1745
|
// Clear write buffer to prevent pending writes from re-populating the database
|
|
1761
|
-
self.write_buffer.lock().
|
|
1746
|
+
self.write_buffer.lock().clear();
|
|
1762
1747
|
|
|
1763
1748
|
// Clear storage if not in memory-only mode
|
|
1764
1749
|
if self.config.persist_mode != PersistMode::Memory {
|
|
1765
|
-
let
|
|
1766
|
-
if let Some(ref mut storage) = *storage_guard {
|
|
1750
|
+
if let Some(ref storage) = self.storage {
|
|
1767
1751
|
storage.clear().map_err(|e| {
|
|
1768
1752
|
PyErr::new::<pyo3::exceptions::PyRuntimeError, _>(format!(
|
|
1769
1753
|
"Failed to clear storage: {}",
|
|
@@ -1986,8 +1970,7 @@ impl DictSQLiteV4 {
|
|
|
1986
1970
|
tables.insert("main".to_string());
|
|
1987
1971
|
Ok(tables.into_iter().collect())
|
|
1988
1972
|
} else {
|
|
1989
|
-
let
|
|
1990
|
-
if let Some(ref storage) = *storage_guard {
|
|
1973
|
+
if let Some(ref storage) = self.storage {
|
|
1991
1974
|
storage.list_tables().map_err(|e| {
|
|
1992
1975
|
PyErr::new::<pyo3::exceptions::PyIOError, _>(e.to_string())
|
|
1993
1976
|
})
|
|
@@ -2042,12 +2025,10 @@ impl TableProxy {
|
|
|
2042
2025
|
}
|
|
2043
2026
|
} else {
|
|
2044
2027
|
// Check storage
|
|
2045
|
-
let
|
|
2046
|
-
if let Some(ref storage) = *storage_guard {
|
|
2028
|
+
if let Some(ref storage) = db.storage {
|
|
2047
2029
|
match storage.get_with_table(&self.table_name, &key) {
|
|
2048
2030
|
Ok(Some(value)) => {
|
|
2049
2031
|
// Promote to hot tier
|
|
2050
|
-
drop(storage_guard);
|
|
2051
2032
|
db.hot_tier.insert(cache_key, value.clone());
|
|
2052
2033
|
// Decrypt if needed
|
|
2053
2034
|
if let Some(ref crypto) = db.crypto {
|
|
@@ -2167,12 +2148,11 @@ impl TableProxy {
|
|
|
2167
2148
|
// Update hot tier
|
|
2168
2149
|
db.hot_tier
|
|
2169
2150
|
.insert(cache_key.clone(), encrypted_data.clone());
|
|
2170
|
-
db.access_tracker.lock().
|
|
2151
|
+
db.access_tracker.lock().put(cache_key, ());
|
|
2171
2152
|
|
|
2172
2153
|
// Write to storage in WriteThrough mode
|
|
2173
2154
|
if db.config.persist_mode == PersistMode::WriteThrough {
|
|
2174
|
-
let
|
|
2175
|
-
if let Some(ref mut storage) = *storage_guard {
|
|
2155
|
+
if let Some(ref storage) = db.storage {
|
|
2176
2156
|
storage
|
|
2177
2157
|
.set_with_table(&self.table_name, &key, &encrypted_data)
|
|
2178
2158
|
.map_err(|e| {
|
|
@@ -2199,13 +2179,12 @@ impl TableProxy {
|
|
|
2199
2179
|
let cache_key = format!("{}:{}", self.table_name, key);
|
|
2200
2180
|
|
|
2201
2181
|
// Remove from hot tier
|
|
2202
|
-
db.access_tracker.lock().
|
|
2182
|
+
db.access_tracker.lock().pop(&cache_key);
|
|
2203
2183
|
db.hot_tier.remove(&cache_key);
|
|
2204
2184
|
|
|
2205
2185
|
// Remove from storage
|
|
2206
2186
|
if db.config.persist_mode != PersistMode::Memory {
|
|
2207
|
-
let
|
|
2208
|
-
if let Some(ref mut storage) = *storage_guard {
|
|
2187
|
+
if let Some(ref storage) = db.storage {
|
|
2209
2188
|
let _ = storage.delete_with_table(&self.table_name, &key);
|
|
2210
2189
|
}
|
|
2211
2190
|
}
|
|
@@ -2234,8 +2213,7 @@ impl TableProxy {
|
|
|
2234
2213
|
|
|
2235
2214
|
// Check storage
|
|
2236
2215
|
if db.config.persist_mode != PersistMode::Memory {
|
|
2237
|
-
let
|
|
2238
|
-
if let Some(ref storage) = *storage_guard {
|
|
2216
|
+
if let Some(ref storage) = db.storage {
|
|
2239
2217
|
if let Ok(Some(_)) = storage.get_with_table(&self.table_name, &key) {
|
|
2240
2218
|
return Ok(true);
|
|
2241
2219
|
}
|
|
@@ -2282,8 +2260,7 @@ impl TableProxy {
|
|
|
2282
2260
|
|
|
2283
2261
|
// Get keys from storage
|
|
2284
2262
|
if db.config.persist_mode != PersistMode::Memory {
|
|
2285
|
-
let
|
|
2286
|
-
if let Some(ref storage) = *storage_guard {
|
|
2263
|
+
if let Some(ref storage) = db.storage {
|
|
2287
2264
|
if let Ok(storage_keys) = storage.keys_with_table(&self.table_name) {
|
|
2288
2265
|
all_keys.extend(storage_keys);
|
|
2289
2266
|
}
|
|
@@ -2399,13 +2376,12 @@ impl TableProxy {
|
|
|
2399
2376
|
|
|
2400
2377
|
for key in keys_to_remove {
|
|
2401
2378
|
db.hot_tier.remove(&key);
|
|
2402
|
-
db.access_tracker.lock().
|
|
2379
|
+
db.access_tracker.lock().pop(&key);
|
|
2403
2380
|
}
|
|
2404
2381
|
|
|
2405
2382
|
// Clear storage table
|
|
2406
2383
|
if db.config.persist_mode != PersistMode::Memory {
|
|
2407
|
-
let
|
|
2408
|
-
if let Some(ref mut storage) = *storage_guard {
|
|
2384
|
+
if let Some(ref storage) = db.storage {
|
|
2409
2385
|
storage.clear_table(&self.table_name).map_err(|e| {
|
|
2410
2386
|
PyErr::new::<pyo3::exceptions::PyIOError, _>(e.to_string())
|
|
2411
2387
|
})?;
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|