Skip to content

Commit

Permalink
feat(calculate_hash): allow to customize hash input
Browse files Browse the repository at this point in the history
  • Loading branch information
sebffischer committed Jan 22, 2024
1 parent 74e1661 commit 3fe7ce1
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 11 deletions.
4 changes: 4 additions & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ S3method(discard,default)
S3method(distinct_values,default)
S3method(distinct_values,factor)
S3method(distinct_values,logical)
S3method(hash_input,"function")
S3method(hash_input,data.table)
S3method(hash_input,default)
S3method(insert_named,"NULL")
S3method(insert_named,data.frame)
S3method(insert_named,data.table)
Expand Down Expand Up @@ -82,6 +85,7 @@ export(formulate)
export(get_private)
export(get_seed)
export(has_element)
export(hash_input)
export(ids)
export(imap)
export(imap_chr)
Expand Down
42 changes: 32 additions & 10 deletions R/calculate_hash.R
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,11 @@
#'
#' @description
#' Calls [digest::digest()] to calculate the hash for all objects provided.
#' The hash is calculated using the [xxhash64] algorithm.
#' By specifying methods for the [`hash_input`] generic, you can control which information of an object
#' is used to calculate the hash.
#'
#' The following operations are performed to make hashing more robust:
#' Methods exist for:
#' * If an object is a [function()], the formals and the body are hashed separately.
#' This ensures that the bytecode or parent environment are not be included
#' in the hash.
Expand All @@ -21,13 +24,32 @@
#' @examples
#' calculate_hash(iris, 1, "a")
calculate_hash = function(...) {
digest(lapply(list(...), function(x) {
if (is.function(x)) {
list(formals(x), as.character(body(x)))
} else if (is.data.table(x)) {
as.list(x)
} else {
x
}
}), algo = "xxhash64")
digest(lapply(list(...), hash_info), algo = "xxhash64")
}

#' Hash Input
#'
#' Returns the information of an object to be used to calculate its hash.
#' @param x (any)\cr
#' Object for which to calculate the hash.
#' @export
hash_input = function(x) {
UseMethod("hash_input")
}

#' @export
hash_input.function = function(x) {
list(formals(x), as.character(body(x)))
}

#' @export
#' @method hash_input data.table
hash_input.data.table = function(x) {
as.list(x)
}

#' @export
hash_input.default = function(x) {
x
}

5 changes: 4 additions & 1 deletion man/calculate_hash.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 15 additions & 0 deletions man/hash_input.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 3fe7ce1

Please sign in to comment.