-
Notifications
You must be signed in to change notification settings - Fork 1.4k
feat: expose various low level memory management menthods #3895
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
adriangb
wants to merge
3
commits into
launchbadge:main
Choose a base branch
from
adriangb:expose-memory-functions
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from 2 commits
Commits
Show all changes
3 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -12,8 +12,14 @@ use futures_core::future::BoxFuture; | |
use futures_intrusive::sync::MutexGuard; | ||
use futures_util::future; | ||
use libsqlite3_sys::{ | ||
sqlite3, sqlite3_commit_hook, sqlite3_get_autocommit, sqlite3_progress_handler, | ||
sqlite3_rollback_hook, sqlite3_update_hook, SQLITE_DELETE, SQLITE_INSERT, SQLITE_UPDATE, | ||
sqlite3, sqlite3_commit_hook, sqlite3_db_release_memory, sqlite3_db_status, | ||
sqlite3_get_autocommit, sqlite3_progress_handler, sqlite3_rollback_hook, | ||
sqlite3_soft_heap_limit64, sqlite3_update_hook, SQLITE_DBSTATUS_CACHE_HIT, | ||
SQLITE_DBSTATUS_CACHE_MISS, SQLITE_DBSTATUS_CACHE_USED, SQLITE_DBSTATUS_CACHE_USED_SHARED, | ||
SQLITE_DBSTATUS_CACHE_WRITE, SQLITE_DBSTATUS_DEFERRED_FKS, SQLITE_DBSTATUS_LOOKASIDE_HIT, | ||
SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL, SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE, | ||
SQLITE_DBSTATUS_LOOKASIDE_USED, SQLITE_DBSTATUS_SCHEMA_USED, SQLITE_DBSTATUS_STMT_USED, | ||
SQLITE_DELETE, SQLITE_INSERT, SQLITE_OK, SQLITE_UPDATE, | ||
}; | ||
#[cfg(feature = "preupdate-hook")] | ||
pub use preupdate_hook::*; | ||
|
@@ -77,6 +83,54 @@ pub enum SqliteOperation { | |
Unknown(i32), | ||
} | ||
|
||
/// Database status parameters for the sqlite3_db_status function. | ||
#[derive(Debug, PartialEq, Eq, Clone, Copy)] | ||
pub enum SqliteDatabaseStatus { | ||
/// Current number of bytes used by lookaside allocations | ||
LookasideUsed, | ||
/// Current number of bytes of pager cache used | ||
CacheUsed, | ||
/// Current number of bytes used by the schema | ||
SchemaUsed, | ||
/// Current number of bytes used by prepared statements | ||
StmtUsed, | ||
/// Number of lookaside malloc hits | ||
LookasideHit, | ||
/// Number of lookaside malloc misses due to size | ||
LookasideMissSize, | ||
/// Number of lookaside malloc misses due to full buffer | ||
LookasideMissFull, | ||
/// Number of pager cache hits | ||
CacheHit, | ||
/// Number of pager cache misses | ||
CacheMiss, | ||
/// Number of dirty cache pages written | ||
CacheWrite, | ||
/// Number of foreign key constraint violations detected | ||
DeferredFks, | ||
/// Maximum cache used in shared cache mode | ||
CacheUsedShared, | ||
} | ||
|
||
impl From<SqliteDatabaseStatus> for i32 { | ||
fn from(status: SqliteDatabaseStatus) -> Self { | ||
match status { | ||
SqliteDatabaseStatus::LookasideUsed => SQLITE_DBSTATUS_LOOKASIDE_USED, | ||
SqliteDatabaseStatus::CacheUsed => SQLITE_DBSTATUS_CACHE_USED, | ||
SqliteDatabaseStatus::SchemaUsed => SQLITE_DBSTATUS_SCHEMA_USED, | ||
SqliteDatabaseStatus::StmtUsed => SQLITE_DBSTATUS_STMT_USED, | ||
SqliteDatabaseStatus::LookasideHit => SQLITE_DBSTATUS_LOOKASIDE_HIT, | ||
SqliteDatabaseStatus::LookasideMissSize => SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE, | ||
SqliteDatabaseStatus::LookasideMissFull => SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL, | ||
SqliteDatabaseStatus::CacheHit => SQLITE_DBSTATUS_CACHE_HIT, | ||
SqliteDatabaseStatus::CacheMiss => SQLITE_DBSTATUS_CACHE_MISS, | ||
SqliteDatabaseStatus::CacheWrite => SQLITE_DBSTATUS_CACHE_WRITE, | ||
SqliteDatabaseStatus::DeferredFks => SQLITE_DBSTATUS_DEFERRED_FKS, | ||
SqliteDatabaseStatus::CacheUsedShared => SQLITE_DBSTATUS_CACHE_USED_SHARED, | ||
} | ||
} | ||
} | ||
|
||
impl From<i32> for SqliteOperation { | ||
fn from(value: i32) -> Self { | ||
match value { | ||
|
@@ -557,6 +611,64 @@ impl LockedSqliteHandle<'_> { | |
let ret = unsafe { sqlite3_get_autocommit(self.as_raw_handle().as_ptr()) }; | ||
ret == 0 | ||
} | ||
|
||
/// Sets the soft heap limit for the current thread. | ||
/// | ||
/// This function sets a soft limit on the amount of heap memory that can be allocated by SQLite. | ||
/// The limit is in bytes. If `limit` is zero, the heap limit is disabled. | ||
/// | ||
/// Returns the previous heap limit. If the heap limit was never set, returns 0. | ||
/// | ||
/// See: https://www.sqlite.org/c3ref/hard_heap_limit64.html | ||
pub fn soft_heap_limit(&mut self, limit: i64) -> i64 { | ||
unsafe { sqlite3_soft_heap_limit64(limit) } | ||
} | ||
|
||
/// Retrieves statistics about a database connection. | ||
/// | ||
/// This function is used to retrieve runtime status information about a single database connection. | ||
/// The `status` parameter determines which statistic to retrieve. | ||
/// | ||
/// Returns a tuple containing `(current_value, highest_value_since_reset)`. | ||
/// If `reset` is true, the highest value is reset to the current value after retrieval. | ||
/// | ||
/// See: https://www.sqlite.org/c3ref/db_status.html | ||
pub fn db_status( | ||
&mut self, | ||
status: SqliteDatabaseStatus, | ||
reset: bool, | ||
) -> Result<(i32, i32), Error> { | ||
let mut current = 0i32; | ||
let mut highest = 0i32; | ||
|
||
let result = unsafe { | ||
sqlite3_db_status( | ||
self.as_raw_handle().as_ptr(), | ||
status.into(), | ||
&mut current, | ||
&mut highest, | ||
if reset { 1 } else { 0 }, | ||
) | ||
}; | ||
|
||
if result == SQLITE_OK { | ||
Ok((current, highest)) | ||
} else { | ||
Err(self.guard.handle.expect_error().into()) | ||
} | ||
} | ||
|
||
/// Attempts to free as much heap memory as possible from the database connection. | ||
/// | ||
/// This function causes SQLite to release some memory used by the database connection, | ||
/// such as memory used to cache prepared statements. | ||
/// | ||
/// Returns the number of bytes of memory released. | ||
/// | ||
/// See: https://www.sqlite.org/c3ref/release_memory.html | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This links to the wrong page. It should be: https://www.sqlite.org/c3ref/db_release_memory.html |
||
pub fn db_release_memory(&mut self) -> i32 { | ||
unsafe { sqlite3_db_release_memory(self.as_raw_handle().as_ptr()) } | ||
} | ||
} | ||
|
||
impl Drop for ConnectionState { | ||
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The very first line of the linked documentation says:
So saying it sets it for the current thread, or having it as a method on the connection. is very misleading.
It should be a free function, or perhaps an associated method of the
Sqlite
type. Probably a free function.Passing a negative number just gets the heap limit and doesn't set it, which also needs to be documented.
A more Rust-y API would be something like
limit: Option<NonZeroU64>
, returning an error if it's greater thani64::MAX
(or using a wrapper type with fallible constructors), and providing a separate getter function, but I don't know if we need to go that far. I'd kind of like to sleep on it, though.