Skip to content

Commit d94fb0f

Browse files
authored
Add hash() (#1058)
- Modelled after [xxhashlite](https://github.com/coolbutuseless/xxhashlite) from @coolbutuseless - Special thanks to the authors of the [xxHash](https://github.com/Cyan4973/xxHash) C library
1 parent b9b7ae2 commit d94fb0f

File tree

12 files changed

+5130
-0
lines changed

12 files changed

+5130
-0
lines changed

DESCRIPTION

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,14 @@ Description: A toolbox for working with base types, core R features
77
Authors@R: c(
88
person("Lionel", "Henry", ,"[email protected]", c("aut", "cre")),
99
person("Hadley", "Wickham", ,"[email protected]", "aut"),
10+
person(given = "mikefc",
11+
email = "[email protected]",
12+
role = "cph",
13+
comment = "Hash implementation based on Mike's xxhashlite"),
14+
person(given = "Yann",
15+
family = "Collet",
16+
role = "cph",
17+
comment = "Author of the embedded xxHash library"),
1018
person("RStudio", role = "cph")
1119
)
1220
License: MIT + file LICENSE

LICENSE.note

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
The implementation of `hash()` uses the xxHash library from Yann Collet, which
2+
is released under the BSD 2-Clause license. This library has been embedded into
3+
rlang, without modification, in `src/internal/xxhash/`. A copy of the
4+
BSD 2-Clause license is provided below.
5+
6+
BSD 2-Clause License -----------------------------------------------------------
7+
8+
xxHash Library
9+
Copyright (c) 2012-2020 Yann Collet
10+
All rights reserved.
11+
12+
BSD 2-Clause License (https://www.opensource.org/licenses/bsd-license.php)
13+
14+
Redistribution and use in source and binary forms, with or without modification,
15+
are permitted provided that the following conditions are met:
16+
17+
* Redistributions of source code must retain the above copyright notice, this
18+
list of conditions and the following disclaimer.
19+
20+
* Redistributions in binary form must reproduce the above copyright notice, this
21+
list of conditions and the following disclaimer in the documentation and/or
22+
other materials provided with the distribution.
23+
24+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
25+
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
26+
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
27+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
28+
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
29+
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
30+
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
31+
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32+
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33+
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

NAMESPACE

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,7 @@ export(global_env)
255255
export(global_frame)
256256
export(has_length)
257257
export(has_name)
258+
export(hash)
258259
export(have_name)
259260
export(inform)
260261
export(inherits_all)

NEWS.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
# rlang (development version)
22

3+
* New `hash()` function to generate 128-bit hashes for arbitrary R objects
4+
using the xxHash library. The implementation is modeled after
5+
[xxhashlite](https://github.com/coolbutuseless/xxhashlite), created
6+
by @coolbutuseless.
7+
38
* New `check_installed()` function. Unlike `is_installed()`, it asks
49
the user whether to install missing packages. If the user accepts,
510
the packages are installed with `pak::pkg_install()` if available,

R/hash.R

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
#' Hash an object
2+
#'
3+
#' @description
4+
#' `hash()` hashes an arbitrary R object.
5+
#'
6+
#' The generated hash is guaranteed to be reproducible across platforms, but
7+
#' not across R versions.
8+
#'
9+
#' @details
10+
#' `hash()` uses the XXH128 hash algorithm of the xxHash library, which
11+
#' generates a 128-bit hash. It is implemented as a streaming hash, which
12+
#' generates the hash with minimal extra memory usage.
13+
#'
14+
#' Objects are converted to binary using R's native serialization tools.
15+
#' On R >= 3.5.0, serialization version 3 is used, otherwise version 2 is used.
16+
#' See [serialize()] for more information about the serialization version.
17+
#'
18+
#' @param x An object.
19+
#'
20+
#' @export
21+
#' @examples
22+
#' hash(c(1, 2, 3))
23+
#' hash(mtcars)
24+
hash <- function(x) {
25+
.Call(rlang_hash, x)
26+
}

man/hash.Rd

Lines changed: 30 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/Makevars

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ internal-files = \
4141
internal/expr-interp.c \
4242
internal/expr-interp-rotate.c \
4343
internal/fn.c \
44+
internal/hash.c \
4445
internal/internal.c \
4546
internal/nse-defuse.c \
4647
internal/quo.c \

src/export/init.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,7 @@ extern sexp* rlang_raw_deparse_str(sexp*, sexp*, sexp*);
143143
extern sexp* rlang_env_browse(sexp*, sexp*);
144144
extern sexp* rlang_env_is_browsed(sexp*);
145145
extern sexp* rlang_ns_registry_env();
146+
extern sexp* rlang_hash(sexp*);
146147

147148

148149
// Library initialisation defined below
@@ -323,6 +324,7 @@ static const r_callable r_callables[] = {
323324
{"rlang_env_browse", (r_fn_ptr) &rlang_env_browse, 2},
324325
{"rlang_env_is_browsed", (r_fn_ptr) &rlang_env_is_browsed, 1},
325326
{"rlang_ns_registry_env", (r_fn_ptr) &rlang_ns_registry_env, 0},
327+
{"rlang_hash", (r_fn_ptr) &rlang_hash, 1},
326328
{NULL, NULL, 0}
327329
};
328330

src/internal.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include "internal/expr-interp.c"
1010
#include "internal/expr-interp-rotate.c"
1111
#include "internal/fn.c"
12+
#include "internal/hash.c"
1213
#include "internal/internal.c"
1314
#include "internal/nse-defuse.c"
1415
#include "internal/quo.c"

0 commit comments

Comments
 (0)