Next Article in Journal
Denoising Diffusion Models on Model-Based Latent Space
Previous Article in Journal
Discovering Non-Linear Boolean Functions by Evolving Walsh Transforms with Genetic Programming
 
 
Font Type:
Arial Georgia Verdana
Font Size:
Aa Aa Aa
Line Spacing:
Column Width:
Background:
Article

Two-Way Linear Probing Revisited

School of Computer Science, McGill University, Montreal, QC H3A 2K6, Canada
*
Author to whom correspondence should be addressed.
Current address: Department of Mathematical Sciences, Ahlia University, Manama P.O. Box 10878, Bahrain.
Algorithms 2023, 16(11), 500; https://doi.org/10.3390/a16110500
Submission received: 2 October 2023 / Revised: 22 October 2023 / Accepted: 23 October 2023 / Published: 28 October 2023

Abstract

:
Linear probing continues to be one of the best practical hashing algorithms due to its good average performance, efficiency, and simplicity of implementation. However, the worst-case performance of linear probing seems to degrade with high load factors due to a primary-clustering tendency of one collision to cause more nearby collisions. It is known that the maximum cluster size produced by linear probing, and hence the length of the longest probe sequence needed to insert or search for a key in a hash table of size n, is Ω ( log n ) , in probability. In this article, we introduce linear probing hashing schemes that employ two linear probe sequences to find empty cells for the keys. Our results show that two-way linear probing is a promising alternative to linear probing for hash tables. We show that two-way linear probing has an asymptotically almost surely O ( log log n ) maximum cluster size when the load factor is constant. Matching lower bounds on the maximum cluster size produced by any two-way linear probing algorithm are obtained as well. Our analysis is based on a novel approach that uses the multiple-choice paradigm and witness trees.

1. Introduction

In classical open addressing hashing [1], m keys are hashed sequentially and on-line into a table of size n > m , (that is, a one-dimensional array with n cells which we denote by the set T = 0 , , n 1 ), where each cell can harbor at most one key. Each key x has only one infinite probe sequence f i ( x ) T , for i N . During the insertion process, if a key is mapped to a cell that is already occupied by another key, a collision occurs, and another probe is required. The probing continues until an empty cell is reached where a key is placed. This method of hashing is pointer-free, unlike hashing with separate chaining where keys colliding in the same cell are hashed to a separate linked list or chain. For a discussion of different hashing schemes, see [2,3,4].
In classical linear probing, the probe sequence for each key x is defined by f i + 1 ( x ) = f i ( x ) + 1 mod n , for i n : = 1 , , n . Linear probing is known for its good practical performance, efficiency, and simplicity. It continues to be one of the best hash tables in practice due to its simplicity of implementation, absence of overhead for internally used pointers, cache efficiency, and locality of reference [5,6,7,8]. On the other hand, the performance of linear probing seems to degrade with high load factors m / n , due to a primary-clustering tendency of one collision to cause more nearby collisions. In particular, the length of the longest probe sequence needed to insert (or search for) a key in a hash table, with constant load factor, constructed by linear probing is proven [9] to be Ω ( log n ) , in probability.
The purpose of this paper is to design efficient open addressing hashing schemes that improve the worst-case performance of classical linear probing. Our study concentrates on schemes that use two linear probe sequences to find possible hashing cells for the keys. Each key chooses two initial cells independently and uniformly at random, with replacement. From each initial cell, we probe linearly, and then cyclically whenever the last cell in the table is reached, to find two empty cells which we call terminal cells. The key then is inserted into one of these terminal cells according to a fixed strategy. We consider strategies that utilize the greedy multiple-choice paradigm [10,11]. We show that some of the trivial insertion strategies with two-way linear probing have unexpected poor performance. For example, one of the trivial strategies we study inserts each key into the terminal cell found by the shorter probe sequence. Another simple strategy inserts each key into the terminal cell that is adjacent to the smaller cluster, where a cluster is an isolated set of consecutively occupied cells. Unfortunately, the performances of these two strategies are not ideal. We prove that, when any of these two strategies is used to construct a hash table with constant load factor, the maximum unsuccessful search time is Ω ( log n ) , with high probability (w.h.p.). Indeed, we prove that, w.h.p., a giant cluster of size Ω ( log n ) emerges in a hash table of constant load factor, if it is constructed by a two-way linear probing insertion strategy that always inserts any key upon arrival into the empty cell of its two initial cells whenever one of them is empty.
Consequently, we introduce two other strategies that overcome this problem. First, we partition the hash table into equal-sized blocks of size β , assuming n / β is an integer. We consider the following strategies for inserting the keys:
A.
Each key is inserted into the terminal cell that belongs to the least crowded block, i.e., the block with the least number of keys.
B.
For each block i, we define its weight to be the number of keys inserted into terminal cells found by linear probe sequences whose starting locations belong to block i. Each key, then, is inserted into the terminal cell found by the linear probe sequence that has started from the block of smaller weight.
For strategy B, we show that β can be chosen such that, for any constant load factor α : = m / n , the maximum unsuccessful search time is not more than c log 2 log n , w.h.p., where c is a function of α . If α < 1 / 2 , the same property also holds for strategy A. Furthermore, these schemes are optimal up to a constant factor in the sense that an Ω ( log log n ) universal lower bound holds for any strategy that uses two linear probe sequences, even if the initial cells are chosen according to arbitrary probability distributions.

Paper Scope

In the next section, we provide a summary of the related background and history. In Section 3, we present our proposed two-way linear probing hashing algorithms. We prove in Section 4 a universal lower bound of order of log log n on the maximum unsuccessful search time of any two-way linear probing algorithm. We prove, in addition, that not every two-way linear probing scheme behaves efficiently. We devote Section 5 to the positive results, where we demonstrate that some of our two-way linear probing heuristics accomplish O ( log log n ) worst-case unsuccessful search time. The simulation and the comparison results of the studied algorithms are summarized in Section 6.

2. Background and History

For hashing with separate chaining, one can achieve O ( log log n ) maximum search time by applying the two-way chaining scheme [10,12,13], where each key is inserted into the shorter chain between two chains chosen independently and uniformly at random, with replacement, breaking ties randomly. It is proven [10,14,15] that, when r = Ω ( n ) keys are inserted into a hash table with n chains, the length of the longest chain upon termination is log 2 log n + r / n ± O ( 1 ) , w.h.p. Of course, this idea can be generalized to open addressing. Assuming the hash table is partitioned into blocks of size β , we allow each key to choose two initial cells, and hence two blocks, independently and uniformly at random, with replacement. From each initial cell and within its block, we probe linearly and cyclically, if necessary, to find two empty cells; that is, whenever we reach the last cell in the block and it is occupied, we continue probing from the first cell in the same block. The key, then, is inserted into the empty cell that belongs to the least full block. Using the two-way chaining result, one can show that, for suitably chosen β , the maximum unsuccessful search time is O ( log log n ) , w.h.p. However, this scheme uses probe sequences that are not totally linear; rather, they are locally linear within the blocks.

2.1. Probing and Replacement

Open addressing schemes are determined by the type of the probe sequence, and the replacement strategy for resolving the collisions. Some of the commonly used probe sequences are as follows:
  • Random Probing [16]: For every key x, the infinite sequence f i ( x ) is assumed to be independent and uniformly distributed over T . That is, we require to have an infinite sequence f i of truly uniform and independent hash functions. If for each key x, the first n probes of the sequence f i ( x ) are distinct, i.e., it is a random permutation, then it is called uniform probing [1].
  • Linear Probing [1]: For every key x, the first probe f 1 ( x ) is assumed to be uniform on T , and the next probes are defined by f i + 1 ( x ) = f i ( x ) + 1 mod n , for i n . So we only require f 1 to be a truly uniform hash function.
  • Double Probing [17]: For every key x, the first probe is f 1 ( x ) , and the next probes are defined by f i + 1 ( x ) = f i ( x ) + g ( x ) mod n , for i N , where f 1 and g are truly uniform and independent hash functions.
Random and uniform probings are, in some sense, the idealized models [18,19], and their plausible performances are among the easiest to analyze, but obviously they are unrealistic. Linear probing is perhaps the simplest to implement, but it behaves badly when the table is almost full. Double probing can be seen as a compromise.
During the insertion process of a key x, suppose that we arrive at the cell f i ( x ) , which is already occupied by another previously inserted key y, that is, f i ( x ) = f j ( y ) , for some j N . Then a replacement strategy for resolving the collision is needed. Three strategies have been suggested in the literature (see [20] for other methods):
  • first come first served (fcfs) [1]: The key y is kept in its cell, and the key x is referred to the next cell f i + 1 ( x ) .
  • last come first served (lcfs) [21]: The key x is inserted into the cell f i ( x ) , and the key y is pushed along to the next cell in its probe sequence, f j + 1 ( y ) .
  • robin hood [22,23]: The key which traveled the farthest is inserted into the cell. That is, if i > j , then the key x is inserted into the cell f i ( x ) , and the key y is pushed along to the next cell f j + 1 ( y ) ; otherwise, y is kept in its cell, and the key x tries its next cell f i + 1 ( x ) .

2.2. Average Performance

Evidently, the performance of any open addressing scheme deteriorates when the ratio m / n approaches 1, as the cluster sizes increase, where a cluster is an isolated set of consecutively occupied cells (cyclically defined) that are bounded by empty cells. Therefore, we shall assume that the hash table is α -full, that is, the number of hashed keys m = α n , where α ( 0 , 1 ) is a constant called the load factor. The asymptotic average-case performance has been extensively analyzed for random and uniform probing [1,16,18,19,24,25], linear probing [3,26,27,28], and double probing [17,29,30,31,32]. The expected search times were proven to be constants, more or less, depending on α only. Recent results about the average-case performance of linear probing and the limit distribution of the construction time have appeared in [33,34,35,36]. See also [37,38,39] for the average-case analysis of linear probing for non-uniform hash functions.
It is worth noting that the average search time of linear probing is independent of the replacement strategy; see [1,3]. This is because the insertion of any order of the keys results in the same set of occupied cells, i.e., the cluster sizes are the same; hence, the total displacement of the keys—from their initial hashing locations—remains unchanged. It is not difficult to see that this independence is also true for random and double probings. That is, the replacement strategy does not have any effect on the average successful search time in any of the above probings. In addition, since, in linear probing, the unsuccessful search time is related to the cluster sizes (unlike random and double probings), the expected and the maximum unsuccessful search times in linear probing are invariant to the replacement strategy.
It is known that the lcfs [21,40] and robin hood [20,22,23,35] strategies minimize the variance of displacement. Recently, Janson [41] and Viola [42] have reaffirmed the effect of these replacement strategies on the individual search times in linear probing hashing.

2.3. Worst-Case Performance

The focal point of this article, however, is the worst-case search time which is proportional to the length of the longest probe sequence over all keys (llps, for short). Many results have been established regarding the worst-case performance of open addressing.
The worst-case performance of linear probing with the fcfs policy was analyzed by Pittel [9]. He proved that the maximum cluster size, and hence the llps needed to insert (or search for) a key, is asymptotic to ( α 1 log α ) 1 log n , in probability. As we mentioned above, this bound holds for linear probing with any replacement strategy. Chassaing and Louchard [43] studied the threshold of emergence of a giant cluster in linear probing. They showed that, when the number of keys m = n ω ( n ) , the size of the largest cluster is o ( n ) , w.h.p.; however, when m = n o ( n ) , a giant cluster of size Θ ( n ) emerges, w.h.p.
Gonnet [44] proved that, with uniform probing and the fcfs replacement strategy, the expected llps is asymptotic to log 1 / α n log 1 / α log 1 / α n + O ( 1 ) for α -full tables. However, Poblete and Munro [21,40] showed that, if random probing is combined with the lcfs policy, then the expected llps is at most ( 1 + o ( 1 ) ) Γ 1 ( α n ) = O ( log n / log log n ) , where Γ is the gamma function.
On the other hand, the robin hood strategy with random probing leads to a more striking performance. Celis [22] first proved that the expected llps is O ( log n ) . However, Devroye, Morin, and Viola [45] tightened the bounds and revealed that the llps is indeed log 2 log n ± Θ ( 1 ) , w.h.p., thus achieving a double logarithmic worst-case insertion and search times for the first time in open addressing hashing. Unfortunately, one cannot ignore the assumption in random probing about the availability of an infinite collection of hash functions that are sufficiently independent and behave like truly uniform hash functions in practice. On the other side of the spectrum, we already know that the robin hood policy does not affect the maximum unsuccessful search time in linear probing. However, robin hood may be promising with double probing.

2.4. Other Initiatives

Open addressing methods that rely on the rearrangement of keys were under investigation for many years, see, e.g., [20,46,47,48,49,50]. Pagh and Rodler [51] studied a scheme called cuckoo hashing that exploits the lcfs replacement policy. It uses two hash tables of size n > ( 1 + ϵ ) m , for some constant ϵ > 0 , and two independent hash functions chosen from an O ( log n ) -universal class—one function only for each table. Each key is hashed initially by the first function to a cell in the first table. If the cell is full, then the new key is inserted there anyway, and the old key is kicked out to the second table to be hashed by the second function. The same rule is applied in the second table. Keys are moved back and forth until a key moves to an empty location or a limit has been reached. If the limit is reached, new independent hash functions are chosen, and the tables are rehashed. The worst-case search time is at most two, and the amortized expected insertion time, nonetheless, is constant. However, this scheme utilizes less than 50% of the allocated memory, has a worst-case insertion time of O ( log n ) , w.h.p., and depends on a wealthy source of provably good independent hash functions for the rehashing process. For further details see [52,53,54,55].
The space efficiency of cuckoo hashing is significantly improved when the hash table is divided into blocks of fixed size b 1 and more hash functions are used to choose k 2 blocks for each key where each is inserted into a cell in one of its chosen blocks using the cuckoo random walk insertion method [56,57,58,59,60,61]. For example, it is known [57,58] that 89.7% space utilization can be achieved when k = 2 and the hash table is partitioned into non-overlapping blocks of size b = 2 . On the other hand, when the blocks are allowed to overlap, the space utilization improves to 96.5% [57,61]. The worst-case insertion time of this generalized cuckoo hashing scheme, however, is proven [59,62] to be polylogarithmic, w.h.p.
Many real-time static and dynamic perfect hashing schemes achieving constant worst-case search time, and linear (in the table size) construction time and space were designed in [63,64,65,66,67,68,69,70]. All of these schemes, which are based, more or less, on the idea of multilevel hashing, employ more than a constant number of perfect hash functions chosen from an efficient universal class. Some of them even use O ( n ) functions.

2.5. The Multiple-Choice Paradigm

Allocating balls into bins is one of the historical assignment problems [71,72]. We are given r balls that have to be placed into s bins. The balls have to be inserted sequentially and on-line, that is, each ball is assigned upon arrival without knowing anything about the future coming balls. The load of a bin is defined to be the number of balls it contains. We would like to design an allocation process that minimizes the maximum load among all bins upon termination. For example, in a classical allocation process, each ball is placed into a bin chosen independently and uniformly at random, with replacement. It is known [44,73,74,75] that, if r = Θ ( s ) , the maximum load upon termination is asymptotic to log s / log log s , in probability.
On the other hand, the greedy multiple-choice allocation process, which appeared in [76,77] and studied by Azar et al. [10], inserts each ball into the least loaded bin among d 2 bins chosen independently and uniformly at random, with replacement, breaking ties randomly. Throughout, we will refer to this process as GreedyMC  ( s , r , d ) for inserting r balls into s bins. Surprisingly, the maximum bin load of GreedyMC ( s , s , d ) decreases exponentially to log d log s ± O ( 1 ) , w.h.p., [10]. However, one can easily generalize this to the case r = Θ ( s ) . It is also known that the greedy strategy is stochastically optimal in the following sense.
Theorem 1
(Azar et al. [10]). Let s , r , d N , where d 2 , and r = Θ ( s ) . Upon termination of GreedyMC ( s , r , d ) , the maximum bin load is log d log s ± O ( 1 ) , w.h.p. Furthermore, the maximum bin load of any on-line allocation process that inserts r balls sequentially into s bins where each ball is inserted into a bin among d bins chosen independently and uniformly at random, with replacement, is at least log d log s O ( 1 ) , w.h.p.
Berenbrink et al. [14] extended Theorem 1 to the heavily loaded case where r s , and recorded the following tight result.
Theorem 2
(Berenbrink et al. [14]). There is a constant C > 0 such that, for any integers r s > 0 , and d 2 , the maximum bin load upon termination of the process GreedyMC ( s , r , d ) is log d log s + r / s ± C , w.h.p.
Theorem 2 is a crucial result that we have used to derive our results; see Theorems 8 and 9. It states that the deviation from the average bin load, which is log d log s , stays unchanged as the number of balls increases.
Vöcking [11,78] demonstrated that it is possible to improve the performance of the greedy process, if non-uniform distributions on the bins and a tie-breaking rule are carefully chosen. He suggested the following variant, which is called Always-Go-Left. The bins are numbered from 1 to n. We partition the s bins into d groups of almost equal size, that is, each group has size Θ ( s / d ) . We allow each ball to select upon arrival d bins independently at random, but the i-th bin must be chosen uniformly from the i-th group. Each ball is placed on-line, as before, in the least full bin, but upon a tie, the ball is always placed in the leftmost bin among the d bins. We shall write LeftMC ( s , r , d ) to refer to this process. Vöcking [11] showed that, if r = Θ ( s ) , the maximum load of LeftMC ( s , r , d ) is log log s / ( d log ϕ d ) + O ( 1 ) , w.h.p., where ϕ d is a constant related to a generalized Fibonacci sequence. For example, the constant ϕ 2 = 1.61 corresponds to the well-known golden ratio, and ϕ 3 = 1.83 . In general, ϕ 2 < ϕ 3 < ϕ 4 < < 2 , and lim d ϕ d = 2 . Observe the improvement on the performance of GreedyMc ( s , r , d ) , even for d = 2 . The maximum load of LeftMC ( s , r , 2 ) is 0.72 . . . × log 2 log s + O ( 1 ) , whereas in GreedyMC ( s , r , 2 ) , it is log 2 log s + O ( 1 ) . The process LeftMC ( s , r , d ) is also optimal in the following sense.
Theorem 3
(Vöcking [11]). Let r , s , d N , where d 2 , and r = Θ ( s ) . The maximum bin load of of LeftMC ( s , r , d ) upon termination is log log s / ( d log ϕ d ) ± O ( 1 ) , w.h.p. Moreover, the maximum bin load of any on-line allocation process that inserts r balls sequentially into s bins where each ball is placed into a bin among d bins chosen according to arbitrary, not necessarily independent, probability distributions defined on the bins is at least log log s / ( d log ϕ d ) O ( 1 ) , w.h.p.
Berenbrink et al. [14] studied the heavily loaded case and recorded the following theorem.
Theorem 4
(Berenbrink et al. [14]). There is a constant A > 0 such that, for any integers r s > 0 , and d 2 , the maximum bin load upon termination of the process LeftMC ( s , r , d ) is log log s / ( d log ϕ d ) + r / s ± A , w.h.p.
For other variants and generalizations of the multiple-choice paradigm see [79,80,81,82,83,84]. The paradigm has been used to derive many applications, e.g., in load balancing, circuit routing, IP address lookups, and computer graphics [75,85,86,87,88].

3. The Proposal

We design linear probing algorithms that accomplish double logarithmic worst-case search time. Inspired by the two-way chaining algorithm [10] and its powerful performance, we promote the concept of open addressing hashing with two-way linear probing. The essence of the proposed concept is based on the idea of allowing each key to generate two independent linear probe sequences and making the algorithm decide, according to some strategy, at the end of which sequence the key should be inserted. Formally, each input key x chooses two cells independently and uniformly at random, with replacement. We call these cells the initial hashing cells available for x. From each initial hashing cell, we start a linear probe sequence (with fcfs policy) to find an empty cell where we stop. Thus, we end up with two unoccupied cells. We call these cells the terminal hashing cells. The question now is: into which terminal cell should we insert the key x?
The insertion process of a two-way linear probing algorithm could follow one of the strategies we mentioned earlier: it may insert the key at the end of the shorter probe sequence, or into the terminal cell that is adjacent to the smaller cluster. Others may make an insertion decision even before linear probing starts. In any of these algorithms, the searching process for any key is basically the same: just start probing in both sequences alternately, until the key is found or the two empty cells at the end of the sequences are reached in the case of an unsuccessful search. Thus, the maximum unsuccessful search time is at most twice the size of the largest cluster plus two.
We study the two-way linear probing algorithms stated above, and show that the hash table, asymptotically almost surely, contains a giant cluster of size Ω ( log n ) . Indeed, we prove that a cluster of size Ω ( log n ) emerges, asymptotically almost surely, in any hash table of constant load factor that is constructed by a two-way linear probing algorithm that inserts any key upon arrival into the empty cell of its two initial cells whenever one of them is empty.
We introduce two other two-way linear probing heuristics that lead to Θ ( log log n ) maximum unsuccessful search times. The common idea of these heuristics is the marriage between the two-way linear probing concept and a technique we call blocking where the hash table is partitioned into equal-sized blocks. These blocks are used by the algorithm to obtain some information about the keys allocation. The information is used to make better decisions about where the keys should be inserted, and hence, lead to a more even distribution of the keys.
Two-way linear probing hashing has several advantages over the other proposed hashing methods mentioned above: it reduces the worst-case behavior of hashing, it requires only two hash functions, it is easy to parallelize, it is pointer-free and easy to implement, and unlike the hashing schemes proposed in [51,58], it does not require any rearrangement of keys or rehashing. Its maximum cluster size is O ( log log n ) , and its average-case performance can be at most twice the classical linear probing as shown in the simulation results. Furthermore, it is not necessary to employ perfectly random hash functions as it is known [6,7,8] that hash functions with a smaller degree of universality will be sufficient to implement linear probing schemes. See also [31,32,51,53,70,76,89] for other suggestions on practical hash functions.
Throughout, we assume the following. We are given m keys—from a universe set of keys U —to be hashed into a hash table of size n such that each cell contains at most one key. The process of hashing is sequential and on-line, that is, we never know anything about the future keys. The constant α ( 0 , 1 ) is preserved in this article for the load factor of the hash table, that is, we assume that m = α n . The n cells of the hash table are numbered 0 , , n 1 . The linear probe sequences always move cyclically from left to right of the hash table. The replacement strategy of all of the introduced algorithms is fcfs. The insertion time is defined to be the number of probes the algorithm performs to insert a key. Similarly, the search time is defined to be the number of probes needed to find a key, or two empty cells in the case of unsuccessful search. Observe that, unlike classical linear probing, the insertion time of two-way linear probing may not be equal to the successful search time. However, they are both bounded by the unsuccessful search time. Notice also that we ignore the time to compute the hash functions.

3.1. Two-Way Linear Probing

To avoid any ambiguity, we consider this definition.
Definition 1. 
A two-way linear probing algorithm is an open addressing hashing algorithm that inserts keys into cells using a certain strategy and does the following upon the arrival of each key:
1. 
It chooses two initial hashing cells independently and uniformly at random, with replacement.
2. 
Two terminal (empty) cells are then found by linear probe sequences starting from the initial cells.
3. 
The key is inserted into one of these terminal cells.
To be clear, we give two examples of inefficient two-way linear probing algorithms.
  • The Shorter Probe Sequence:   ShortSeq  Algorithm
Our first algorithm places each key into the terminal cell discovered by the shorter probe sequence. More precisely, once the key chooses its initial hashing cells, we start two linear probe sequences. We proceed, sequentially and alternately, one probe from each sequence until we find an empty (terminal) cell where we insert the key. Formally, let f , g : U 0 , , n 1 be independent and truly uniform hash functions. For x U , define the linear sequence f 1 ( x ) = f ( x ) , and f i + 1 ( x ) = f i ( x ) + 1 mod n , for i n ; and similarly define the sequence g i ( x ) . The algorithm, then, inserts each key x into the first unoccupied cell in the following probe sequence: f 1 ( x ) , g 1 ( x ) , f 2 ( x ) , g 2 ( x ) , f 3 ( x ) , g 3 ( x ) , , as shown in Figure 1. We denote this algorithm that hashes m keys into n cells by ShortSeq ( n , m ) , for the shorter sequence.
  • The Smaller Cluster:   SmallCluster  Algorithm
The second algorithm inserts each key into the empty (terminal) cell that is the right neighbor of the smaller cluster among the two clusters containing the initial hashing cells, breaking ties randomly. If one of the initial cells is empty, then the key is inserted into it, and if both of the initial cells are empty, we break ties evenly. Recall that a cluster is a group of consecutively occupied cells whose left and right neighbors are empty cells. This means that one can compute the size of the cluster that contains an initial hashing cell by running two linear probe sequences in opposite directions starting from the initial cell and going to the empty cells at the boundaries. So practically, the algorithm uses four linear probe sequences. We refer to this algorithm by SmallCluster ( n , m ) for inserting m keys into n cells (Figure 2).
In Section 4.2, we show that algorithms ShortSeq and SmallCluster have unexpected poor performance. Indeed we prove that such algorithms, which always insert any key upon arrival into the empty cell of its two initial cells whenever one of them is empty, produce a cluster of size Ω ( log n ) , asymptotically almost surely. To overcome the problems of these algorithms, we introduce blocking.

3.2. Hashing with Blocking

The hash table is partitioned into equal-sized disjoint blocks of cells. Whenever a key has two terminal cells, the algorithm considers the information provided by the blocks, e.g., the number of keys it harbors, to make a decision. Thus, the blocking technique enables the algorithm to avoid some of the bad decisions the previous algorithms make. This leads to a more controlled allocation process, and hence, to a more even distribution of the keys. We use the blocking technique to design two two-way linear probing algorithms, and an algorithm that uses linear probing locally within each block. The algorithms are characterized by the way the keys pick their blocks to land in. The worst-case performance of these algorithms is analyzed in Section 5 and proven to be O ( log log n ) , w.h.p.
Note also that (for insertion operations only) the algorithms require a counter with each block, but the extra space consumed by these counters is asymptotically negligible. In fact, we will see that the extra space is O ( n / log log n ) in a model in which integers take O ( 1 ) space, and at worst O ( n log log log n / log log n ) = o ( n ) units of memory, w.h.p., in a bit model.
Since the block size for each of the following algorithms is different, we assume throughout and without loss of generality that, whenever we use a block of size β , then n / β is an integer. Recall that the cells are numbered 0 , , n 1 , and hence, for i n / β , the i-th block consists of the cells ( i 1 ) β , , i β 1 . In other words, the cell k 0 , , n 1 belongs to block number λ ( k ) : = k / β + 1 .
  • Two-Way Locally Linear Probing:   LocallyLinear  Algorithm
As a simple example of the blocking technique, we present the following algorithm, which is a trivial application of the two-way chaining scheme [10]. The algorithm does not satisfy the definition of two-way linear probing as we explained earlier, because the linear probes are performed within each block and not along the hash table. That is, whenever the linear probe sequence reaches the right boundary of a block, it continues probing starting from the left boundary of the same block.
The algorithm partitions the hash table into disjoint blocks each of size β 1 ( n ) , where β 1 ( n ) is an integer to be defined later. We save with each block its load, that is, the number of keys it contains, and keep it updated whenever a key is inserted in the block. For each key, we choose two initial hashing cells, and hence two blocks, independently and uniformly at random, with replacement. From the initial cell that belongs to the least loaded block, breaking ties randomly, we probe linearly and cyclically within the block until we find an empty cell where we insert the key. If the load of the block is β 1 , i.e., it is full, then we check its right neighbor block and so on, until we find a block that is not completely full. We insert the key into the first empty cell there. Notice that only one probe sequence is used to insert any key. The search operation, however, uses two probe sequences as follows. First, we compute the two initial hashing cells. We start probing linearly and cyclically within the two (possibly identical) blocks that contain these initial cells. If both probe sequences reach empty cells, or if one of them reaches an empty cell and the other one finishes the block without finding the key, we declare the search to be unsuccessful. If both blocks are full and the probe sequences completely search them without finding the key, then the right neighbors of these blocks (cyclically speaking) are searched sequentially in the same way mentioned above, and so on. We will refer to this algorithm as LocallyLinear ( n , m ) for inserting m keys into n cells.
  • Two-Way Pre-Linear Probing:   DecideFirst  Algorithm
In the previous two-way linear probing algorithms, each input key initiates linear probe sequences that reach two terminal cells, and then the algorithms decide in which terminal cell the key should be inserted. The following algorithm, however, allows each key to choose two initial hashing cells, and then decides, according to some strategy, which initial cell should start a linear probe sequence to find a terminal cell to harbor the key. Therefore, technically, the insertion process of any key uses only one linear probe sequence, but we still use two sequences for any search.
Formally, we describe the algorithm as follows. Let α ( 0 , 1 ) be the load factor. Partition the hash table into blocks of size β 2 ( n ) , where β 2 ( n ) is an integer to be defined later. Each key x still chooses, independently and uniformly at random, two initial hashing cells, say I x and J x , and hence, two blocks which we denote by λ ( I x ) and λ ( J x ) . For convenience, we say that the key x has landed in block i, if the linear probe sequence used to insert the key x has started (from the initial hashing cell available for x) in block i. Define the weight of a block to be the number of keys that have landed in it. We save with each block its weight and keep it updated whenever a key lands in it. Now, upon the arrival of key x, the algorithm allows x to land into the block among λ ( I x ) and λ ( J x ) of smaller weight, breaking ties randomly. Whence, it starts probing linearly from the initial cell contained in the block until it finds a terminal cell into which the key x is placed. If, for example, both I x and J x belong to the same block, then x lands in λ ( I x ) , and the linear sequence starts from an arbitrarily chosen cell among I x and J x .
We will write DecideFirst ( n , m ) to refer to this algorithm for inserting m keys into n cells. In short, the strategy of  DecideFirst ( n , m ) as illustrated in Figure 3 is: land in the block of smaller weight, walk linearly, and insert into the first empty cell reached.
  • Two-Way Post-Linear Probing:   WalkFirst  Algorithm
We introduce yet another hashing algorithm that achieves Θ ( log log n ) worst-case search time, in probability, and shows better performance in experiments than DecideFirst algorithm as demonstrated in the simulation results presented in Section 6. Suppose that the load factor α ( 0 , 1 / 2 ) , and that the hash table is divided into blocks of size
β 3 ( n ) : = log 2 log n + 8 1 δ ,
where δ ( 2 α , 1 ) is an arbitrary constant. Define the load of a block to be the number of keys (or occupied cells) it contains. Suppose that we save with each block its load and keep it updated whenever a key is inserted into one of its cells. Recall that each key x has two initial hashing cells. From these initial cells, the algorithm probes linearly and cyclically until it finds two empty cells U x and V x , which we call terminal cells. Let λ ( U x ) and λ ( V x ) be the blocks that contain these cells. The algorithm, then, inserts the key x into the terminal cell (among U x and V x ) that belongs to the least loaded block among λ ( U x ) and λ ( V x ) , breaking ties randomly. We refer to this algorithm of open addressing hashing for inserting m keys into n cells as WalkFirst ( n , m ) (Figure 4).

4. Lower Bounds

We prove here that the idea of two-way linear probing alone is not always sufficient to pull off a plausible hashing performance. We prove that a large group of two-way linear probing algorithms have an Ω ( log n ) lower bound on their worst-case search time. We shall first record a lower bound that holds for any two-way linear probing algorithm.

4.1. Universal Lower Bound

The following lower bound holds for any two-way linear probing hashing scheme, in particular, the ones that are presented in this article.
Theorem 5. 
Let n N , and m = α n , where α ( 0 , 1 ) is a constant. Let A be any two-way linear probing algorithm that inserts m keys into a hash table of size n. Then upon termination of A , w.h.p., the table contains a cluster of size of at least log 2 log n O ( 1 ) .
Proof. 
Imagine that we have a bin associated with each cell in the hash table. Recall that, for each key x, algorithm A chooses two initial cells, and hence two bins, independently and uniformly at random, with replacement. Algorithm A , then, probes linearly to find two (possibly identical) terminal cells, and inserts the key x into one of them. Now imagine that after the insertion of each key x, we also insert a ball into the bin associated with the initial cell from which the algorithm started probing to reach the terminal cell into which the key x was placed. If both of the initial cells lead to the same terminal cell, then we break the tie randomly. Clearly, if there is a bin with k balls, then there is a cluster of size of at least k, because the k balls represent k distinct keys that belong to the same cluster. However, Theorem 1 asserts that the maximum bin load upon termination of algorithm A is at least log 2 log n O ( 1 ) , w.h.p. □
The above lower bound is valid for all algorithms that satisfy Definition 1. A more general lower bound can be established on all open addressing schemes that use two linear probe sequences where the initial hashing cells are chosen according to some (not necessarily uniform or independent) probability distributions defined on the cells. We still assume that the probe sequences are used to find two (empty) terminal hashing cells, and the key is inserted into one of them according to some strategy. We call such schemes non-uniform two-way linear probing. The proof of the following theorem is basically similar to Theorem 5, but by using instead Vöcking’s lower bound as stated in Theorem 3.
Theorem 6. 
Let n N , and m = α n , where α ( 0 , 1 ) is a constant. Let A be any non-uniform two-way linear probing algorithm that inserts m keys into a hash table of size n where the initial hashing cells are chosen according to some probability distributions. Then the maximum cluster size produced by A , upon termination, is at least log log n / ( 2 log ϕ 2 ) O ( 1 ) , w.h.p.

4.2. Algorithms That Behave Poorly

We characterize some of the inefficient two-way linear probing algorithms. Notice that the main mistake in algorithms ShortSeq ( n , m ) and SmallCluster ( n , m ) is that the keys are allowed to be inserted into empty cells even if these cells are very close to some giant clusters. This leads us to the following theorem whose proof utilizes Lemmas A4–A6, stated in Appendix A, regarding negative association of random variables. Throughout, we write binomial ( n , p ) to denote a binomial random variable with parameters n N and p [ 0 , 1 ] .
Theorem 7. 
Let α ( 0 , 1 ) be constant. Let A be a two-way linear probing algorithm that inserts m = α n keys into n cells such that, whenever a key chooses an empty and an occupied initial cells, the algorithm inserts the key into the empty one. Then algorithm A produces a giant cluster of size Ω ( log n ) , w.h.p.
Proof. 
Let β = b log a n for some positive constants a and b to be defined later, and without loss of generality, assume that N : = n / β is an integer. Suppose that the hash table is divided into N disjoint blocks, each of size β . For i N , let B i = β ( i 1 ) + 1 , , β i be the set of cells of the i-th block, where we consider the cell numbers in a circular fashion. We say that a cell j n is “covered” if there is a key whose first initial hashing cell is the cell j and its second initial hashing cell is an occupied cell. A block is covered if all of its cells are covered. Observe that, if a block is covered, then it is fully occupied. Thus, it suffices to show that there would be a covered block, w.h.p.
For i N , let Y i be the indicator that the i-th block is covered. The random variables Y 1 , , Y N are negatively associated which can been seen as follows. For j n and t m , let X j ( t ) be the indicator that the j-th cell is covered by the t-th key, and set X 0 ( t ) : = 1 j = 1 n X j ( t ) . Notice that the random variable X 0 ( t ) is binary. The zero-one Lemma asserts that the binary random variables X 0 ( t ) , , X n ( t ) are negatively associated. However, since the keys choose their initial hashing cells independently, the random variables X 0 ( t ) , , X n ( t ) are mutually independent from the random variables X 0 ( t ) , , X n ( t ) , for any distinct t , t m . Thus, by Lemma 5, the union t = 1 m X 0 ( t ) , , X n ( t ) is a set of negatively associated random variables. The negative association of the Y i is assured now by Lemma 6 as they can be written as non-decreasing functions of disjoint subsets of the indicators X j ( t ) . Since the Y i are negatively associated and identically distributed, then
P Y 1 = 0 , , Y N = 0 P Y 1 = 0 × × P Y N = 0 exp N P Y 1 = 1 .
Thus, we only need to show that N P Y 1 = 1 tends to infinity as n goes to infinity. To bound the last probability, we need to focus on the way the first block B 1 = 1 , 2 , , β is covered. For j n , let t j be the smallest t m such that X j ( t ) = 1 (if such exists), and m + 1 otherwise. We say that the first block is “covered in order” if and only if 1 t 1 < t 2 < < t β m . Since there are β ! orderings of the cells in which they can be covered (for the first time), we have
P Y 1 = 1 = β ! P B 1 is covered in order .
For t m , let M ( t ) = 1 if block B 1 is full before the insertion of the t-th key, and otherwise be the minimum i B 1 such that the cell i has not been covered yet. Let A be the event that, for all t m , the first initial hashing cell of the t-th key is either cell M ( t ) or a cell outside B 1 . Define the random variable W : = t = 1 m W t , where W t is the indicator that the t-th key covers a cell in B 1 . Clearly, if A is true and W β , then the first block is covered in order. Thus,
P Y 1 = 1 β ! P W β A = β ! P A P W β | A .
However, since the initial hashing cells are chosen independently and uniformly at random, then for n chosen large enough, we have
P A 1 β n m e 2 β ,
and for t m / 2 ,
P W t = 1 | A = 1 n β + 1 · t 1 n α 4 n .
Therefore, for n that is sufficiently large, we obtain
N P Y 1 = 1 N β ! e 2 β P binomial m / 2 , α / ( 4 n ) β N β ! e 2 β ( m / 2 β ) β β ! α 4 n β 1 α 4 n n N α 2 8 e 2 β 1 2 β m β 1 1 4 n n n 4 β α 2 8 e 2 β ,
which goes to infinity as n approaches infinity whenever a = 8 e 2 / α 2 and b is any positive constant less than 1. □
Clearly, algorithms ShortSeq ( n , m ) and SmallCluster ( n , m ) satisfy the condition of Theorem 7. So this corollary follows.
Corollary 1. 
Let n N , and m = α n , where α ( 0 , 1 ) is constant. The size of the largest cluster generated by algorithm  ShortSeq ( n , m ) is Ω ( log n ) , w.h.p. The same result holds for algorithm  SmallCluster ( n , m ) .

5. Upper Bounds

In this section, we establish upper bounds on the worst-case performance of the two-way linear probing algorithms that use a blocking technique: LocallyLinearDecideFirst, and WalkFirst. We show that the block size can be chosen for each of these algorithms to demonstrate that the maximum cluster size is O ( log log n ) , w.h.p.

5.1. Two-Way Locally Linear Probing: LocallyLinear Algorithm

Recall that algorithm LocallyLinear ( n , m ) inserts keys into a hash table with disjoint blocks of size β 1 ( n ) . We show next that β 1 can be defined such that none of the blocks are completely full, w.h.p. This means that, whenever we search for any key, most of the time, we only need to search linearly and cyclically the two blocks that the key chooses initially.
Theorem 8. 
Let n N , and m = α n , where α ( 0 , 1 ) is a constant. Let C be the constant defined in Theorem 2, and define
β 1 ( n ) : = log 2 log n + C 1 α + 1 .
Then, w.h.p., the maximum unsuccessful search time of  LocallyLinear ( n , m ) with blocks of size β 1 is at most 2 β 1 , and the maximum insertion time is at most β 1 1 .
Proof. 
Notice the equivalence between algorithm LocallyLinear ( n , m ) and the allocation process GreedyMC ( n / β 1 , m , 2 ) where m balls (keys) are inserted into n / β 1 bins (blocks) by placing each ball into the least loaded bin among two bins chosen independently and uniformly at random, with replacement. It suffices, therefore, to study the maximum bin load of GreedyMC ( n / β 1 , m , 2 ) , which we denote by L n . However, Theorem 2 says that, w.h.p.,
L n log 2 log n + C + α β 1 < ( 1 α ) β 1 + α β 1 = β 1 .
and similarly,
L n log 2 log n + α β 1 C > log 2 log n + C 1 α 2 C β 1 2 C 1 .

5.2. Two-Way Pre-Linear Probing: DecideFirst Algorithm

The next theorem describes the worst-case performance of algorithm DecideFirst ( n , m ) with blocks of size β 2 showing that the size of the largest cluster produced by the algorithm is Θ ( log log n ) , w.h.p.
Theorem 9. 
Let n N , and m = α n , where α ( 0 , 1 ) is a constant. There is a constant η > 0 such that, if
β 2 ( n ) : = ( 1 + 2 α ) 2 α ( 1 α ) ( log 2 log n + η ) ,
then, w.h.p., the worst-case unsuccessful search time of algorithm  DecideFirst ( n , m ) with blocks of size β 2 is at most ξ n : = 12 ( 1 α ) 2 ( log 2 log n + η ) , and the maximum insertion time is at most ξ n / 2 .
Proof. 
Assume first that DecideFirst ( n , m ) is applied to a hash table with blocks of size β = b ( log 2 log n + η ) , and that n / β is an integer, where b = ( 1 + ϵ ) / ( 1 α ) , for some arbitrary constant ϵ > 0 . Consider the resulting hash table after termination of the algorithm. Let M 0 be the maximum number of consecutive blocks that are fully occupied. Without loss of generality, suppose that these blocks start at block i + 1 , and let S = i , i + 1 , , i + M represent these full blocks in addition to the left adjacent block that is not fully occupied (Figure 5).
Notice that each key chooses two cells (and hence, two possibly identical blocks) independently and uniformly at random. Moreover, any key always lands in the block of smaller weight. Since there are n / β blocks, and α n keys, then by Theorem 2, there is a constant C > 0 such that the maximum block weight is not more than λ n : = ( α b + 1 ) log 2 log n + α b η + α + C , w.h.p. Let A n denote the event that the maximum block weight is at most λ n . Let W be the number of keys that have landed in S, i.e., the total weight of blocks contained in S. Plainly, since block i is not full, then all the keys that belong to the M full blocks have landed in S. Thus, W M b ( log 2 log n + η ) , deterministically. Now, clearly, if we choose η = C + α , then the event A n implies that ( M + 1 ) ( α b + 1 ) M b , because otherwise, we have
W ( M + 1 ) ( α b + 1 ) log 2 log n + α b η + α + C α b + 1 < M b ( log 2 log n + η ) ,
which is a contradiction. Therefore, A n yields that
M α b + 1 ( 1 α ) b 1 1 + ϵ α ϵ ( 1 α ) .
Recall that ( α b + 1 ) < b = ( 1 + ϵ ) / ( 1 α ) . Again, since block i is not full, the size of the largest cluster is not more than the total weight of the M + 2 blocks that cover it. Consequently, the maximum cluster size is, w.h.p., not more than
( M + 2 ) ( α b + 1 ) ( log 2 log n + η ) ψ ( ϵ ) ( 1 α ) 2 ( log 2 log n + η ) ,
where ψ ( ϵ ) : = 3 α + ( 2 α ) ϵ + 1 / ϵ . Since ϵ is arbitrary, we choose it such that ψ ( ϵ ) is minimum, i.e., ϵ = 1 / 2 α ; in other words, ψ ( ϵ ) = 3 α + 2 2 α < 6 . This concludes the proof as the maximum unsuccessful search time is at most twice the maximum cluster size plus two. □
Remark 1.
We have showed that, w.h.p., the maximum cluster size produced by DecideFirst ( n , m ) is in fact not more than
3 α + 2 2 α ( 1 α ) 2 log 2 log n + O ( 1 ) < 6 ( 1 α ) 2 log 2 log n + O ( 1 ) .

5.3. Two-Way Post-Linear Probing: WalkFirst Algorithm

Next, we analyze the worst-case performance of algorithm WalkFirst ( n , m ) with blocks of size β 3 . Recall that the maximum unsuccessful search time is bounded from above by twice the maximum cluster size plus two. The following theorem asserts that upon termination of the algorithm, it is most likely that every block has at least one empty cell. This implies that the length of the largest cluster is at most 2 β 3 2 .
Theorem 10. 
Let n N , and m = α n , for some constant α ( 0 , 1 / 2 ) . Let δ ( 2 α , 1 ) be an arbitrary constant, and define
β 3 ( n ) : = log 2 log n + 8 1 δ .
Upon termination of algorithm   WalkFirst ( n , m ) with blocks of size β 3 , the probability that there is a fully loaded block goes to zero as n tends to infinity. That is, w.h.p., the maximum unsuccessful search time of  WalkFirst ( n , m ) is at most 4 β 3 2 , and the maximum insertion time is at most 4 β 3 4 .
For k m , let us denote by A k the event that after the insertion of k keys (i.e., at time k), none of the blocks is fully loaded. To prove Theorem 10, we shall show that P A m c = o ( 1 ) . We do that by using a witness tree argument; see e.g., [11,85,90,91,92,93]. We show that, if a fully loaded block exists, then there is a witness binary tree of height β 3 that describes the history of that block. The formal definition of a witness tree is given below. Let us number the keys 1 , , m according to their insertion time. Recall that each key t m has two initial cells which lead to two terminal empty cells belonging to two blocks. Let us denote these two blocks available for the t-th key by X t and Y t . Notice that all the initial cells are independent and uniformly distributed. However, all terminal cells—and so their blocks—are not. Nonetheless, for each fixed t, the two random values X t and Y t are independent.
  • The History Tree
We define for each key t a full history tree T t that describes essentially the history of the block that contains the t-th key up to its insertion time. It is a colored binary tree that is labeled by key numbers except possibly the leaves, where each key refers to the block that contains it. Thus, it is indeed a binary tree that represents all the pairs of blocks available for all other keys upon which the final position of the key t relies. Formally, we construct the binary tree node by node in Breadth-First-Search (bfs) order as follows. First, the root of T t is labeled t, and is colored white. Any white node labeled τ has two children: a left child corresponding to the block X τ , and a right child corresponding to the block Y τ . The left child is labeled and colored according to the following rules:
(a)
If the block X τ contains some keys at the time of insertion of key τ , and the last key inserted in that block, say σ , has not been encountered thus far in the bfs order of the binary tree T t , then the node is labeled σ and colored white.
(b)
As in case (a), except that σ has already been encountered in the bfs order. We distinguish such nodes by coloring them black, but they are given the same label σ .
(c)
If the block X τ is empty at the time of insertion of key τ , then it is a “dead end” node without any label and it is colored gray.
Next, the right child of τ is labeled and colored by following the same rules but with the block Y τ . We continue processing nodes in bfs fashion. A black or gray node in the tree is a leaf and is not processed any further. A white node with label σ is processed in the same way we processed the key τ , but with its two blocks X σ and Y σ . We continue recursively constructing the tree until all the leaves are black or gray. See Figure 6 for an example of a full history tree.
Notice that the full history tree is totally deterministic as it does not contain any random value. It is also clear that the full history tree contains at least one gray leaf and every internal (white) node in the tree has two children. Furthermore, since the insertion process is sequential, node values (key numbers) along any path down from the root must be decreasing (so the binary tree has the heap property), because any non-gray child of any node represents the last key inserted in the block containing it at the insertion time of the parent. We will not use the heap property, however.
Clearly, the full history tree permits one to deduce the load of the block that contains the root key at the time of its insertion: it is the length of the shortest path from the root to any gray node. Thus, if the block’s load is more than h, then all gray nodes must be at a distance more than h from the root. This leads to the notion of a truncated history tree of height h, that is, with h + 1 levels of nodes. The top part of the full history tree that includes all nodes at the first h + 1 levels is copied, and the remainder is truncated.
We are in particular interested in truncated history trees without gray nodes. Thus, by the property mentioned above, the length of the shortest path from the root to any gray node (and as noted above, there is at least one such node) would have to be at least h + 1 , and therefore, the load of the block harboring the root’s key would have to be at least h + 1 . More generally, if the load is at least h + ξ for a positive integer ξ , then all nodes at the bottom level of the truncated history tree that are not black nodes (and there is at least one such node) must be white nodes whose children represent keys that belong to blocks with load of at least ξ at their insertion time. We redraw these node as boxes to denote the fact that they represent blocks of load at least ξ , and we call them “block” nodes.
  • The Witness Tree
Let ξ N be a fixed integer to be picked later. For positive integers h and k, where h + ξ k m , a witness tree W k ( h ) is a truncated history tree of a key in the set k , with h + 1 levels of nodes (thus, of height h) and with two types of leaf nodes, black nodes and “block” nodes. This means that each internal node has two children, and the node labels belong to the set k . Each black leaf has a label of an internal node that precedes it in bfs order. Block nodes are unlabeled nodes that represent blocks with load of at least ξ . Block nodes must all be at the furthest level from the root, and there is at least one such node in a witness tree. Notice that every witness tree is deterministic. An example of a witness tree is shown in Figure 7.
Let W k ( h , w , b ) denote the class of all witness trees W k ( h ) of height h that have w 1 white (internal) nodes, and b w black nodes (and thus w b + 1 block nodes). Notice that, by definition, the class W k ( h , w , b ) could be empty, e.g., if w < h , or w 2 h . However, | W k ( h , w , b ) | 4 w 2 w + 1 w b k w , which is due to the following. Without the labeling, there are at most 4 w different shape binary trees, because the shape is determined by the w internal nodes, and hence, the number of trees is the Catalan number 2 w w / ( w + 1 ) 4 w . Having fixed the shape, each of the leaves is of one of two types. Each black leaf can receive one of the w white node labels. Each of the white nodes obtains one of k possible labels.
Note that, unlike the full history tree, not every key has a witness tree W k ( h ) : the key must be placed into a block of load of at least h + ξ 1 just before the insertion time. We say that a witness tree W k ( h )  occurs, if upon execution of algorithm WalkFirst, the random choices available for the keys represented by the witness tree are actually as indicated in the witness tree itself. Thus, a witness tree of height h exists if and only if there is a key that is inserted into a block of load of at least h + ξ 1 before the insertion.
Before we embark on the proof of Theorem 10, we highlight three important facts whose proofs are provided in Appendix A. First, we bound the probability that a valid witness tree occurs.
Lemma 1. 
Let D denote the event that the number of blocks in  WalkFirst ( n , m ) with load of at least ξ, after termination, is at most n / ( a β 3 ξ ) , for some constant a > 0 . For k m , let A k be the event that, after the insertion of k keys, none of the blocks is fully loaded. Then for any positive integers h , w and k h + ξ , and a non-negative integer b w , we have
sup W k ( h ) W k ( h , w , b ) P W k ( h ) occurs | A k 1 D 4 w β 3 w + b 1 ( a ξ ) w b + 1 n w + b 1 .
The next lemma asserts that the event D in Lemma 1 is most likely to be true, for sufficiently large ξ < β 3 .
Lemma 2. 
Let α, δ, and β 3 be as defined in Theorem 10. Let N be the number of blocks with load of at least ξ upon termination of algorithm  WalkFirst ( n , m ) . If ξ δ β 3 , then P N n / ( a β 3 ξ ) = o ( 1 ) , for any constant a > 0 .
Lemma 3 addresses a simple but crucial fact. If the height of a witness tree W k ( h ) W k ( h , w , b ) is h 2 , then the number of white nodes w is at least two, (namely, the root and its left child); but what can we say about b, the number of black nodes?
Lemma 3. 
In any witness tree W k ( h ) W k ( h , w , b ) , if h 2 and w 2 h η , where η 1 , then the number b of black nodes is η , i.e., I [ b η ] [ w > 2 h η ] = 1 .
  • Proof of Theorem 10.
Recall that A k , for k m , is the event that after the insertion of k keys (i.e., at time k), none of the blocks is fully loaded. Notice that A m A m 1 A 1 , and the event A β 3 1 is deterministically true. We shall show that P A m c = o ( 1 ) . Let D denote the event that the number of blocks with load of at least ξ , after termination, is at most n / ( a β 3 ξ ) , for some constant a > 1 to be decided later. Observe that
P A m c P D c + P A m c | D P D c + P A m c | A m 1 D + P A m 1 c | D P D c + k = β 3 m P A k c | A k 1 D .
Lemma 2 reveals that P D c = o ( 1 ) , and hence, we only need to demonstrate that p k : = P A k c | A k 1 D = o ( 1 / n ) , for k = β 3 , , m . We do that by using the witness tree argument. Let h , ξ , η [ 2 , ) be some integers to be picked later such that h + ξ β 3 . If after the insertion of k keys, there is a block with load of at least h + ξ , then a witness tree W k ( h ) (with block nodes representing blocks with load of at least ξ ) must have occurred. Recall that the number of white nodes w in any witness tree W k ( h ) is at least two. Using Lemmas 1 and 3, we see that
p k W k ( h ) P W k ( h ) occurs | A k 1 D w = 2 2 h 1 b = 0 w W k ( h ) W k ( h , w , b ) P W k ( h ) occurs | A k 1 D w = 2 2 h 1 b = 0 w | W k ( h , w , b ) | sup W k ( h ) W k ( h , w , b ) P W k ( h ) occurs | A k 1 D w = 2 2 h b = 0 w 2 w + 1 4 2 w w b k w β 3 w + b 1 ( a ξ ) w b + 1 n w + b 1 I [ b η ] [ w > 2 h η ] 2 n a ξ β 3 w = 2 2 h 32 α β 3 a ξ w b = 0 w a w ξ β 3 n b I [ b η ] [ w > 2 h η ] .
Note that we disallow b = w + 1 , because any witness tree has at least one block node. We split the sum over w 2 h η , and w > 2 h η . For w 2 h η , we have b η , and thus
b = 0 w a w ξ β 3 n b I [ b η ] [ w > 2 h η ] = b = η w a w ξ β 3 n b a w ξ β 3 n η b = 0 a w ξ β 3 n b < 2 a w ξ β 3 n η ,
provided that n is so large that a 2 h + 1 ξ β 3 n , (this insures that a w ξ β 3 / n < 1 / 2 ). For w ( 2 h η , 2 h ] , we bound trivially, assuming the same large n condition:
b = 0 w a w ξ β 3 n b 2 .
In summary, we see that
p k 4 n w > 2 h η 32 α β 3 a ξ w + 4 a ξ β 3 n η 1 w = 2 2 h η 32 α β 3 a ξ w w η .
We set a = 32 , and ξ = δ β 3 , so that 32 α β 3 / ( a ξ ) 1 / 2 , because δ ( 2 α , 1 ) . With this choice, we have
p k 4 n 2 2 h η + 4 c 32 β 3 2 n η 1 ,
where c = w 2 w η / 2 w . Clearly, if we put h = η + log 2 log 2 n η , and η = 3 , then we see that h + ξ β 3 , and p k = o ( 1 / n ) . Notice that h and ξ satisfy the technical condition a 2 h + 1 ξ β 3 n , asymptotically. □
Remark 2.
The restriction on α is needed only to prove Lemma 2 where the binomial tail inequality is valid only if α < 1 / 2 . Simulation results, as we show next, suggest that a variant of Theorem 10 might hold for any α ( 0 , 1 ) with block size ( 1 α ) 1 log 2 log n .

5.4. Trade-Offs

We have seen that, by using two linear probe sequences instead of just one, the maximum unsuccessful search time decreases exponentially from O ( log n ) to O ( log log n ) . The average search time, however, could at worst double, as shown in the simulation results. Most of the results presented in this article can be improved, by a constant factor though, by increasing the number of hashing choices per key. For example, Theorems 5 and 6 can be easily generalized for open addressing hashing schemes that use d 2 linear probe sequences. Similarly, all the two-way linear probing algorithms we design here can be generalized to d-way linear probing schemes. The maximum unsuccessful search time will, then, be at most d C log d log n + O ( d ) , where C is a constant depending on α . This means that the best worst-case performance is when d = 3 where the minimum of d / log d is attained. The average search time, on the other hand, could triple.
The performance of these algorithms can be further improved by using Vöcking’s scheme LeftMC ( n , m , d ) , explained in Section 2.5, with d 2 hashing choices. The maximum unsuccessful search time, in this case, is at most C log log n / log ϕ d + O ( d ) , for some constant C depending on α . This is minimized when d = o ( log log n ) , but we know that it cannot be better than C log 2 log n + O ( d ) , because lim d ϕ d = 2 .

6. Simulation Results

We simulate all linear probing algorithms we discussed in this article with the fcfs replacement strategy: the classical linear probing algorithm ClassicLinear, the locally linear algorithm LocallyLinear, and the two-way linear probing algorithms ShortSeqSmallClusterWalkFirst, and DecideFirst. For each value of n 2 8 , 2 12 , 2 16 , 2 20 , 2 22 , and constant α 0.4 , 0.9 , we simulate each algorithm 1000 times divided into 10 iterations (experiments). Each iteration consists of 100 simulations of the same algorithm where we insert α n keys into a hash table with n cells. In each simulation, we compute the average and the maximum successful search and insert times. For each iteration (100 simulations), we compute the average of the average values and and the average of the maximum values computed during the 100 simulations for the successful search and insert times. The overall results are finally averaged over the 10 iterations and recorded in the next tables. Similarly, the average maximum cluster size is computed for each algorithm as it can be used to bound the maximum unsuccessful search time, as mentioned earlier. Notice that in the case of the algorithms ClassicLinear and ShortSeq, the successful search time is the same as the insertion time.
Table 1 and Table 2 contain the simulation results of the algorithms ClassicLinearShortSeq, and SmallCluster. With the exception of the average insertion time of the SmallCluster algorithm, which is slightly bigger than the ClassicLinear algorithm, it is evident that the average and the worst-case performances of SmallCluster and ShortSeq are better than ClassicLinear. The SmallCluster algorithm seems to have the best worst-case performance among the three algorithms. This is not a total surprise to us, because the algorithm considers more information (relative to the other two) before it makes its decision of where to insert the keys. It is also clear that there is a nonlinear increase, as a function of n, in the difference between the performances of these algorithms. This may suggest that the worst-case performances of algorithms ShortSeq and SmallCluster are roughly of the order of log n .
The simulation data of algorithms LocallyLinearWalkFirst, and DecideFirst are presented in Table 3, Table 4 and Table 5. These algorithms are simulated with blocks of size ( 1 α ) 1 log 2 log n . The purpose of this is to show that, practically, the additive and the multiplicative constants appearing in the definitions of the block sizes stated in Theorems 8–10 can be chosen to be small. The hash table is partitioned into equal-sized blocks, except possibly the last one. The average and the maximum values of the successful search time, inset time, and cluster size (averaged over 10 iterations each consisting of 100 simulations of the algorithms) are recorded in the tables below where the best performances are drawn in boldface.
Results show that the LocallyLinear algorithm has the best performance, whereas WalkFirst appears to perform better than DecideFirst. Indeed, the sizes of the cluster produced by WalkFirst appears to be very close to that of LocallyLinear. This supports the conjecture that Theorem 10 is, in fact, true for any constant load factor α ( 0 , 1 ) , and the maximum unsuccessful search time of WalkFirst is at most 4 ( 1 α ) 1 log 2 log n + O ( 1 ) , w.h.p. The average maximum cluster size of DecideFirst seems to be close to the other ones when α is small, but it almost doubles when α is large. This may suggest that the multiplicative constant in the maximum unsuccessful search time established in Theorem 9 could be improved.
Comparing the simulation data from all tables, one can see that the best average performance is achieved by the algorithms LocallyLinear and ShortSeq. Notice that the ShortSeq algorithm achieves the best average successful search time when α = 0.9 . The best (average and maximum) insertion time is achieved by the LocallyLinear algorithm. On the other hand, algorithms WalkFirst and LocallyLinear are superior to the others in worst-case performance. It is worth noting that surprisingly, the worst-case successful search time of SmallCluster is very close to the one achieved by WalkFirst and better than that of DecideFirst, although, it appears that the difference becomes larger as n increases.

7. Conclusions

In this research, we designed efficient open addressing hashing schemes that improve the worst-case performance of classical linear probing. We proposed two-way linear probing hashing schemes that use two independent linear probe sequences and accomplish Θ ( log log n ) worst-case insertion and search times, w.h.p. The common idea of these schemes is the successful marriage between the two-way linear probing concept and the blocking technique where the hash table is partitioned into equal-sized blocks. Simulation and comparison results supported our theoretical analyses of all algorithms discussed in this research and illustrated that the worst-case and average performances of such schemes are practically plausible. Thus, we conclude that two-way linear probing hashing with blocking has several advantages over other proposed hashing methods as it reduces the worst-case behavior of hashing, it requires only two hash functions, it is easy to parallelize, it is pointer-free and easy to implement, and it does not require any rearrangement of keys or rehashing. Its maximum cluster size is O ( log log n ) , and its average-case performance can be at most twice the classical linear probing as shown in the simulation results.
Furthermore, we also showed that not every two-way linear probing algorithm has a good worst-case performance. We proved that, if the two-way linear probing algorithm always inserts any key upon arrival into the empty cell of its two initial cells whenever one of them is empty, then, w.h.p., a cluster of size Ω ( log n ) emerges in the hash table.
Our results suggest that two-way linear probing may be a more promising open addressing hashing scheme than classical linear probing for many applications, including, e.g., mobile networks [94,95].
It would be interesting to extend the result of Theorem 10 to any constant load factor α ( 0 , 1 ) —as is suggested by the simulation results—and to investigate its applications to other problems in computer science.

Author Contributions

Conceptualization and methodology, L.D. and E.M.; validation and formal analysis, K.D., L.D. and E.M.; writing—original draft preparation, E.M.; writing—review and editing, K.D. and L.D.; supervision and project administration, L.D. All authors have read and agreed to the published version of the manuscript.

Funding

This research was funded by NSERC Grant A3456.

Conflicts of Interest

The authors declare no conflict of interest.

Appendix A

Appendix A.1. Lemmas Needed for Theorem 10

For completeness, we prove the lemmas used in the proof of Theorem 10.
Lemma 1. 
Let D denote the event that the number of blocks in  WalkFirst ( n , m ) with load of at least ξ, after termination, is at most n / ( a β 3 ξ ) , for some constant a > 0 . For k m , let A k be the event that after the insertion of k keys, none of the blocks is fully loaded. Then for any positive integers h , w and k h + ξ , and a non-negative integer b w , we have
sup W k ( h ) W k ( h , w , b ) P W k ( h ) occurs | A k 1 D 4 w β 3 w + b 1 ( a ξ ) w b + 1 n w + b 1 .
Proof. 
Notice first that given A k 1 , the probability that any fixed key in the set k chooses a certain block is at most 2 β 3 / n . Let W k ( h ) W k ( h , w , b ) be a fixed witness tree. We compute the probability that W k ( h ) occurs given that A k 1 is true, by looking at each node in bfs order. Suppose that we are at an internal node, say u, in W k ( h ) . We would like to find the conditional probability that a certain child of node u is exactly as indicated in the witness tree, given that A k 1 is true, and everything is revealed except those nodes that precede u in the bfs order. This depends on the type of the child. If the child is white or black, the conditional probability is not more than 2 β 3 / n . This is because each key refers to the unique block that contains it, and moreover, the initial hashing cells of all keys are independent. Multiplying just these conditional probabilities yields ( 2 β 3 / n ) w + b 1 , as there are w + b 1 edges in the witness tree that have a white or black nodes as their lower endpoint. On the other hand, if the child is a block node, the conditional probability is at most 2 / ( a ξ ) . This is because a block node corresponds to a block with load of at least ξ , and there are at most n / ( a β 3 ξ ) such blocks each of which is chosen with probability of at most 2 β 3 / n . Since there are w b + 1 block nodes, the result follows plainly by multiplying all the conditional probabilities. □
To prove Lemma 2, we need to recall the following binomial tail inequality [96]: for p ( 0 , 1 ) , and any positive integers r, and t η r p , for some η > 1 , we have
P binomial ( r , p ) t φ t r p t ( φ ( η ) ) t ,
where φ ( x ) = x 1 e 1 1 / x , which is decreasing on ( 1 , ) . Notice that φ ( x ) < 1 , for any x > 1 , because 1 / x = ( 1 z ) < e z = e 1 / x 1 , for some z ( 0 , 1 ) .
Lemma 2. 
Let α, δ, and β 3 be as defined in Theorem 10. Let N be the number of blocks with load of at least ξ upon termination of algorithm  WalkFirst ( n , m ) . If ξ δ β 3 , then P N n / ( a β 3 ξ ) = o ( 1 ) , for any constant a > 0 .
Proof. 
Fix ξ δ β 3 . Let B denote the last block in the hash table, i.e., B consists of the cells n β 3 , , n 1 . Let L be the load of B after termination. Since the loads of the blocks are identically distributed, we have
E N = n β 3 P L ξ .
Let S be the set of the consecutively occupied cells, after termination, that occur between the first empty cell to the left of the block B and the cell n β 3 ; see Figure A1.
Figure A1. The last part of the hash table showing clusters, the last block B, and the set S.
Figure A1. The last part of the hash table showing clusters, the last block B, and the set S.
Algorithms 16 00500 g0a1
We say that a key is born in a set of cells A if at least one of its two initial hashing cells belong to A. For convenience, we write ν ( A ) to denote the number of keys that are born in A. Obviously, ν ( A ) is binomial ( m , 2 | A | / n ) . Since the cell adjacent to the left boundary of S is empty, all the keys that are inserted in S are actually born in S. That is, if | S | = j , then ν ( S ) j . So, by the binomial tail inequality given earlier, we see that
P | S | = j = P ν ( S ) j | S | = j P binomial ( m , 2 j / n ) j c j ,
where the constant c : = φ ( 1 / ( 2 α ) ) = 2 α e 1 2 α < 1 , because α < 1 / 2 . Let
: = log c 1 c ξ 2 = O ( log β 3 ) .
and notice that, for n that is large enough,
ξ δ β 3 δ 2 m ( + β 3 ) ( 1 + / β 3 ) 2 α n y 2 m ( + β 3 ) n ,
where y = 1 / 2 + δ / ( 4 α ) > 1 , because δ ( 2 α , 1 ) . Clearly, by the same property of S stated above, L ν ( S B ) ; and hence, by the binomial tail inequality again, we conclude that, for n that is sufficiently large,
P L ξ P ν ( S B ) ξ | S | + j = m P | S | = j P binomial ( m , 2 ( + β 3 ) / n ) ξ + c 1 c φ ( y ) ξ + c 1 c 1 ξ 2 + 1 ξ 2 = 2 ξ 2 .
Thence, E N 2 n / ( β 3 ξ 2 ) which implies by Markov’s inequality that
P N n a β 3 ξ 2 a ξ = o ( 1 ) .
Lemma 3. 
In any witness tree W k ( h ) W k ( h , w , b ) , if h 2 and w 2 h η , where η 1 , then the number b of black nodes is η , i.e., I [ b η ] [ w > 2 h η ] = 1 .
Proof. 
Note that any witness tree has at least one block node at distance h from the root. If we have b black nodes, the number of block nodes is at least 2 h b . Since w 2 h η , then 2 h η b + 1 w b + 1 2 h b . If b = 0 , then we have a contradiction. So, assume b 1 . But then 2 h η 2 h b ; that is, b η . □

Appendix A.2. Lemmas Needed for Theorem 7

The following definition and lemmas are used to prove Theorem 7.
Definition A1 
(See, e.g., [97]). Any non-negative random variables X 1 , , X n are said to be negatively associated, if for every disjoint index subsets I , J n , and for any functions f : R | I | R , and g : R | J | R that are both non-decreasing or both non-increasing (component-wise), we have
E f ( X i , i I ) g ( X j , j J ) E f ( X i , i I ) E g ( X j , j J ) .
Once we establish that X 1 , , X n are negatively associated, it follows, by considering inductively the indicator functions, that
P X 1 < x 1 , , X n , < x n i = 1 n P X i < x i .
The next lemmas, which are proven in [97,98,99], provide some tools for establishing the negative association.
Lemma 4 
(Zero-One Lemma). Any binary random variables X 1 , , X n whose sum is one are negatively associated.
Lemma 5. 
If X 1 , , X n and Y 1 , , Y m are independent sets of negatively associated random variables, then the union X 1 , , X n , Y 1 , , Y m is also a set of negatively associated random variables.
Lemma 6. 
Suppose that X 1 , , X n are negatively associated. Let I 1 , , I k n be disjoint index subsets, for some positive integer k. For j k , let h j : R | I j | R be non-decreasing functions, and define Z j = h j ( X i , i I j ) . Then the random variables Z 1 , , Z k are negatively associated. In other words, non-decreasing functions of disjoint subsets of negatively associated random variables are also negatively associated. The same holds if h j are non-increasing functions.

References

  1. Peterson, W.W. Addressing for random-access storage. IBM J. Res. Dev. 1957, 1, 130–146. [Google Scholar] [CrossRef]
  2. Gonnet, G.H.; Baeza-Yates, R. Handbook of Algorithms and Data Structures; Addison-Wesley: Workingham, UK, 1991. [Google Scholar]
  3. Knuth, D.E. The Art of Computer Programming, Vol. 3: Sorting and Searching; Addison-Wesley: Reading, UK, 1973. [Google Scholar]
  4. Vitter, J.S.; Flajolet, P. Average-case analysis of algorithms and data structures. In Handbook of Theoretical Computer Science, Volume A: Algorithms and Complexity; van Leeuwen, J., Ed.; MIT Press: Amsterdam, The Netherlands, 1990; pp. 431–524. [Google Scholar]
  5. Janson, S.; Viola, A. A unified approach to linear probing hashing with buckets. Algorithmica 2016, 75, 724–781. [Google Scholar]
  6. Pagh, A.; Pagh, R.; Ružić, M. Linear probing with 5-wise independence. SIAM Rev. 2011, 53, 547–558. [Google Scholar] [CrossRef]
  7. Richter, S.; Alvarez, V.; Dittrich, J. A seven-dimensional analysis of hashing methods and its implications on query processing. Porc. Vldb Endow. 2015, 9, 96–107. [Google Scholar] [CrossRef]
  8. Thorup, M.; Zhang, Y. Tabulation-based 5-independent hashing with applications to linear probing and second moment estimation. SIAM J. Comput. 2012, 41, 293–331. [Google Scholar] [CrossRef]
  9. Pittel, B. Linear probing: The probable largest search time grows logarithmically with the number of records. J. Algorithms 1987, 8, 236–249. [Google Scholar]
  10. Azar, Y.; Broder, A.Z.; Karlin, A.R.; Upfal, E. Balanced allocations. SIAM J. Comput. 2000, 29, 180–200. [Google Scholar] [CrossRef]
  11. Vöcking, B. How asymmetry helps load balancing. J. ACM 2003, 50, 568–589. [Google Scholar] [CrossRef]
  12. Malalla, E. Two-Way Hashing with Separate Chaining and Linear Probing. Ph.D. Thesis, School of Computer Science, McGill University, Montreal, QC, Canada, 2004. [Google Scholar]
  13. Dalal, K.; Devroye, L.; Malalla, E.; McLeish, E. Two-way chaining with reassignment. SIAM J. Comput. 2005, 35, 327–340. [Google Scholar] [CrossRef]
  14. Berenbrink, P.; Czumaj, A.; Steger, A.; Vöcking, B. Balanced allocations: The heavily loaded case. SIAM J. Comput. 2006, 35, 1350–1385. [Google Scholar] [CrossRef]
  15. Malalla, E. Two-way chaining for non-uniform distributions. Int. J. Comput. Math. 2010, 87, 454–473. [Google Scholar]
  16. Morris, R. Scatter storage techniques. Commun. ACM 1968, 11, 38–44. [Google Scholar] [CrossRef]
  17. De Balbine, G. Computational Analysis of the Random Components Induced by Binary Equivalence Relations. Ph.D. Thesis, California Institute of Technology, Pasadena, CA, USA, 1969. [Google Scholar]
  18. Ullman, J.D. A note on the efficiency of hashing functions. J. ACM 1972, 19, 569–575. [Google Scholar]
  19. Yao, A.C. Uniform hashing is optimal. J. ACM 1985, 32, 687–693. [Google Scholar] [CrossRef]
  20. Munro, J.I.; Celis, P. Techniques for collision resolution in hash tables with open addressing. In Proceedings of the 1986 Fall Joint Computer Conference, Dallas, TX, USA, 2–6 November 1999; pp. 601–610. [Google Scholar]
  21. Poblete, P.V.; Munro, J.I. Last-Come-First-Served hashing. J. Algorithms 1989, 10, 228–248. [Google Scholar]
  22. Celis, P. Robin Hood Hashing. Ph.D. Thesis, Computer Science Department, University of Waterloo, Waterloo, ON, Canada, 1986. [Google Scholar]
  23. Celis, P.; Larson, P.; Munro, J.I. Robin Hood hashing (preliminary report). In Proceedings of the 26th Annual IEEE Symposium on Foundations of Computer Science (FOCS), Portland, OR, USA, 21–23 October 1985; pp. 281–288. [Google Scholar]
  24. Larson, P. Analysis of uniform hashing. J. ACM 1983, 30, 805–819. [Google Scholar] [CrossRef]
  25. Bollobás, B.; Broder, A.Z.; Simon, I. The cost distribution of clustering in random probing. J. ACM 1990, 37, 224–237. [Google Scholar]
  26. Knuth, D.E. Notes on “Open” Addressing. Unpublished Notes. 1963. Available online: https://jeffe.cs.illinois.edu/teaching/datastructures/2011/notes/knuth-OALP.pdf (accessed on 31 August 2023).
  27. Konheim, A.G.; Weiss, B. An occupancy discipline and applications. SIAM Journal on Applied Mathematics 1966, 14, 1266–1274. [Google Scholar] [CrossRef]
  28. Mendelson, H.; Yechiali, U. A new approach to the analysis of linear probing schemes. J. ACM 1980, 27, 474–483. [Google Scholar]
  29. Guibas, L.J. The analysis of hashing techniques that exhibit K-ary clustering. J. ACM 1978, 25, 544–555. [Google Scholar] [CrossRef]
  30. Lueker, G.S.; Molodowitch, M. More analysis of double hashing. Combinatorica 1993, 13, 83–96. [Google Scholar] [CrossRef]
  31. Schmidt, J.P.; Siegel, A. Double Hashing Is Computable and Randomizable with Universal Hash Functions; Submitted. A Full Version Is Available as Technical Report TR1995-686; Computer Science Department, New York University: New York, NY, USA, 1995. [Google Scholar]
  32. Siegel, A.; Schmidt, J.P. Closed Hashing Is Computable and Optimally Randomizable with Universal Hash Functions; Submitted. A Full Version Is Available as Technical Report TR1995-687; Computer Science Department, New York University: New York, NY, USA, 1995. [Google Scholar]
  33. Flajolet, P.; Poblete, P.V.; Viola, A. On the analysis of linear probing hashing. Algorithmica 1998, 22, 490–515. [Google Scholar] [CrossRef]
  34. Knuth, D.E. Linear probing and graphs, average-case analysis for algorithms. Algorithmica 1998, 22, 561–568. [Google Scholar] [CrossRef]
  35. Viola, A.; Poblete, P.V. The analysis of linear probing hashing with buckets. Algorithmica 1998, 21, 37–71. [Google Scholar] [CrossRef]
  36. Janson, S. Asymptotic distribution for the cost of linear probing hashing. Random Struct. Algorithms 2001, 19, 438–471. [Google Scholar] [CrossRef]
  37. Gonnet, G.H. Open addressing hashing with unequal-probability keys. J. Comput. Syst. Sci. 1980, 20, 354–367. [Google Scholar] [CrossRef]
  38. Aldous, D. Hashing with linear probing, under non-uniform probabilities. Probab. Eng. Inform. Sci. 1988, 2, 1–14. [Google Scholar] [CrossRef]
  39. Pflug, G.C.; Kessler, H.W. Linear probing with a nonuniform address distribution. J. ACM 1987, 34, 397–410. [Google Scholar] [CrossRef]
  40. Poblete, P.V.; Viola, A.; Munro, J.I. Analyzing the LCFS linear probing hashing algorithm with the help of Maple. Maple Tech. Newlett. 1997, 4, 8–13. [Google Scholar]
  41. Janson, S. Individual Displacements for Linear Probing Hashing with Different Insertion Policies; Technical Report No. 35; Department of Mathematics, Uppsala University: Uppsala, Sweden, 2003. [Google Scholar]
  42. Viola, A. Exact distributions of individual displacements in linear probing hashing. ACM Trans. Algorithms 2005, 1, 214–242. [Google Scholar] [CrossRef]
  43. Chassaing, P.; Louchard, G. Phase transition for parking blocks, Brownian excursion and coalescence. Random Struct. Algorithms 2002, 21, 76–119. [Google Scholar] [CrossRef]
  44. Gonnet, G.H. Expected length of the longest probe sequence in hash code searching. J. ACM 1981, 28, 289–304. [Google Scholar] [CrossRef]
  45. Devroye, L.; Morin, P.; Viola, A. On worst-case Robin Hood hashing. SIAM J. Comput. 2004, 33, 923–936. [Google Scholar] [CrossRef]
  46. Gonnet, G.H.; Munro, J.I. Efficient ordering of hash tables. SIAM J. Comput. 1979, 8, 463–478. [Google Scholar] [CrossRef]
  47. Brent, R.P. Reducing the retrieval time of scatter storage techniques. Commun. ACM 1973, 16, 105–109. [Google Scholar] [CrossRef]
  48. Madison, J.A.T. Fast lookup in hash tables with direct rehashing. Comput. J. 1980, 23, 188–189. [Google Scholar] [CrossRef]
  49. Mallach, E.G. Scatter storage techniques: A uniform viewpoint and a method for reducing retrieval times. Comput. J. 1977, 20, 137–140. [Google Scholar] [CrossRef]
  50. Rivest, R.L. Optimal arrangement of keys in a hash table. J. ACM 1978, 25, 200–209. [Google Scholar] [CrossRef]
  51. Pagh, R.; Rodler, F.F. Cuckoo hashing. In Algorithms—ESA 2001, Proceedings of the 9th Annual European Symposium, Aarhus, Denmark, 28–31 August 2001; LNCS 2161; Springer: Berlin/Heidelberg, Germany, 2001; pp. 121–133. [Google Scholar]
  52. Devroye, L.; Morin, P. Cuckoo hashing: Further analysis. Inf. Process. Lett. 2003, 86, 215–219. [Google Scholar] [CrossRef]
  53. Östlin, A.; Pagh, R. Uniform hashing in constant time and linear space. In Proceedings of the 35th Annual ACM Symposium on Theory of Computing (STOC), San Diego, CA, USA, 9–11 June 2003; pp. 622–628. [Google Scholar]
  54. Dietzfelbinger, M.; Wolfel, P. Almost random graphs with simple hash functions. In Proceedings of the 35th Annual ACM Symposium on Theory of Computing (STOC), San Diego, CA, USA, 9–11 June 2003; pp. 629–638. [Google Scholar]
  55. Fotakis, D.; Pagh, R.; Sanders, P.; Spirakis, P. Space efficient hash tables with worst case constant access time. In STACS 2003, Proceedings of the 20th Annual Symposium on Theoretical Aspects of Computer Science, Berlin, Germany, 27 February–1 March 2003; LNCS 2607; Springer: Berlin/Heidelberg, Germany, 2003; pp. 271–282. [Google Scholar]
  56. Fountoulakis, N.; Panagiotou, K. Sharp Load Thresholds for Cuckoo Hashing. Random Struct. Algorithms 2012, 41, 306–333. [Google Scholar] [CrossRef]
  57. Lehman, E.; Panigrahy, R. 3.5-Way Cuckoo Hashing for the Price of 2-and-a-Bit. In Proceedings of the 17th Annual European Symposium, Copenhagen, Denmark, 7–9 September 2009; pp. 671–681. [Google Scholar]
  58. Dietzfelbinger, M.; Weidling, C. Balanced allocation and dictionaries with tightly packed constant size bins. Theor. Comput. Sci. 2007, 380, 47–68. [Google Scholar] [CrossRef]
  59. Fountoulakis, N.; Panagiotou, K.; Steger, A. On the Insertion Time of Cuckoo Hashing. SIAM J. Comput. 2013, 42, 2156–2181. [Google Scholar] [CrossRef]
  60. Frieze, A.M.; Melsted, P. Maximum Matchings in Random Bipartite Graphs and the Space Utilization of Cuckoo Hash Tables. Random Struct. Algorithms 2012, 41, 334–364. [Google Scholar] [CrossRef]
  61. Walzer, S. Load thresholds for cuckoo hashing with overlapping blocks. In Proceedings of the 45th International Colloquium on Automata, Languages, and Programming, Prague, Czech Republic, 9–13 July 2018; pp. 102:1–102:10. [Google Scholar]
  62. Frieze, A.M.; Melsted, P.; Mitzenmacher, M. An analysis of random-walk cuckoo hashing. SIAM J. Comput. 2011, 40, 291–308. [Google Scholar] [CrossRef]
  63. Pagh, R. Hash and displace: Efficient evaluation of minimal perfect hash functions. In Algorithms and Data Structures, Proceedings of the 6th International Workshop, WADS’99, Vancouver, BC, Canada, 11–14 August 1999; LNCS 1663; Springer: Berlin/Heidelberg, Germany, 1999; pp. 49–54. [Google Scholar]
  64. Pagh, R. On the cell probe complexity of membership and perfect hashing. In Proceedings of the 33rd Annual ACM Symposium on Theory of Computing (STOC), Crete, Greece, 6–8 July 2001; pp. 425–432. [Google Scholar]
  65. Dietzfelbinger, M.; auf der Heide, F.M. High performance universal hashing, with applications to shared memory simulations. In Data Structures and Efficient Algorithms; LNCS 594; Springer: Berlin/Heidelberg, Germany, 1992; pp. 250–269. [Google Scholar]
  66. Fredman, M.; Komlós, J.; Szemerédi, E. Storing a sparse table with O(1) worst case access time. J. ACM 1984, 31, 538–544. [Google Scholar] [CrossRef]
  67. Dietzfelbinger, M.; Karlin, A.; Mehlhorn, K.; auf der Heide, F.M.; Rohnert, H.; Tarjan, R. Dynamic perfect hashing: Upper and lower bounds. SIAM J. Comput. 1994, 23, 738–761. [Google Scholar] [CrossRef]
  68. Dietzfelbinger, M.; auf der Heide, F.M. A new universal class of hash functions and dynamic hashing in real time. In Automata, Languages and Programming, Proceedings of the 17th International Colloquium, Warwick University, UK, 16–20 July 1990; LNCS 443; Springer: Berlin/Heidelberg, Germany, 1990; pp. 6–19. [Google Scholar]
  69. Broder, A.Z.; Karlin, A. Multilevel adaptive hashing. In Proceedings of the 1st Annual ACM-SIAM Symposium on Discrete Algorithms (SODA), Salt Lake City, UT, USA, 5–8 January 2020; ACM Press: New York, NY, USA, 2000; pp. 43–53. [Google Scholar]
  70. Dietzfelbinger, M.; Gil, J.; Matias, Y.; Pippenger, N. Polynomial hash functions are reliable (extended abstract). In Automata, Languages and Programming, Proceedings of the 19th International Colloquium, Wien, Austria, 13–17 July 1992; LNCS 623; Springer: Berlin/Heidelberg, Germany, 1992; pp. 235–246. [Google Scholar]
  71. Johnson, N.L.; Kotz, S. Urn Models and Their Application: An Approach to Modern Discrete Probability Theory; John Wiley: New York, NY, USA, 1977. [Google Scholar]
  72. Kolchin, V.F.; Sevast’yanov, B.A.; Chistyakov, V.P. Random Allocations; V. H. Winston & Sons: Washington, DC, USA, 1978. [Google Scholar]
  73. Devroye, L. The expected length of the longest probe sequence for bucket searching when the distribution is not uniform. J. Algorithms 1985, 6, 1–9. [Google Scholar] [CrossRef]
  74. Raab, M.; Steger, A. “Balls and bins”—A simple and tight analysis. In Randomization and Approximation Techniques in Computer Science, Second International Workshop, RANDOM’98, Barcelona, Spain, 8–10 October 1998; LNCS 1518; Springer: Berlin/Heidelberg, Germany, 1998; pp. 159–170. [Google Scholar]
  75. Mitzenmacher, M.D. The Power of Two Choices in Randomized Load Balancing. Ph.D. Thesis, Computer Science Department, University of California at Berkeley, Berkeley, CA, USA, 1996. [Google Scholar]
  76. Karp, R.; Luby, M.; auf der Heide, F.M. Efficient PRAM simulation on a distributed memory machine. Algorithmica 1996, 16, 245–281. [Google Scholar] [CrossRef]
  77. Eager, D.L.; Lazowska, E.D.; Zahorjan, J. Adaptive load sharing in homogeneous distributed systems. IEEE Trans. Softw. Eng. 1986, 12, 662–675. [Google Scholar] [CrossRef]
  78. Vöcking, B. Symmetric vs. asymmetric multiple-choice algorithms. In Proceedings of the 2nd ARACNE Workshop, Aarhus, Denmark, 27 August 2001; pp. 7–15. [Google Scholar]
  79. Adler, M.; Berenbrink, P.; Schroeder, K. Analyzing an infinite parallel job allocation process. In Proceedings of the 6th European Symposium on Algorithms, Venice, Italy, 24–26 August 1998; pp. 417–428. [Google Scholar]
  80. Adler, M.; Chakrabarti, S.; Mitzenmacher, M.; Rasmussen, L. Parallel randomized load balancing. In Proceedings of the 27th Annual ACM Symposium on Theory of Computing (STOC), Las Vegas, NV, USA, 29 May–1 June 1995; pp. 238–247. [Google Scholar]
  81. Czumaj, A.; Stemann, V. Randomized Allocation Processes. Random Struct. Algorithms 2001, 18, 297–331. [Google Scholar] [CrossRef]
  82. Berenbrink, P.; Czumaj, A.; Friedetzky, T.; Vvedenskaya, N.D. Infinite parallel job allocations. In Proceedings of the 12th Annual ACM Symposium on Parallel Algorithms and Architectures (SPAA), Bar Harbor, ME, USA, 9–13 July 2000; pp. 99–108. [Google Scholar]
  83. Stemann, V. Parallel balanced allocations. In Proceedings of the 8th Annual ACM Symposium on Parallel Algorithms and Architectures (SPAA), Padua, Italy, 24–26 June 1996; pp. 261–269. [Google Scholar]
  84. Mitzenmacher, M. Studying balanced allocations with differential equations. Comb. Probab. Comput. 1999, 8, 473–482. [Google Scholar]
  85. Mitzenmacher, M.D.; Richa, A.; Sitaraman, R. The power of two random choices: A survey of the techniques and results. In Handbook of Randomized Computing; Pardalos, P., Rajasekaran, S., Rolim, J., Eds.; Kluwer Press: London, UK, 2000; pp. 255–305. [Google Scholar]
  86. Broder, A.; Mitzenmacher, M. Using multiple hash functions to improve IP lookups. In Proceedings of the 20th Annual Joint Conference of the IEEE Computer and Communications Societies (INFOCOM 2001); Full Version Available as Technical Report TR–03–00; Department of Computer Science, Harvard University: Cambridge, MA, USA, 2000; pp. 1454–1463. [Google Scholar]
  87. Mitzenmacher, M.; Vöcking, B. The asymptotics of Selecting the shortest of two, improved. In Proceedings of the 37th Annual Allerton Conference on Communication, Control, and Computing, Monticello, IL, USA, 22–23 September 1998; pp. 326–327. [Google Scholar]
  88. Wu, J.; Kobbelt, L. Fast mesh decimation by multiple-choice techniques. In Proceedings of the Vision, Modeling, and Visualization, Erlangen, Germany, 20–22 November 2002; pp. 241–248. [Google Scholar]
  89. Siegel, A. On universal classes of extremely random constant time hash functions and their time-space tradeoff. Technical Report TR1995-684, Computer Science Department, New York University, 1995. A previous version appeared under the title “On universal classes of fast high performance hash functions, their time-space tradeoff and their applications”. In Proceedings of the 30th Annual IEEE Symposium on Foundations of Computer Science (FOCS), Triangle Park, NC, USA, 30 October–1 November 1989; pp. 20–25. [Google Scholar]
  90. Auf der Heide, F.M.; Scheideler, C.; Stemann, V. Exploiting storage redundancy to speed up randomized shared memory simulations. Theor. Comput. Sci. 1996, 162, 245–281. [Google Scholar]
  91. Schickinger, T.; Steger, A. Simplified witness tree arguments. In SOFSEM 2000: Theory and Practice of Informatics, Proceedings of the 27th Annual Conference on Current Trends in Theory and Practice of Informatics, Milovy, Czech Republic, 25 November–2 December 2000; LNCS 1963; Springer: Berlin/Heidelberg, Germany, 2000; pp. 71–78. [Google Scholar]
  92. Cole, R.; Maggs, B.M.; auf der Heide, F.M.; Mitzenmacher, M.; Richa, A.W.; Schroeder, K.; Sitaraman, R.K.; Voecking, B. Randomized protocols for low-congestion circuit routing in multistage interconnection networks. In Proceedings of the 29th Annual ACM Symposium on the Theory of Computing (STOC), El Paso, TX, USA, 4–6 May 1998; pp. 378–388. [Google Scholar]
  93. Cole, R.; Frieze, A.; Maggs, B.M.; Mitzenmacher, M.; Richa, A.W.; Sitaraman, R.K.; Upfal, E. On balls and bins with deletions. In Randomization and Approximation Techniques in Computer Science, Proceedings of the 2nd International Workshop, RANDOM’98, Barcelona, Spain, 8–10 October 1998; LNCS 1518; Springer: Berlin/Heidelberg, Germany, 1998; pp. 145–158. [Google Scholar]
  94. Swain, S.N.; Subudhi, A. A novel RACH scheme for efficient access in 5G and Beyond betworks using hash function. In Proceedings of the 2022 IEEE Future Networks World Forum (FNWF), Montreal, QC, Canada, 10–14 October 2022; pp. 75–82. [Google Scholar]
  95. Guo, J.; Liu, Z.; Tian, S.; Huang, F.; Li, J.; Li, X.; Igorevich, K.K.; Ma, J. TFL-DT: A trust evaluation scheme for federated learning in digital twin for mobile networks. IEEE J. Sel. Areas Commun. 2023, 41, 3548–3560. [Google Scholar] [CrossRef]
  96. Okamoto, M. Some inequalities relating to the partial sum of binomial probabilities. Ann. Math. Stat. 1958, 10, 29–35. [Google Scholar] [CrossRef]
  97. Dubhashi, D.; Ranjan, D. Balls and bins: A study in negative dependence. Random Struct. Algorithms 1998, 13, 99–124. [Google Scholar] [CrossRef]
  98. Esary, J.D.; Proschan, F.; Walkup, D.W. Association of random variables, with applications. Ann. Math. Stat. 1967, 38, 1466–1474. [Google Scholar] [CrossRef]
  99. Joag-Dev, K.; Proschan, F. Negative association of random variables, with applications. Ann. Stat. 1983, 11, 286–295. [Google Scholar] [CrossRef]
Figure 1. An illustration of algorithm ShortSeq ( n , m ) in terms of balls (keys) and bins (cells). Each ball is inserted into the empty bin found by the shorter sequence.
Figure 1. An illustration of algorithm ShortSeq ( n , m ) in terms of balls (keys) and bins (cells). Each ball is inserted into the empty bin found by the shorter sequence.
Algorithms 16 00500 g001
Figure 2. Algorithm SmallCluster ( n , m ) inserts each key into the empty cell adjacent to the smaller cluster, breaking ties randomly. The size of the clusters is determined by probing linearly in both directions.
Figure 2. Algorithm SmallCluster ( n , m ) inserts each key into the empty cell adjacent to the smaller cluster, breaking ties randomly. The size of the clusters is determined by probing linearly in both directions.
Algorithms 16 00500 g002
Figure 3. An illustration of algorithm DecideFirst ( n , m ) . The hash table is divided into blocks of size β 2 . The number under each block is its weight. Each key decides first to land into the block of smaller weight, breaking ties randomly, then probes linearly to find its terminal cell.
Figure 3. An illustration of algorithm DecideFirst ( n , m ) . The hash table is divided into blocks of size β 2 . The number under each block is its weight. Each key decides first to land into the block of smaller weight, breaking ties randomly, then probes linearly to find its terminal cell.
Algorithms 16 00500 g003
Figure 4. Algorithm WalkFirst ( n , m ) inserts each key into the terminal cell that belongs to the least crowded block, breaking ties arbitrarily.
Figure 4. Algorithm WalkFirst ( n , m ) inserts each key into the terminal cell that belongs to the least crowded block, breaking ties arbitrarily.
Algorithms 16 00500 g004
Figure 5. A portion of the hash table showing the largest cluster, and the set S, which consists of the full consecutive blocks and their left neighbor.
Figure 5. A portion of the hash table showing the largest cluster, and the set S, which consists of the full consecutive blocks and their left neighbor.
Algorithms 16 00500 g005
Figure 6. The full history tree of key 18. White nodes represent type (a) nodes. Black nodes are type (b) nodes—they refer to keys already encountered in bfs order. Gray nodes are type (c) nodes—they occur when a key selects an empty block.
Figure 6. The full history tree of key 18. White nodes represent type (a) nodes. Black nodes are type (b) nodes—they refer to keys already encountered in bfs order. Gray nodes are type (c) nodes—they occur when a key selects an empty block.
Algorithms 16 00500 g006
Figure 7. A witness tree of height h which is a truncated history tree without gray nodes. The boxes at the lowest level are block nodes. They represent selected blocks with load of at least ξ . The load of the block that contains key 70 is at least h + ξ .
Figure 7. A witness tree of height h which is a truncated history tree without gray nodes. The boxes at the lowest level are block nodes. They represent selected blocks with load of at least ξ . The load of the block that contains key 70 is at least h + ξ .
Algorithms 16 00500 g007
Table 1. The average and the maximum successful search and insert times averaged over 10 iterations each consisting of 100 simulations of the algorithms. The best successful search time is shown in boldface and the best insert time is shown in italic.
Table 1. The average and the maximum successful search and insert times averaged over 10 iterations each consisting of 100 simulations of the algorithms. The best successful search time is shown in boldface and the best insert time is shown in italic.
n α  ClassicLinear
Insert/Search Time
 ShortSeq
Insert/Search Time
 SmallCluster
Search Time
 SmallCluster
InsertTime
Avg Max Avg Max Avg Max Avg Max
2 8 0.41.335.751.284.571.284.691.509.96
0.94.3868.152.8639.723.0535.696.6371.84
2 12 0.41.3310.661.287.351.297.491.5214.29
0.95.39275.912.9078.213.0766.036.91118.34
2 16 0.41.3316.901.2810.301.2910.141.5218.05
0.95.49581.702.89120.323.0794.586.92155.36
2 20 0.41.3323.641.2813.241.2913.031.5221.41
0.95.50956.022.89164.543.07122.656.92189.22
2 22 0.41.3326.941.2814.941.2914.441.5223.33
0.95.501157.342.89188.023.07136.626.93205.91
Table 2. The average maximum cluster size and the average cluster size over 100 simulations of the algorithms. The best performances are drawn in boldface.
Table 2. The average maximum cluster size and the average cluster size over 100 simulations of the algorithms. The best performances are drawn in boldface.
n α  ClassicLinear  ShortSeq  SmallCluster
Avg Max Avg Max Avg Max
2 8 0.42.028.321.766.051.765.90
0.915.1087.6312.2750.1912.2643.84
2 12 0.42.0314.951.759.481.759.05
0.915.17337.2212.35106.2412.3478.75
2 16 0.42.0222.541.7512.761.7512.08
0.915.16678.1212.36155.2612.36107.18
2 20 0.42.0229.921.7516.051.7515.22
0.915.171091.0312.35203.1612.35136.19
2 22 0.42.0233.811.7517.741.7516.65
0.915.171309.0412.35226.4412.35150.23
Table 3. The average and the maximum successful search time averaged over 10 iterations each consisting of 100 simulations of the algorithms. The best performances are drawn in boldface.
Table 3. The average and the maximum successful search time averaged over 10 iterations each consisting of 100 simulations of the algorithms. The best performances are drawn in boldface.
n α  LocallyLinear  WalkFirst  DecideFirst
Avg Max Avg Max Avg Max
2 8 0.41.734.731.785.321.755.26
0.94.7636.234.7643.985.0659.69
2 12 0.41.746.251.807.861.787.88
0.94.7647.664.8067.044.94108.97
2 16 0.41.767.931.809.841.7810.08
0.94.7856.404.8989.775.18137.51
2 20 0.41.768.421.8112.081.7912.39
0.94.7765.074.98108.245.26162.04
2 22 0.41.769.181.8112.881.7913.37
0.94.8071.695.04118.065.32181.46
Table 4. The average and the maximum insert time averaged over 10 iterations each consisting of 100 simulations of the algorithms. The best performances are drawn in boldface.
Table 4. The average and the maximum insert time averaged over 10 iterations each consisting of 100 simulations of the algorithms. The best performances are drawn in boldface.
n α  LocallyLinear  WalkFirst  DecideFirst
Avg Max Avg Max Avg Max
2 8 0.41.142.782.526.051.153.30
0.92.8922.606.1948.003.1942.64
2 12 0.41.143.382.538.481.175.19
0.92.9127.226.2869.303.1684.52
2 16 0.41.154.082.5310.401.176.56
0.92.8431.216.4391.213.17106.09
2 20 0.41.154.642.5412.581.188.16
0.92.8935.216.54109.713.22117.42
2 22 0.41.154.992.5413.411.188.83
0.92.9138.756.61119.073.26132.83
Table 5. The average and the maximum cluster sizes averaged over 10 iterations each consisting of 100 simulations of the algorithms. The best performances are drawn in boldface.
Table 5. The average and the maximum cluster sizes averaged over 10 iterations each consisting of 100 simulations of the algorithms. The best performances are drawn in boldface.
n α  LocallyLinear  WalkFirst  DecideFirst
Avg Max Avg Max Avg Max
2 8 0.41.574.341.654.701.634.81
0.912.1833.3512.5434.4013.4847.76
2 12 0.41.626.061.686.321.686.82
0.912.4248.7612.7851.8013.4594.98
2 16 0.41.627.141.687.311.688.92
0.912.6659.6112.9862.2413.53125.40
2 20 0.41.658.251.718.501.7110.76
0.912.8367.2313.1169.4513.62145.30
2 22 0.41.628.901.718.951.7111.46
0.912.7265.5813.1973.2213.66164.45
Disclaimer/Publisher’s Note: The statements, opinions and data contained in all publications are solely those of the individual author(s) and contributor(s) and not of MDPI and/or the editor(s). MDPI and/or the editor(s) disclaim responsibility for any injury to people or property resulting from any ideas, methods, instructions or products referred to in the content.

Share and Cite

MDPI and ACS Style

Dalal, K.; Devroye, L.; Malalla, E. Two-Way Linear Probing Revisited. Algorithms 2023, 16, 500. https://doi.org/10.3390/a16110500

AMA Style

Dalal K, Devroye L, Malalla E. Two-Way Linear Probing Revisited. Algorithms. 2023; 16(11):500. https://doi.org/10.3390/a16110500

Chicago/Turabian Style

Dalal, Ketan, Luc Devroye, and Ebrahim Malalla. 2023. "Two-Way Linear Probing Revisited" Algorithms 16, no. 11: 500. https://doi.org/10.3390/a16110500

Note that from the first issue of 2016, this journal uses article numbers instead of page numbers. See further details here.

Article Metrics

Back to TopTop