diff --git a/DESCRIPTION b/DESCRIPTION
index 2a38519..7ec7d37 100644
--- a/DESCRIPTION
+++ b/DESCRIPTION
@@ -1,6 +1,6 @@
Package: storr.tiledb
Title: A TileDB Storage Driver for Storr
-Version: 0.0.39
+Version: 0.0.40
Date: 2026-05-21
Authors@R:
person("Constantinos", "Giachalis", , "xx@github.com", role = c("aut", "cre"))
diff --git a/NEWS.md b/NEWS.md
index b9ac05f..b304e22 100644
--- a/NEWS.md
+++ b/NEWS.md
@@ -1,3 +1,3 @@
-# storr.tiledb 0.0.39
+# storr.tiledb 0.0.40
* Initial GitHub release.
diff --git a/R/StorrTimeTravel.R b/R/StorrTimeTravel.R
index 959e366..326ce7f 100644
--- a/R/StorrTimeTravel.R
+++ b/R/StorrTimeTravel.R
@@ -347,6 +347,16 @@ StorrTimeTravel <- R6::R6Class(
sort(private$DRIVER$list_hashes())
},
+ #' @description List unused hashes stored in the storr.
+ #'
+ #'
+ #' @return A sorted character vector with unused hashes.
+ #'
+ list_unused_hashes = function() {
+
+ sort(private$DRIVER$list_unused_hashes())
+ },
+
#' @description List all namespaces in the storr.
#'
#'
diff --git a/R/TileDBStorr.R b/R/TileDBStorr.R
index e3c72fb..722709e 100644
--- a/R/TileDBStorr.R
+++ b/R/TileDBStorr.R
@@ -1862,6 +1862,16 @@ TileDBStorr <- R6::R6Class(
sort(private$DRIVER$list_hashes())
},
+ #' @description List unused hashes stored in the storr.
+ #'
+ #'
+ #' @return A sorted character vector with unused hashes.
+ #'
+ list_unused_hashes = function() {
+
+ sort(private$DRIVER$list_unused_hashes())
+ },
+
#' @description List all namespaces in the storr.
#'
#'
diff --git a/R/storr_tiledb.R b/R/storr_tiledb.R
index 83a2106..3214bff 100644
--- a/R/storr_tiledb.R
+++ b/R/storr_tiledb.R
@@ -109,6 +109,7 @@
#'
#' - **`list()`** - List all keys in a namespace
#' - **`list_hashes()`** - List all stored object hashes
+#' - **`list_unused_hashes()`** - List all stored object unused hashes
#' - **`list_namespaces()`** - List all namespaces
#'
#' **Storage Management**
diff --git a/R/storr_timetravel.R b/R/storr_timetravel.R
index d21cba4..a602e45 100644
--- a/R/storr_timetravel.R
+++ b/R/storr_timetravel.R
@@ -52,6 +52,7 @@
#'
#' - **`list()`** - List all keys in a namespace
#' - **`list_hashes()`** - List all stored object hashes
+#' - **`list_unused_hashes()`** - List all stored object unused hashes
#' - **`list_namespaces()`** - List all namespaces
#'
#' **Storage Management**
diff --git a/man/StorrTimeTravel.Rd b/man/StorrTimeTravel.Rd
index f5bda4b..b11ca21 100644
--- a/man/StorrTimeTravel.Rd
+++ b/man/StorrTimeTravel.Rd
@@ -51,6 +51,7 @@ the resource will be opened at. Effective in \code{"READ"} mode only.}
\item \href{#method-StorrTimeTravel-has_expired_keys}{\code{StorrTimeTravel$has_expired_keys()}}
\item \href{#method-StorrTimeTravel-list}{\code{StorrTimeTravel$list()}}
\item \href{#method-StorrTimeTravel-list_hashes}{\code{StorrTimeTravel$list_hashes()}}
+ \item \href{#method-StorrTimeTravel-list_unused_hashes}{\code{StorrTimeTravel$list_unused_hashes()}}
\item \href{#method-StorrTimeTravel-list_namespaces}{\code{StorrTimeTravel$list_namespaces()}}
\item \href{#method-StorrTimeTravel-export}{\code{StorrTimeTravel$export()}}
\item \href{#method-StorrTimeTravel-index_export}{\code{StorrTimeTravel$index_export()}}
@@ -432,6 +433,21 @@ Default is \code{TRUE}.}
}
}
+\if{html}{\out{
}}
+\if{html}{\out{}}
+\if{latex}{\out{\hypertarget{method-StorrTimeTravel-list_unused_hashes}{}}}
+\subsection{\code{StorrTimeTravel$list_unused_hashes()}}{
+ List unused hashes stored in the storr.
+ \subsection{Usage}{
+ \if{html}{\out{}}
+ \preformatted{StorrTimeTravel$list_unused_hashes()}
+ \if{html}{\out{
}}
+ }
+ \subsection{Returns}{
+ A sorted character vector with unused hashes.
+ }
+}
+
\if{html}{\out{
}}
\if{html}{\out{}}
\if{latex}{\out{\hypertarget{method-StorrTimeTravel-list_namespaces}{}}}
diff --git a/man/TileDBStorr.Rd b/man/TileDBStorr.Rd
index ce297a8..40dbd6c 100644
--- a/man/TileDBStorr.Rd
+++ b/man/TileDBStorr.Rd
@@ -94,6 +94,7 @@ usage is through \code{\link[=storr_tiledb]{storr_tiledb()}}.
\item \href{#method-TileDBStorr-clear_expired_keys}{\code{TileDBStorr$clear_expired_keys()}}
\item \href{#method-TileDBStorr-list}{\code{TileDBStorr$list()}}
\item \href{#method-TileDBStorr-list_hashes}{\code{TileDBStorr$list_hashes()}}
+ \item \href{#method-TileDBStorr-list_unused_hashes}{\code{TileDBStorr$list_unused_hashes()}}
\item \href{#method-TileDBStorr-list_namespaces}{\code{TileDBStorr$list_namespaces()}}
\item \href{#method-TileDBStorr-gc}{\code{TileDBStorr$gc()}}
\item \href{#method-TileDBStorr-import}{\code{TileDBStorr$import()}}
@@ -1231,6 +1232,21 @@ Default is \code{TRUE}.}
}
}
+\if{html}{\out{
}}
+\if{html}{\out{}}
+\if{latex}{\out{\hypertarget{method-TileDBStorr-list_unused_hashes}{}}}
+\subsection{\code{TileDBStorr$list_unused_hashes()}}{
+ List unused hashes stored in the storr.
+ \subsection{Usage}{
+ \if{html}{\out{}}
+ \preformatted{TileDBStorr$list_unused_hashes()}
+ \if{html}{\out{
}}
+ }
+ \subsection{Returns}{
+ A sorted character vector with unused hashes.
+ }
+}
+
\if{html}{\out{
}}
\if{html}{\out{}}
\if{latex}{\out{\hypertarget{method-TileDBStorr-list_namespaces}{}}}
diff --git a/man/storr_tiledb.Rd b/man/storr_tiledb.Rd
index b771d81..33870b8 100644
--- a/man/storr_tiledb.Rd
+++ b/man/storr_tiledb.Rd
@@ -148,6 +148,7 @@ For complete definitions, see \strong{Methods} section in \link{TileDBStorr}.
\itemize{
\item \strong{\code{list()}} - List all keys in a namespace
\item \strong{\code{list_hashes()}} - List all stored object hashes
+\item \strong{\code{list_unused_hashes()}} - List all stored object unused hashes
\item \strong{\code{list_namespaces()}} - List all namespaces
}
diff --git a/man/storr_timetravel.Rd b/man/storr_timetravel.Rd
index 601c7e8..9845d3f 100644
--- a/man/storr_timetravel.Rd
+++ b/man/storr_timetravel.Rd
@@ -88,6 +88,7 @@ For complete definitions, see \strong{Methods} section in \link{StorrTimeTravel}
\itemize{
\item \strong{\code{list()}} - List all keys in a namespace
\item \strong{\code{list_hashes()}} - List all stored object hashes
+\item \strong{\code{list_unused_hashes()}} - List all stored object unused hashes
\item \strong{\code{list_namespaces()}} - List all namespaces
}
diff --git a/tests/testthat/test-StorrTimeTravel.R b/tests/testthat/test-StorrTimeTravel.R
index 4b55f19..68df006 100644
--- a/tests/testthat/test-StorrTimeTravel.R
+++ b/tests/testthat/test-StorrTimeTravel.R
@@ -78,6 +78,46 @@ test_that("'get'/'mget' with time-travel", {
})
+test_that("'list_unsed_hashes' with time-travel", {
+
+ uri <- file.path(withr::local_tempdir(), "test-storr")
+ sto <- storr_tiledb(uri, init = TRUE, default_namespace = "ns1")
+
+ t0 <- Sys.time()
+ sto$mset(c("a", "b"), 1:2)
+ t1 <- Sys.time()
+ del_hash <- sto$get_hash("a")
+ sto$del("a")
+ sto$set("b", 3, namespace = "ns2")
+ t2 <- Sys.time()
+
+ sto$gc()
+ t3 <- Sys.time()
+
+ hashes <- sto$list_hashes()
+
+ # Open at t0 ---
+ stott <- storr_timetravel(uri, timestamp = t0, default_namespace = "ns1")
+
+ # Expect nothing at t0
+ expect_equal(stott$list_hashes(), character())
+
+ # Open at t1
+ stott$timestamp <- t1
+ expect_equal(stott$mget(c("a", "b")), list(1, 2))
+ expect_length(stott$list_hashes(), 2)
+
+ # Open at t2
+ stott$timestamp <- t2
+ expect_equal(stott$list_unused_hashes(), del_hash)
+ expect_length(stott$list_hashes(), 3)
+
+ stott$timestamp <- t3
+ expect_equal(stott$list_unused_hashes(), character(0))
+ expect_length(stott$list_hashes(), 2)
+
+})
+
test_that("'get_keymeta'/'mget_keymeta' and friends with time-travel", {
uri <- file.path(withr::local_tempdir(), "test-storr")
@@ -246,7 +286,6 @@ test_that("'export_tdb' with time-travel", {
expect_warning(stott$export_tdb(uri_dest = uri2), class = "warning",
"Nothing to export for the selected key-namespace.")
-
# Open at t1
stott$timestamp <- t1
expect_no_error(stott$export_tdb(uri_dest = uri2))
diff --git a/tests/testthat/test-storr_tiledb.R b/tests/testthat/test-storr_tiledb.R
index b259816..9e691e8 100644
--- a/tests/testthat/test-storr_tiledb.R
+++ b/tests/testthat/test-storr_tiledb.R
@@ -167,3 +167,23 @@ test_that("cache global option", {
expect_equal(numhash(sto$envir_metadata), 2)
})
+
+
+test_that("'list_unused_hashes'", {
+
+ uri <- file.path(withr::local_tempdir(), "test-driver")
+ sto <- storr_tiledb(uri, init = TRUE)
+
+ sto$mset(letters[1:3], 1:3)
+
+ sto$del("a")
+
+ expect_length(sto$list_hashes(), 3)
+ expect_equal(sto$list_unused_hashes(), "9dc695ac953ca975b83c673f7144cffb")
+
+ sto$gc()
+ expect_length(sto$list_hashes(), 2)
+
+ expect_equal(sto$list_unused_hashes(), character(0))
+
+})