---
title: Re-Hash Operation Mechanisms
url: https://www.emergentmind.com/topics/re-hash-operation
type: topic
---

# Re-Hash Operation Mechanisms

A re-hash operation denotes a family of update procedures that modify a hash-derived state after a change in input data, bucket count, or table capacity. In the cited literature, the term covers several technically distinct mechanisms: consistent reassignment of keys when the number of buckets changes; homomorphic digest updates under document amendment or row replacement; deferred movement of entries during concurrent table growth; and incremental split-or-merge procedures during GPU resizing [2403.18682] [2502.13197] [2507.21096] [1509.02235] [2510.15095]. The common objective is to avoid a full recomputation while preserving the invariants required by the underlying scheme, such as uniformity and monotonicity, homomorphic correctness, collision resistance, or lock-free progress.

## 1. Definitions and invariants

In distributed key assignment, the relevant object is a consistent hash function \(CH(k,N)\) mapping a key \(k\) to one of \(N\) buckets. Two properties characterize the desired behavior: **Uniformity**, given by \(\Pr[CH(k,N)=b]=1/N\) for all \(b\in\{0\ldots N-1\}\), and **Monotonicity (minimal disruption)**, given by the rule that if \(CH(k,N)\neq CH(k,N+1)\), then \(CH(k,N+1)=N\) [2403.18682]. These properties formalize balanced placement together with minimal remapping when capacity increases.

In incremental cryptographic hashing, the invariant is homomorphic compatibility with concatenation or dataset deltas. For Cayley hashing, the defining relation is
\[
\forall\,X,Y\in\{0,1\}^*:\quad H(X\|\;Y)=H(X)\cdot H(Y),
\]
which permits direct update of an existing digest after appending a block \(P\) [2502.13197]. In HexaMorphHash, the invariant is linearity in \(\mathbb Z_q^n\): the digest is a modular vector sum over encoded rows, so insertion, deletion, and replacement are realized by coordinate-wise addition and subtraction [2507.21096].

In extensible hash tables, the invariant is structural correctness during resizing without a global pause. Anton Malakhov’s per-bucket concurrent rehashing algorithm separates resizing and rehashing so that they neither invalidate existing buckets nor block any concurrent operations; Hive adopts an analogous avoidance of global rehash on GPUs through incremental linear hashing in \(K\)-bucket batches [1509.02235] [2510.15095]. This suggests that “re-hash operation” is context-dependent: in some settings it is a digest update, in others a controlled relocation of entries, and in others a reassignment function that minimizes disruption.

## 2. Consistent reassignment under changing bucket counts

The simplest bucket-selection rule is
\[
h(k)\bmod N \to \text{bucket},
\]
which is uniform when \(h(k)\) is a high-quality 64-bit hash, but unstable under re-sharding. When \(N\to N+1\), the assignment becomes \(h(k)\bmod (N+1)\), which, for large \(N\), differs from \(h(k)\bmod N\) with probability \(N/(N+1)\to 1\); in practice, nearly all keys “jump,” causing massive data-movement storms, including cache-miss spikes and network bursts [2403.18682]. Modulo hashing is therefore uniform but not monotonic.

"JumpBackHash: Say Goodbye to the Modulo Operation to Distribute Keys Uniformly to Buckets" introduces an \(O(1)\)-expected-time consistent hash using only integer arithmetic and a single PRNG [2403.18682]. Its construction is based on “active indices,” defined as bucket indices that currently hold the minimum random number seen so far. Rather than scanning all possible indices, the method generates only the needed active indices in descending order from an upper power-of-two bound \(N_{\max}=2^L\) and stops as soon as one falls below \(N\). The algorithm consumes two initial 32-bit random values, forms a mask from \(r_0\oplus r_1\), explores flagged intervals, and refines candidates within \([2^m,2^{m+1})\) via geometric sampling. All operations—bit shifts, masks, and modulo \(2^m\)—are integer.

The method’s stability guarantee is explicit: when \(N\to N+1\), the only keys that change bucket are those whose new active index is the newly added bucket \(N\), so any given key has \(\Pr[\mathrm{remap}] = 1/(N+1)\), which is optimal by the “balanced mapping” lower bound [2403.18682]. The time analysis yields
\[
E[K]=2+\tfrac12\rho\in[2.5,3),
\]
where \(K\) is the number of PRG calls and \(\rho=2^{j_0}/N\in[1,2)\). By contrast, JumpConsistentHash takes on average \(H_N\approx \ln N\) random draws and thus \(O(\log N)\) time, while rendezvous hashing is monotonic but costs \(O(N)\) bucket evaluations per key. On Xeon Platinum with splitmix64 PRG and Java 21, benchmarks for \(N\) up to \(10^6\) report \(5\)–\(10\) ns/op for JumpBackHash, \(15\)–\(30\) ns/op for JumpConsistentHash, \(5\) ns/op for modulo, and \(2000\) ns/op for naive rendezvous [2403.18682].

## 3. Homomorphic re-hash in Cayley hash functions

Cayley hash functions encode a bit string as a product of generators in a semigroup or group. The surveyed construction takes
\[
S = SL_2(\mathbb F_p)
\]
for a large prime \(p\), and chooses
\[
A=\begin{pmatrix}1 & k\\ 0 & 1\end{pmatrix},
\qquad
B=\begin{pmatrix}1 & 0\\ k & 1\end{pmatrix},
\]
with \(k\ge 2\); the paper singles out \(k=2\) as a good compromise between efficiency and girth [2502.13197]. The bit \(0\) is associated with \(A\), the bit \(1\) with \(B\), and for \(w=x_1x_2\cdots x_n\in\{0,1\}^n\),
\[
H(w)=\prod_{i=1}^n A^{1-x_i}B^{x_i}\in S.
\]
If the ambient structure is a group, one may set \(H(\varepsilon)=e\) for the empty string.

The re-hash operation is a direct consequence of the homomorphic property
\[
H(X\|\;Y)=H(X)\cdot H(Y).
\]
If a document \(D\) has already been hashed to \(H(D)\) and a new block \(P\) is appended or used to amend it, one computes \(H(P)\) and updates by
\[
H(D\|\;P)=H(D)\cdot H(P).
\]
If one chooses a right-to-left convention instead, the update becomes \(H(D\|\;P)=H(P)\,H(D)\); the choice of left- or right-multiplication is explicitly described as a matter of convention [2502.13197].

The security constraints are expressed through girth and joint spectral radius. Collision resistance up to length \(L\) is equivalent to the absence of a nontrivial relation of length \(<L\) among \(A,B\) in \(S\). In Cayley-graph language, the girth of the directed Cayley graph of \(\langle A,B\rangle\subset SL_2(\mathbb F_p)\) with generators \(\{A,B\}\) must exceed the maximum message-block length intended without re-randomization [2502.13197]. If \(A,B\) lift to a free semigroup in \(SL_2(\mathbb Z)\) and have joint spectral radius \(\rho\), then
\[
\text{girth}\approx \frac{\log p}{\log \rho}.
\]
For \((A(2),B(2))\), \(\rho=1+\sqrt 2\), and with a 256-bit prime \(p\) the text states that the girth is pushed to \(\sim 200{,}000\) bits or more, making short collisions infeasible. Performance is characterized by one \(2\times 2\)-matrix multiply in \(\mathbb F_p\) per bit; this is heavier than a single bitwise XOR but perfectly parallelizable, and incremental update for \(|D|\gg |P|\) costs only \(|P|\) multiplies plus one final multiply by the old hash \(H(D)\) [2502.13197].

## 4. HexaMorphHash and signed vector re-hash

HexaMorphHash places the re-hash operation in the additive group \(G=\mathbb Z_q^n\), with
\[
q=2^d,\qquad n=\mathrm{poly}(\lambda),\qquad d=\Theta(\lambda),
\]
and models the underlying cryptographic hash as an extendable-output function
\[
h:\{0,1\}^* \to \{0,1\}^{nd},
\]
whose output is parsed into \(n\) limbs of \(d\) bits [2507.21096]. The induced map
\[
\widetilde h(x)=\bigl(h_1(x),h_2(x),\dots,h_n(x)\bigr)\in\mathbb Z_q^n
\]
defines the digest of an ordered database \(D=((1,x_1),\dots,(N,x_N))\) by
\[
H(D)=\Bigl(\sum_{i=1}^N \widetilde h(\mathrm{encode}(i,x_i))\Bigr)\bmod q,
\]
where \(\mathrm{encode}(i,x)=\mathrm{binary}(i)\|x\). The digest is then signed as \(\sigma_D=\mathrm{Sign}(sk,H(D))\).

The re-hash operation is an additive delta update. For replacement of row \(i\)’s old value \(x\) with new value \(y\),
\[
\Delta_{\rm del}=-\,\widetilde h(\mathrm{encode}(i,x)),
\qquad
\Delta_{\rm add}=\widetilde h(\mathrm{encode}(i,y)),
\]
and the updated digest is
\[
D' = H(D)+\Delta_{\rm del}+\Delta_{\rm add}\pmod q.
\]
For pure insertion of a new element \(x\) at fresh index \(i\),
\[
\Delta_{\rm ins}=\widetilde h(\mathrm{encode}(i,x)),
\qquad
D'=D+\Delta_{\rm ins}\pmod q.
\]
For pure deletion,
\[
\Delta_{\rm del}=-\,\widetilde h(\mathrm{encode}(i,x)),
\qquad
D'=D+\Delta_{\rm del}\pmod q.
\]
After the update, the distributor re-signs and the subscriber applies the same vector additions or subtractions locally, followed by one signature verification [2507.21096].

Collision resistance is reduced to the Short Integer Solutions problem. If two distinct datasets \(S\neq T\) satisfy \(H(S)=H(T)\), then
\[
\sum_{x\in S}\widetilde h(x)-\sum_{y\in T}\widetilde h(y)\equiv 0\pmod q.
\]
Stacking the public vectors \(\widetilde h(\cdot)\) into a matrix \(A\), the task becomes finding a short nonzero integer vector \(v\) with \(Av\equiv 0\pmod q\), which is exactly SIS [2507.21096]. For parameters \((n,d)=(1024,16)\), the text states that SIS is conjectured infeasible even for quantum adversaries. The implementation discussion gives \(O(n)\) work per update for the two vector hashes and coordinate-wise additions or subtractions, one ECDSA sign at approximately \(0.5\) ms, one signature verify at approximately \(0.3\) ms, and a fixed digest of \(1024\times 16\) bits \(=2\) KB. On a \(3.5\) GHz Haswell, the reported measurements are approximately \(0.5\) ms for publish and approximately \(2.0\) ms to apply \(100\) updates and one signature verify; a single distributor is said to handle tens of thousands of updates per second [2507.21096].

## 5. Deferred and concurrent rehashing in extensible hash tables

Anton Malakhov’s per-bucket concurrent rehashing algorithm addresses a different form of re-hash operation: redistribution of entries during table growth without a global stop-the-world pass [1509.02235]. The table consists of an array of buckets of current capacity \(S\). To grow from \(S\) to \(2S\) buckets, the algorithm allocates \(S\) new empty buckets alongside the existing ones; the new buckets are marked “new (un-rehashed),” and the table logically has capacity \(2S\), but no global rehash step is performed.

The old-to-new bucket correspondence is one-to-one. If \(i_p\) is the index of an old bucket, then its corresponding new bucket index \(i_n\) satisfies
\[
i_n \bmod S = i_p.
\]
With a power-of-two capacity \(S=2^\ell\), bucket indices are computed by masks:
\[
i_{\rm old}=H(\mathrm{Key}) \,\&\, (2^\ell-1)=H(\mathrm{Key})\,\&\,m,
\]
\[
i_{\rm new}=H(\mathrm{Key}) \,\&\, (2^{\ell+1}-1)=H(\mathrm{Key})\,\&\,m'.
\]
The parent of a bucket after expansion is obtained by clearing the most significant 1-bit, equivalently
\[
i_p=i_{\rm new}\,\&\,m
\]
for the power-of-two case [1509.02235].

Rehashing is on-demand. An operation first reads the global mask \(m\), computes \(i=H(K)\,\&\,m\), acquires bucket \(i\)’s lock, and, if bucket \(i\) is still marked NEW, invokes `RehashBucket(i)`. Under the lock on bucket \(i\), the algorithm locks the parent bucket, scans its entries, recomputes the new mask destination \(j\), moves the entries for which \(j=i\), and then marks bucket \(i\) as REHASHED [1509.02235]. A lookup that fails must detect whether a concurrent resize could have moved the key out of bucket \(i\); this is handled by re-reading the mask and evaluating candidate child buckets, restarting only if a race is detected. The design uses bucket-level synchronization only, allows a race condition between lookup and moving operations in different threads, and resolves it by detection and restart rather than explicit synchronization across the table.

The complexity discussion states average-case \(O(1+\alpha)\) lookup, insert, and delete, with \(\alpha=\mathrm{load\_factor}=n/S\), worst-case \(O(n)\) under pathological collisions, and amortized \(O(1)\) extra cost per insert because each key is moved at most once per doubling [1509.02235]. Memory overhead is \(2\times S\) buckets at peak, one extra bit or flag per bucket, and optionally a segment table of size \(O(\log S)\). Micro-benchmarks on a 24-core Xeon X7460 compare the method with `tbb::concurrent_hash_map` and `tbb::concurrent_unordered_map`: the per-bucket rehashing implementation matches or exceeds the split-ordered list across all reported insertion rates, scales nearly linearly to approximately \(16\) threads, and produces only negligible restart counts—tens of restarts over millions of operations [1509.02235].

## 6. Warp-cooperative GPU resizing

Hive hash table transfers the re-hash problem to the GPU and frames it as warp-parallel dynamic resizing without global rehashing [2510.15095]. The load factor is defined as
\[
\alpha = \frac{\text{number of occupied entries}}{n_{\rm buckets}\times S},
\]
with fixed bucket size \(S=32\) slots by default. Expansion is triggered when \(\alpha>\alpha_{\max}=0.90\), contraction when \(\alpha<\alpha_{\min}=0.25\), and resizing proceeds in increments of \(K\) buckets per epoch [2510.15095].

The indexing scheme is classical linear hashing. The table maintains a round mask
\[
M=2^m-1
\]
and a split pointer \(\mathit{split\_ptr}\in[0,M]\). During expansion, \(K\) new buckets are allocated and, for each \(i=0,\dots,K-1\),
\[
b_{\rm src}=\mathit{split\_ptr}+i,
\qquad
b_{\rm dst}=b_{\rm src}+(M+1).
\]
The next mask is
\[
M'=(M\ll 1)+1 = 2^{m+1}-1,
\]
so the new address is
\[
h'(k)=h(k)\bmod(M'+1),
\]
equivalently determined by testing the extra high bit against \(b_{\rm dst}\) [2510.15095]. Contraction reverses the procedure with
\[
b_{\rm src}=b_{\rm dst}-(M+1),
\qquad
M'=(M\lor 1)\gg 1 = 2^{m-1}-1,
\qquad
\mathit{split\_ptr}\leftarrow M'+1.
\]

Each warp handles one bucket pair \((b_{\rm src},b_{\rm dst})\). It loads all \(S\) entries coalescently, computes a warp-wide move mask using \(\_\_ballot\_sync\), compacts movers by prefix-popcount rank, writes moved entries into the destination bucket, clears source slots, and updates bucket-local `freeMask` words through atomic operations [2510.15095]. Per split or merge the work is \(O(S)\), and with \(S=32\) constant, a batch of \(K\) buckets costs \(O(K)\) time. Doubling from \(N\) to \(2N\) buckets requires \(N/K\) batches, hence overall \(O(N)\) work and amortized \(O(1)\) rehash cost per insertion. The design explicitly avoids a single, table-wide rehash loop, global locks, and host-device synchronization.

The GPU-centric optimization strategy is hardware-aware: buckets are aligned so that \(32\) lanes reading \(64\)-bit packed key-value words generate at most two \(128\)-byte L1/L2 cache-line fetches; updates and removals are single CAS operations on \(64\)-bit words; `freeMask` is a \(32\)-bit word per bucket; and warp-synchronous “claim” and “match” protocols reduce contention to one atomic per warp [2510.15095]. Experimental evaluation on an NVIDIA RTX 4090 reports sustained load factors up to \(95\%\), \(1.5\)–\(2\times\) higher throughput than Slab-Hash, DyCuckoo, and WarpCore under mixed insert-delete-lookup workloads, \(3.5\) billion updates/s, and nearly \(4\) billion lookups/s on balanced workload [2510.15095].

## 7. Comparative interpretation and common misconceptions

A common misconception is that re-hash necessarily means rescanning all existing data. The cited constructions provide several counterexamples: a consistent reassignment function can limit remapping to a \(1/(N+1)\) fraction of keys when a bucket is added; a Cayley hash can update by group multiplication \(H(D\|\;P)=H(D)\cdot H(P)\); HexaMorphHash can update by vector addition \(D'=D+\Delta \pmod q\); a concurrent table can defer movement to the first operation that touches a NEW bucket; and a GPU table can split or merge only \(K\) buckets in one epoch [2403.18682] [2502.13197] [2507.21096] [1509.02235] [2510.15095].

A second misconception is that avoiding full rehash removes hard correctness constraints. In fact, each scheme replaces full recomputation with a different invariant. In JumpBackHash the invariant is uniformity plus monotonicity; in Cayley hashing it is the concatenation homomorphism and a girth bound large enough to preclude short relations; in HexaMorphHash it is linearity in \(\mathbb Z_q^n\) together with a reduction from collisions to SIS; in Malakhov’s algorithm it is bucket-local synchronization plus race detection and restart; and in Hive it is linear-hashing correctness under warp-synchronous movement and atomic `freeMask` maintenance [2403.18682] [2502.13197] [2507.21096] [1509.02235] [2510.15095].

A plausible implication is that “re-hash operation” should be interpreted operationally rather than syntactically. The operation is not defined by repeating a hash computation from scratch; it is defined by the admissible state transition after a change. In cryptographic settings that transition is algebraic and must preserve collision, preimage, or second-preimage resistance. In data-structure settings it is structural and must preserve load balance, lookup correctness, or concurrency properties. The literature therefore treats re-hash not as a singular algorithmic primitive, but as a design pattern for incremental state maintenance under change.

Source: https://www.emergentmind.com/topics/re-hash-operation