-
Notifications
You must be signed in to change notification settings - Fork 198
Switch the fingerprint algo to xxh3_128 #1630
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
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -33,13 +33,15 @@ | |
| implementation should pass the `depth` parameter to prevent `RecursionError`. | ||
| """ | ||
|
|
||
| from __future__ import annotations | ||
|
|
||
| import base64 | ||
| import datetime | ||
| import functools | ||
| import hashlib | ||
| import logging | ||
| import sys | ||
| from collections.abc import Mapping, Sequence, Set | ||
| from typing import TYPE_CHECKING | ||
|
|
||
| from hamilton.experimental import h_databackends | ||
|
|
||
|
|
@@ -49,6 +51,31 @@ | |
| except ImportError: | ||
| NoneType = type(None) | ||
|
|
||
| if TYPE_CHECKING: | ||
| from collections.abc import Buffer, Callable | ||
| from typing import Protocol | ||
|
|
||
| class Hash(Protocol): | ||
| def digest(self) -> bytes: ... | ||
|
|
||
|
|
||
| hash_func: Callable[[str | Buffer], Hash] | ||
| try: | ||
| # xxh3_128 produces a 16-byte digest (24 base64url chars, the same width as the | ||
| # md5 it replaces) while running substantially faster on buffer-bound paths. | ||
| # TODO(2.0): revisit once/if a dependency-free `apache-hamilton-core` package | ||
| # exists, so this optional performance dependency lands in the right tier. | ||
| import xxhash | ||
|
|
||
| hash_func = xxhash.xxh3_128 | ||
| except (ModuleNotFoundError, AttributeError): | ||
| # ModuleNotFoundError covers xxhash not being installed; AttributeError | ||
| # covers an xxhash older than 0.8.0 (which added xxh3_128). | ||
| # usedforsecurity=False avoids a ValueError on FIPS-mode Python; it | ||
| # doesn't change the digest. | ||
| import hashlib | ||
|
Comment on lines
+63
to
+76
Contributor
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. Do we need to an env variable to enable someone to opt-out of xxhash? Just thinking of the very small case where someone has it, but was using the old way... ?
Collaborator
Author
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. Valid case, I suppose. However: 1) I think there's nothing wrong with nudging users towards using what we consider better practices; 2) Cache was already invalidated by other recent changes, so impact on users should be minimal. |
||
|
|
||
| hash_func = functools.partial(hashlib.md5, usedforsecurity=False) | ||
|
Dev-iL marked this conversation as resolved.
|
||
|
|
||
| logger = logging.getLogger("hamilton.caching") | ||
|
|
||
|
|
@@ -81,8 +108,16 @@ def _hash_bytes(data: bytes) -> str: | |
|
|
||
| All hashing in this module routes through this single helper so the | ||
| underlying hashing algorithm can be changed in exactly one place. | ||
|
|
||
| Uses the non-cryptographic xxh3_128 algorithm when the optional | ||
| ``xxhash`` package is installed (see the ``performance`` extra), | ||
| falling back to hashlib's md5 otherwise. Both produce a 16-byte digest | ||
| (24 base64url chars), so digest width is unaffected either way, but the | ||
| two algorithms don't produce the same bytes for the same input: | ||
| fingerprints are stable within an environment, not across installs with | ||
| a different backend. | ||
| """ | ||
| return _compact_hash(hashlib.md5(data).digest()) | ||
| return _compact_hash(hash_func(data).digest()) | ||
|
|
||
|
|
||
| @functools.singledispatch | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.