100% found this document useful (1 vote)
43 views55 pages

The Joys of Hashing: Hash Table Programming With C 1st Edition Thomas Mailund - Explore The Complete Ebook Content With The Fastest Download

The document promotes various eBooks authored by Thomas Mailund, focusing on programming topics such as hashing, data structures, and statistical programming in R. It provides links to download these eBooks in multiple formats and emphasizes the efficiency of hash tables for data representation. The content includes detailed chapters on hash table implementation, collision resolution, and performance considerations.

Uploaded by

ozgenctieko
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
100% found this document useful (1 vote)
43 views55 pages

The Joys of Hashing: Hash Table Programming With C 1st Edition Thomas Mailund - Explore The Complete Ebook Content With The Fastest Download

The document promotes various eBooks authored by Thomas Mailund, focusing on programming topics such as hashing, data structures, and statistical programming in R. It provides links to download these eBooks in multiple formats and emphasizes the efficiency of hash tables for data representation. The content includes detailed chapters on hash table implementation, collision resolution, and performance considerations.

Uploaded by

ozgenctieko
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 55

Explore the full ebook collection and download it now at textbookfull.

com

The Joys of Hashing: Hash Table Programming with C


1st Edition Thomas Mailund

https://textbookfull.com/product/the-joys-of-hashing-hash-
table-programming-with-c-1st-edition-thomas-mailund/

OR CLICK HERE

DOWLOAD EBOOK

Browse and Get More Ebook Downloads Instantly at https://textbookfull.com


Click here to visit textbookfull.com and download textbook now
Your digital treasures (PDF, ePub, MOBI) await
Download instantly and pick your perfect format...

Read anywhere, anytime, on any device!

Domain Specific Languages in R Advanced Statistical


Programming 1st Edition Thomas Mailund

https://textbookfull.com/product/domain-specific-languages-in-r-
advanced-statistical-programming-1st-edition-thomas-mailund/

textbookfull.com

Domain Specific Languages in R Advanced Statistical


Programming 1st Edition Thomas Mailund

https://textbookfull.com/product/domain-specific-languages-in-r-
advanced-statistical-programming-1st-edition-thomas-mailund-2/

textbookfull.com

Pointers in C Programming A Modern Approach to Memory


Management Recursive Data Structures Strings and Arrays
Thomas Mailund
https://textbookfull.com/product/pointers-in-c-programming-a-modern-
approach-to-memory-management-recursive-data-structures-strings-and-
arrays-thomas-mailund/
textbookfull.com

String Algorithms in C: Efficient Text Representation and


Search 1st Edition Thomas Mailund

https://textbookfull.com/product/string-algorithms-in-c-efficient-
text-representation-and-search-1st-edition-thomas-mailund/

textbookfull.com
Functional Programming in R: Advanced Statistical
Programming for Data Science, Analysis and Finance 1st
Edition Thomas Mailund
https://textbookfull.com/product/functional-programming-in-r-advanced-
statistical-programming-for-data-science-analysis-and-finance-1st-
edition-thomas-mailund/
textbookfull.com

Functional Data Structures in R: Advanced Statistical


Programming in R Thomas Mailund

https://textbookfull.com/product/functional-data-structures-in-r-
advanced-statistical-programming-in-r-thomas-mailund/

textbookfull.com

Advanced Object-Oriented Programming in R: Statistical


Programming for Data Science, Analysis and Finance 1st
Edition Thomas Mailund
https://textbookfull.com/product/advanced-object-oriented-programming-
in-r-statistical-programming-for-data-science-analysis-and-
finance-1st-edition-thomas-mailund/
textbookfull.com

Metaprogramming in R: Advanced Statistical Programming for


Data Science, Analysis and Finance 1st Edition Thomas
Mailund
https://textbookfull.com/product/metaprogramming-in-r-advanced-
statistical-programming-for-data-science-analysis-and-finance-1st-
edition-thomas-mailund/
textbookfull.com

Data Management Solutions Using SAS Hash Table Operations


: A Business Intelligence Case Study. Paul Dorfman

https://textbookfull.com/product/data-management-solutions-using-sas-
hash-table-operations-a-business-intelligence-case-study-paul-dorfman/

textbookfull.com
The Joys of
Hashing
Hash Table Programming with C

Thomas Mailund
The Joys of Hashing
Hash Table Programming
with C

Thomas Mailund
The Joys of Hashing: Hash Table Programming with C
Thomas Mailund
Aarhus N, Denmark

ISBN-13 (pbk): 978-1-4842-4065-6 ISBN-13 (electronic): 978-1-4842-4066-3


https://doi.org/10.1007/978-1-4842-4066-3
Library of Congress Control Number: 2019932793
Copyright © 2019 by Thomas Mailund
This work is subject to copyright. All rights are reserved by the Publisher, whether the whole or
part of the material is concerned, specifically the rights of translation, reprinting, reuse of
illustrations, recitation, broadcasting, reproduction on microfilms or in any other physical way,
and transmission or information storage and retrieval, electronic adaptation, computer software,
or by similar or dissimilar methodology now known or hereafter developed.
Trademarked names, logos, and images may appear in this book. Rather than use a trademark
symbol with every occurrence of a trademarked name, logo, or image we use the names, logos,
and images only in an editorial fashion and to the benefit of the trademark owner, with no
intention of infringement of the trademark.
The use in this publication of trade names, trademarks, service marks, and similar terms, even if
they are not identified as such, is not to be taken as an expression of opinion as to whether or not
they are subject to proprietary rights.
While the advice and information in this book are believed to be true and accurate at the date of
publication, neither the authors nor the editors nor the publisher can accept any legal
responsibility for any errors or omissions that may be made. The publisher makes no warranty,
express or implied, with respect to the material contained herein.
Managing Director, Apress Media LLC: Welmoed Spahr
Acquisitions Editor: Steve Anglin
Development Editor: Matthew Moodie
Coordinating Editor: Mark Powers
Cover designed by eStudioCalamar
Cover image designed by Freepik (www.freepik.com)
Distributed to the book trade worldwide by Springer Science+Business Media New York, 233
Spring Street, 6th Floor, New York, NY 10013. Phone 1-800-SPRINGER, fax (201) 348-4505, e-mail
[email protected], or visit www.springeronline.com. Apress Media, LLC is a
California LLC and the sole member (owner) is Springer Science + Business Media Finance Inc
(SSBM Finance Inc). SSBM Finance Inc is a Delaware corporation.
For information on translations, please e-mail [email protected]; for reprint, paperback, or
audio rights, please email [email protected].
Apress titles may be purchased in bulk for academic, corporate, or promotional use. eBook
versions and licenses are also available for most titles. For more information, reference our Print
and eBook Bulk Sales web page at www.apress.com/bulk-sales.
Any source code or other supplementary material referenced by the author in this book is
available to readers on GitHub via the book’s product page, located at www.apress.com/
9781484240656. For more detailed information, please visit www.apress.com/source-code.
Printed on acid-free paper
Table of Contents
About the Author��������������������������������������������������������������������������������vii
About the Technical Reviewer�������������������������������������������������������������ix
Acknowledgements�����������������������������������������������������������������������������xi

Chapter 1: The Joys of Hashing������������������������������������������������������������1

Chapter 2: Hash Keys, Indices, and Collisions��������������������������������������7


Mapping from Keys to Indices������������������������������������������������������������������������������9
Risks of Collisions�����������������������������������������������������������������������������������������������12
Mapping Hash Keys to Bins��������������������������������������������������������������������������������18

Chapter 3: Collision Resolution, Load Factor, and Performance���������21


Chaining��������������������������������������������������������������������������������������������������������������21
Linked Lists���������������������������������������������������������������������������������������������������22
Chained Hashing Collision Resolution�����������������������������������������������������������25
Open Addressing�������������������������������������������������������������������������������������������������27
Probing Strategies����������������������������������������������������������������������������������������������32
Load and Performance����������������������������������������������������������������������������������������35
Theoretical Runtime Performance�����������������������������������������������������������������35
Experiments��������������������������������������������������������������������������������������������������������43

Chapter 4: Resizing����������������������������������������������������������������������������49
Amortizing Resizing Costs����������������������������������������������������������������������������������50
Resizing Chained Hash Tables����������������������������������������������������������������������������57

iii
Table of Contents

Resizing Open Addressing Hash Tables��������������������������������������������������������������61


Theoretical Considerations for Choosing the Load Factor����������������������������������65
Experiments��������������������������������������������������������������������������������������������������������68
Resizing When Table Sizes Are Not Powers of Two���������������������������������������������75
Dynamic Resizing������������������������������������������������������������������������������������������������85

Chapter 5: Adding Application Keys and Values�������������������������������101


Hash Sets����������������������������������������������������������������������������������������������������������103
Chained Hashing�����������������������������������������������������������������������������������������104
Updating Linked Lists����������������������������������������������������������������������������������105
Updating the Hash Table������������������������������������������������������������������������������110
Open Addressing�����������������������������������������������������������������������������������������114
Implementing Hash Maps���������������������������������������������������������������������������������120
Chained Hashing�����������������������������������������������������������������������������������������121
Updates to the Linked Lists�������������������������������������������������������������������������121
Updates to the Hash Table���������������������������������������������������������������������������127
Open Addressing�����������������������������������������������������������������������������������������132

Chapter 6: Heuristic Hash Functions������������������������������������������������139


What Makes a Good Hash Function?����������������������������������������������������������������141
Hashing Computer Words����������������������������������������������������������������������������������143
Additive Hashing������������������������������������������������������������������������������������������146
Rotating Hashing�����������������������������������������������������������������������������������������148
One-at-a-Time Hashing�������������������������������������������������������������������������������152
Jenkins Hashing������������������������������������������������������������������������������������������161
Hashing Strings of Bytes�����������������������������������������������������������������������������������166

iv
Table of Contents

Chapter 7: Universal Hashing�����������������������������������������������������������173


Uniformly Distributed Keys�������������������������������������������������������������������������������174
Universal Hashing���������������������������������������������������������������������������������������������175
Stronger Universal Families������������������������������������������������������������������������������176
Binning Hash Keys���������������������������������������������������������������������������������������177
Collision Resolution Strategies��������������������������������������������������������������������178
Constructing Universal Families�����������������������������������������������������������������������179
Nearly Universal Families����������������������������������������������������������������������������180
Polynomial Construction for k-Independent Families����������������������������������180
Tabulation Hashing��������������������������������������������������������������������������������������182
Performance Comparison����������������������������������������������������������������������������186
Rehashing���������������������������������������������������������������������������������������������������������190

Chapter 8: Conclusions���������������������������������������������������������������������199

Bibliography�������������������������������������������������������������������������������������201

Index�������������������������������������������������������������������������������������������������203

v
About the Author
Thomas Mailund is an associate professor in bioinformatics at Aarhus
University, Denmark. He has a background in math and computer science.
For the past decade, his main focus has been on genetics and evolutionary
studies, particularly comparative genomics, speciation, and gene flow
between emerging species.
He is the author of Domain-Specific Languages in R, Beginning Data
Science in R, Functional Programming in R, and Metaprogramming in R, all
from Apress, as well as other books.

vii
About the Technical Reviewer
Michael Thomas has worked in software
development for over 20 years as an individual
contributor, team lead, program manager, and
vice president of engineering. Michael has over
10 years of experience working with mobile
devices. His current focus is in the medical
sector using mobile devices to accelerate
information transfer between patients and
health care providers.

ix
Acknowledgments
I am very grateful to Rasmus Pagh for comments on the manuscript,
suggestions for topics to add, and correcting me when I have been
imprecise or downright wrong. I am also grateful to Anders Halager for
many discussions about implementation details and bit fiddling. I am also
grateful to Shiella Balbutin for proofreading the book.

xi
CHAPTER 1

The Joys of Hashing


This book is an introduction to the hash table data structure. When
implemented and used appropriately, hash tables are exceptionally
efficient data structures for representing sets and lookup tables. They
provide constant time, low overhead, insertion, deletion, and lookup.
The book assumes the reader is familiar with programming and the
C programming language. For the theoretical parts of the book, it also
assumes some familiarity with probability theory and algorithmic theory.
Hash tables are constructed from two basic ideas: reducing application
keys to a hash key, a number in the range from 0 to some N – 1, and
mapping that number into a smaller range from 0 to m – 1, m « N. We can
use the small range to index into an array with constant time access. Both
ideas are simple, but how they are implemented in practice affects the
efficiency of hash tables.
Consider Figure 1-1. This figure illustrates the main components of
storing values in a hash table: application values, which are potentially
complex, are mapped to hash keys, which are integer values in a range of
size N, usually zero to N – 1. In the figure, N = 64. Doing this simplifies the
representation of the values; now you only have integers as keys, and if N is
small, you can store them in an array of size N. You use their hash keys as
their index into the array. However, if N is large, this is not feasible.
If, for example, the space of hash keys is 32-bit integers, then N = 4, 294,
967, 295, slightly more than four billion. An array of bytes of this size would,

© Thomas Mailund 2019 1


T. Mailund, The Joys of Hashing, https://doi.org/10.1007/978-1-4842-4066-3_1
Chapter 1 The Joys of Hashing

therefore, take up more than four gigabytes of space. To be able to store


pointers or integers, simple objects, you would need between four and
eight times as much memory. It is impractical to use this size of an array to
store some application keys.

Application value space Hash key space Table bin space


0
1
2
3
4
5
6
7
8
9
10
11
12 0
13
1
14
2
15
3
16
4
17
5
18
6
19
20 7
21
22
23
24
25
26
27
28
29
30
31
32
.
.
.
61
62
63

Figure 1-1. Values map to hash keys that then map to table bins

Even if N is considerably smaller than four-byte words, if you plan to


store n « N keys, you waste a lot of space to have the array. Since this array
needs to be allocated and initialized, merely creating it will cost you O(N).
Even if you get constant time insertion and deletion into such an array, the
cost of producing it can easily swamp the time your algorithm will spend
while using the array. If you want a table that is efficient, you should be
able to both initialize it and use it to insert or delete n keys, all in time O(n).
Therefore, N should be in O(n).

2
Chapter 1 The Joys of Hashing

The typical solution to this is to keep N large but have a second step
that reduces the hash key range down to a smaller bin range of size m with
m ∈ O(n); in the example, you use m = 8. If you keep m small, as in O(n),
you can allocate and initialize it in linear time, and you can get any bin in
it in constant time. To insert, check, or delete an element in the table, you
map the application value to its hash key and then map the hash key to a
bin index.
You reduce values to bin indices in two steps because the first step,
mapping data from your application domain to a number, is program-­
specific and cannot be part of a general hash table implementation.1
Moving from large integer intervals to smaller, however, can be
implemented as part of the hash table. If you resize the table to adapt it to
the number of keys you store in it, you need to change m. You do not want
the application programmer to provide separate functions for each m.
You can think of the hash key space, [N] = [0, ... , N – 1], as the interface
between the application and the data structure. The hash table itself can
map from this space to indices in an array, [m] = [0, ... , m – 1].
The primary responsibility of the first step is to reduce potentially
complicated application values to simpler hash keys, such as to map
application-relevant information like positions on a board game or
connections in a network down to integers. These integers can then be
handled by the hash table data structure. A second responsibility of the
function is to make the hash keys uniformly distributed in the range [N].
The binning strategy for mapping hash keys to bins assumes that the hash
keys are uniformly distributed to distribute keys into bins evenly. If this
is violated, the data structure does not guarantee (expected) constant
time operations. Here, you can add a third, middle step that maps from

1
I n some textbooks, you will see the hashing step and the binning step combined
and called hashing. Then you have a single function that maps application-
specific keys directly to bins. I prefer to consider this as two or three separate
functions, and it usually is implemented as such.

3
Chapter 1 The Joys of Hashing

[N] → [N] and scrambles the application hash keys to hash keys with a
better distribution; see Figure 1-2. These functions can be application-­
independent and part of a hash table library. You will return to such
functions in Chapter 6 and Chapter 7. Having a middle step does not
eliminate the need for application hash functions. You still need to map
complex data into integers. The middle step only alleviates the need for
an even distribution of keys. The map from application keys to hash keys
still has some responsibility for this, though. If it maps different data to
the same hash keys, then the middle step cannot do anything but map the
same input to the same output.

Application key space Hash key space Table bin space


Application value space
0 0
1 1
2 2
3 3
4 4
5 5
6 6
7 7
8 8
9 9
10 10
11 11
12 12 0
13 13
1
14
2
15 15
3
16
4
17 17
5
18 18
6
19 19
20 20 7
21 21
22 22
23 23
24 24
25 25
26 26
27
28 28
29 29
30 30
31 31
32 32
. .
. .
. .
61 61
62 62
63 63

Figure 1-2. If the application maps values to keys, but they are not
uniformly distributed, then a hashing step between the application
and the binning can be added

Strictly speaking, you do not need the distribution of hash keys to


be uniform as long as the likelihood of two different values mapping to
the same key is highly unlikely. The goal is to have uniformly distributed

4
Chapter 1 The Joys of Hashing

hash keys, as these are easiest to work with when analyzing theoretical
performance. The runtime results referred to in Chapter 3 assume this,
and therefore, we will as well. In Chapter 7, you will learn techniques for
achieving similar results without the assumption.
The book is primarily about implementing the hash table data
structure and only secondarily about hash functions. The concerns when
implementing hash tables are these: given hash keys with application
values attached to them, how do you represent the data such that you
can update and query tables in constant time? The fundamental idea
is, of course, to reduce hash keys to bins and then use an array of bins
containing values. In the purest form, you can store your data values
directly in the array at the index the hash function and binning functions
provide but if m is relatively small compared to the number of data values,
then you are likely to have collisions: cases where two hash keys map to the
same bin. Although different values are unlikely to hash to the same key in
the range [N], this does not mean that collisions are unlikely in the range
[m] if m is smaller than N (and as the number of keys you insert in the
table, n, approaches m, collisions are guaranteed). Dealing with collisions
is a crucial aspect of implementing hash tables, and a topic we will deal
with for a sizeable part of this book.

5
CHAPTER 2

Hash Keys, Indices,


and Collisions
As mentioned in the introduction, this book is primarily about
implementing hash tables and not hash functions. So to simplify the
exposition, assume that the data values stored in tables are identical to the
hash keys. In Chapter 5, you will address which changes you have to make
to store application data together with keys, but for most of the theory of
hash tables you only need to consider hash keys; everywhere else, you will
view additional data as black box data and just store their keys. While the
code snippets below cover all that you need to implement the concepts in
the chapter, you cannot easily compile them from the book, but you can
download the complete code listings from https://github.com/mailund/
JoyChapter2.
Assume that the keys are uniformly distributed in the interval
[N] = [0, ... , N – 1] where N is the maximum uint32_t and consider the
most straightforward hash table. It consists of an array where you can
store keys and a number holding the size of the table, m. To be able
to map from the range [N] to the range [m], you need to remember m.
You store this number in the variable size in the structure below. You
cannot use a special key to indicate that an entry in the table is not
occupied, so you will use a structure called struct bin that contains a
flag for this.

© Thomas Mailund 2019 7


T. Mailund, The Joys of Hashing, https://doi.org/10.1007/978-1-4842-4066-3_2
Chapter 2 Hash Keys, Indices, and Collisions

struct bin {
    int is_free : 1;
    uint32_t key;
};

struct hash_table {
    struct bin *table;
    uint32_t size;
};

Functions for allocating and deallocating tables can then look like this:

struct hash_table *empty_table(uint32_t size)


{
    struct hash_table *table =
        (struct hash_table*)malloc(sizeof(struct hash_table));
    table->table = (struct bin *)malloc(size * sizeof
(struct bin));
    for (uint32_t i = 0; i < size; ++i) {
        struct bin *bin = & table->table[i];
        bin->is_free = true;
    }
    table->size = size;
    return table;
}
void delete_table(struct hash_table *table)
{
    free(table->table);
    free(table);
}

8
Chapter 2 Hash Keys, Indices, and Collisions

The operations you want to implement on hash tables are the insertion
and deletion of keys and queries to test if a table holds a given key. You use
this interface to the three operations:

void insert_key (struct hash_table *table, uint32_t key);


bool contains_key (struct hash_table *table, uint32_t key);
void delete_key (struct hash_table *table, uint32_t key);

Mapping from Keys to Indices


When you have to map a hash key from [N] down to the range of the
indices in the array, [m], the most straightforward approach is to take the
remainder of a division by m:

    unsigned int index = key % table->size;

You then use that index to access the array. Assuming that you
never have collisions when doing this, the implementation of the three
operations would then be as simple as this:

void insert_key(struct hash_table *table, uint32_t key)


{
    uint32_t index = key % table->size;
    struct bin *bin = & table->table[index];
    if (bin->is_free) {
        bin->key = key;
        bin->is_free = false;
    } else {
        // There is already a key here, so we have a
        // collision. We cannot deal with this yet.
    }
}

9
Chapter 2 Hash Keys, Indices, and Collisions

bool contains_key(struct hash_table *table, uint32_t key)


{
    uint32_t index = key % table->size;
    struct bin *bin = & table->table[index];
    if (!bin->is_free && bin->key == key) {
        return true;
    } else {
        return false;
    }
}

void delete_key(struct hash_table *table, uint32_t key)


{
    uint32_t index = key % table->size;
    struct bin *bin = & table->table[index];
    if (bin->key == key) {
        bin->is_free = true;
    }
}

When inserting an element, you place the value at the index given by
the mapping from the space of hash keys to the range of the array. Deleting
a key is similarly simple: you set the flag in the bin to false. To check if the
table contains a key, you check that the bin is not free and that it contains
the right key. If you assume that the only way you can get an index at a
given index is if you have the key value, this would be correct. However,
you also usually check that the application keys match the key in the
hash table, not just that the hash keys match. In this implementation, the
application keys and hash keys are the same, so you check if the hash keys
are identical only. Because, of course, you could have a situation where two

10
Chapter 2 Hash Keys, Indices, and Collisions

different hash keys would map to the same bin index, even if the hash keys
never collide. The space of bin indices, after all, is much smaller than the
space of keys.
Collisions of hash values are rare events if they are the results of a
well-­designed hash function. Although collisions of hash keys are rare,
it does not imply that you cannot get collisions in the indices. The range
[N] is usually vastly larger than the array indices in the range [m]. Two
different hash keys can easily end up in the same hash table bin; see
Figure 2-1. Here, you have hash keys in the space of size N = 64 and only
m = 8 bins. The numbers next to the hash keys are written in octal, and
you map keys to bins by extracting the lower eight bits of the key, which
corresponds to the last digit in the octal representation. The keys 8 and
16, or 108 and 208 in octal, both map to bin number 0, so they collide in
the table.
The figure is slightly misleading since the hash space is only a factor of
eight larger than the size of the hash table. In any real application, the keys
range over a much wider interval than could ever be represented in a table.
In the setup in this book, the range [N] maps over all possible unsigned
integers, which in most C implementations means all possible memory
addresses on your computer. This space is much larger than what you
could reasonably use for an array; if you had to use your entire computer
memory for a hash table, you would have no space for your actual
computer program. Each value might map to a unique hash key, but when
you have to map the hash keys down to a smaller range to store values in a
table, you are likely to see collisions.

11
Chapter 2 Hash Keys, Indices, and Collisions

Hash key space Table bin space


0
1
2
3
4
5
6
7
8
9
10
11
12 0
13
1
14
2
15
3
16
4
17
5
18
6
19
20 7
21
22
23
24
25
26
27
28
29
30
31
32
.
.
.
61
62
63

Figure 2-1. Collisions of hash keys when binning them

Risks of Collisions
Assuming a uniform distribution of hash keys, let’s do some back-of-
the-­envelope calculations of collisions probabilities. The chances of
collisions are surprisingly high once the number of values approaches
even a small fraction of the number of indices we can hit. To figure

12
Chapter 2 Hash Keys, Indices, and Collisions

out the chances of collisions, let’s use the birthday paradox (https://
en.wikipedia.org/wiki/Birthday). In a room of n people, what is the
probability that two or more have the same birthday? Ignoring leap
years, there are 365 days in a year, so how many people do we need for
the chance that at least two have the same birthday is above one half?
This number, n, turns out to be very low. If we assume that each date is
equally likely as a birthday, then with only 23 people we would expect a
50% chance that at least two share a birthday.
Let’s phrase the problem of “at least two having the same birthday”
a little differently. Let’s ask “what is the probability that all n people have
different birthdays?” The answer to the first problem will then be one
minus the answer to the second.
To answer the second problem, we can reason like this: out of the n
people, the first birthday hits 1 out of 365 days without any collisions. The
second person, if we avoid collisions, has to hit 1 of the remaining 364
days. The third person has to have his birthday on 1 of the 363 remaining
days. Continuing this reasoning, the probability of no collisions in
birthdays of n people is

365 364 365 - n + 1


´ ´… ´ .
365 365 365

where 1 minus this product is then the risk of at least one collision when
there are n people in the room. Figure 2-2 shows this probability as a
function of the number of people. The curve crosses the point of 50%
collision risk between 22 and 23.

13
Chapter 2 Hash Keys, Indices, and Collisions

1.0
0.8
Collision risk
0.6
0.4
0.2
0.0

0 10 20 30 40 50
People

Figure 2-2. Birthday paradox

The math carries over to an arbitrary number of “days,” m, and tells


us what the risk of collision is if we try to insert n elements into a hash
table of size m. Provided that the keys are uniformly distributed in
the range from 0 to m − 1, the probability that there is at least one
collision is

m!
p ( n|m ) = 1 -
m (m - n )!
n

See Figure 2-3 for a few examples of m and n.

14
Chapter 2 Hash Keys, Indices, and Collisions

1000

1.0
10000

0.8
Collision risk
0.6
0.4
0.2
0.0 20000

0 50 100 150 200


n

Figure 2-3. Collision risks for different sizes of tables

In practice, you are less interested in when the risk of collision reaches
any particular probability than you are interested in how many items you
can put into a table of size n before you get the first collision. Let K denote
the random variable that represents the first time you get a collision when
inserting elements into the table. The probability that the first collision is
when you add item number k is

m! k -1
Pr ( K = k|m ) = ×
m ( m - k - 1) ! m
k

where the first term is the probability that there were no collisions in the first
k – 1 insertions and the second term is the probability that the kth element
hits one of the k – 1 slots already occupied. The expected number of inserts
you can do until you get the first collision can then be computed as
m +1
E [ k|m ] = åk × Pr ( K = k|m )
k =1

15
Chapter 2 Hash Keys, Indices, and Collisions

The sum starts at 1 where no collision is possible and ends at m + 1


where a collision is guaranteed. Figure 2-4 shows the expected waiting
time, together with sampled collision waiting times.
It may not be immediately apparent from Figure 2-3 and Figure 2-4
what the relationship between m and k is for the risk of collision, but it
should be evident that it is not linear. In Figure 2-3, increasing m by an
order of magnitude when going from 1,000 to 10,000 does not change the k
where the risk is above 50% by an order of magnitude; the change is closer
to a factor of three. Doubling m when going from 10,000 to 20,000 far from
doubles the k where you pass 50%. That the expected number of elements
you can insert into a table does not grow linearly with the size of the table
is even more apparent from Figure 2-4, but how large should you to have to
make a table before you can expect to avoid collisions?

Figure 2-4. Expected number of insertions before a collision

An approximation to the collision risk that is reasonably accurate for


low probabilities is this:

k2
p ( k |m ) »
2m

16
Chapter 2 Hash Keys, Indices, and Collisions

Figure 2-5 shows this approximation as dashed lines.

1000

1.0
0.8 10000
Collision risk

20000
0.6
0.4
0.2
0.0

0 50 100 150 200


n

Figure 2-5. Square approximation

The approximation is unquestionably very poor at high probabilities


(it tends to infinity, which is a bad approximation for a probability), but it
is only slightly conservative at low probabilities. The good thing about this
approximation is that it is easy to reason about it. You can rewrite it to

k2

2 p ( k |m )

The formula says that to keep the collision risk low, m has to be
proportional to the square of k, with a coefficient that is inversely
proportional to how low you want the risk.
This formula is potentially bad news. If you need to initialize the hash
table before you can use it,1 then you automatically have a quadratic
time algorithm on your hands. That is a hefty price to pay for constant

1
I t is technically possible to use the array in the table without initializing it, but it
requires some trickery that incurs overhead.

17
Chapter 2 Hash Keys, Indices, and Collisions

time access to the elements you put into the table. Since hash tables are
used everywhere, this should tell you that in practice they do not rely on
avoiding collisions entirely; they obviously have to deal with them, and
most of this book is about how to do so.

Mapping Hash Keys to Bins


Before you move on from the discussion on the size of the tables, however,
there is one more topic to address. You are mainly concerned with the
relationship between the number of elements you can efficiently put in a
hash table, n, and the size of the table, m, but you also need to consider
your choice for the value of m.
This is not important in most cases. You want to keep the size of
the table linear in the number of elements you put into it. Otherwise,
initializing the table will be expensive compared to the number of
operations you do on the table. If the reason that you use a hash table
is to get constant time operations, and thus a linear time usage for n
operations, it would be counter to the purpose to spend more time on
initializing them.
In the literature, you will often see suggested that the table size is
a prime. There are several reasons for this. One is that if there is some
structure to the keys, such as if they tend to be a power of some number
more often than not, and that number divides m, then you will only hit a
subsection of bins. Such patterns are not uncommon in applications. If
you choose a table size that is prime, the keys would have to be powers of
that particular prime for this to be a problem.
Sticking to primes has some drawbacks, however. You will often need
to resize tables if the number of keys you insert into it is not known ahead
of time; you will look at this in Chapter 4. If you want to stick to primes, you
need a table of primes to pick from when growing or shrinking your table. If
you instead choose table sizes that are powers of two, it is very easy to grow

18
Chapter 2 Hash Keys, Indices, and Collisions

and shrink them. You can easily combine modulus primes with this idea. If
you pick a prime p > m, you can index bins as h(x) mod p mod m. Modulus
p reduces the problem of regularity in keys and if m is a power of two, you
can grow and shrink tables easily and you can mask to get the bins.
If your keys are randomly distributed, you can easily pick table sizes
that are powers of two. If so, you can use the lower bits of keys as bin
indices and modulus can be replaced by bit masking. If the keys are
random, the lower bits will also be random.
You can mask out the lower bits of a key like this:

    unsigned int mask = table->size - 1;


    unsigned int index = key & mask;

Subtracting one from table size m will give you the lower k bits,
provided m is a power of two, and masking with that, gives you the index.
Masking is a faster operation than modulo. In my experiments, I see about
a factor of five in the speed difference. Compilers can optimize modulus to
masking if they know that m is a power of two, but if m is a prime (and larger
than two), this is of little help. How much of an issue this is depends on your
application and choice of hash function. Micro-­optimizations will matter very
little if you have hash functions that are slow to compute.
There is a trick to avoid modulo, however,2 and replace it with
multiplication. Multiplication is faster than modulus, but not as fast as
masking. Still, if you need to have m be a prime, it is still better than modulo.
The first idea is this: you do not need to map keys x to x mod m but you
can map them to any bin as long as you do so fairly. By fairly I mean that
each bin in [m] will contain the same number of keys if you map all of the
keys in [N] down to the keys in [m]. This is what the expression x mod m
does, but you can do it any way that you like.3

2
h ttps://tinyurl.com/yazblf4o
3
You cannot make a perfectly fair such mapping if N if m does not divide N —x
mod m cannot do this either. However, if N >> m, then you can get very close.

19
Chapter 2 Hash Keys, Indices, and Collisions

Typically, N is a power of two, N = 2w (for example w = 32-bit words). If


you want to map w-bit keys, x, to [m], you can use x⋅m/2w. This is obviously
not the same as x mod m but this map is as fair as that. The product x.m
will not necessarily fit in w bits, but it will fit into 2w bits, so if you use
32-­bit words for [N], you can cast them to 64-bit words, do the
multiplication, and then divide by 2w by shifting w bits:

    ((uint64_t) x * (uint64_t) m) >> 32 ;

In my experiments, this mapping is only about 50% slower than


masking.
Another trick is possible if you use Mersenne primes, which are those
on the form 2s – 1. One such is 261 – 1, which can be a good choice for 32-bit
words. Let p = 2s and x < 2s – 1. Let x be on the form a2s + b; that is, let x mod
2s = b. Because 2s mod p = 1, x mod p = a + b mod p. Since you use integer
division and b/s2 < 0, you also have x/2s = a. Because x < 2s − 1, x/2s mod
p = x/2s (i.e., it is itself modulo 2s).
Now, let y = (x mod 2s) + (x/s2). Again, because x < 2s − 1 you have a < p
so a + b < 2p. Therefore, either y ≤ p or y ≤ 2p. If the former, that is x mod p,
of the latter, then x mod p = y − p.
Because x mod 2x is the same as masking x by p and x/2s is the same as
shifting x by s bits, you can compute modulo as this:

uint64_t mod_Mersenne(uint64_t x, uint8_t s)


{
    uint64_t p = (uint64_t)(1 << s) - 1;
    uint64_t y = (x & p) + (x >> s);
    return (y > p) ? y - p : y;
}

This avoids multiplications and modulo, and only uses fast bit
operations. This will be much faster than modulo.

20
CHAPTER 3

Collision Resolution,
Load Factor, and
Performance
Collisions are inevitable when using a hash table, at least if you want the
table size, and thus the initialization time for the table, to be linear in the
number of keys you put into it. Therefore, you need a way to deal with
collisions so you can still insert keys if the bin you map it to is already
occupied. There are two classical approaches to collision resolution:
chaining (where you use linked lists to store colliding keys) and open
addressing (where you find alternative empty slots to store values in when
keys collide).
You can download the complete code for this chapter from
https://github.com/mailund/JoyChapter3.

C
 haining
One of the most straightforward approaches to resolve collisions is to
put colliding keys in a data structure that can hold them, and the most
straightforward data structure is a linked list.

© Thomas Mailund 2019 21


T. Mailund, The Joys of Hashing, https://doi.org/10.1007/978-1-4842-4066-3_3
Discovering Diverse Content Through
Random Scribd Documents
the melancholy spaces, once full of radiance and cheer and genial company.
All the doors of the staterooms had been removed, both those opening on
the guards and the inner ones, of which the panels were decorated with
mirrors and which gave upon the saloon. A vague jingle caught his
attention; a fragment of an electrolier still clung to the ceiling and
sometimes, shaken by the ripples, its glass pendants sent forth a shrill,
disconsolate vibration, like a note of funereal keening. Suddenly from
amidst that weird desolation of shifting waters a face stared up at him. It
was unmistakable. He saw it distinctly. But when he looked again it was
gone.
Floyd-Rosney was trembling from head to foot. He had turned ghastly
pale. But for the wall of the texas against which he staggered he might have
fallen. He did not question the reality of his impression. It was as definite as
the light of day,—a face strangely familiar, yet sinister, seen in the murky
depths. He wondered wildly if it could be the drowned face of some victim
of the wreck, or if this were now impossible, some curious explorer such as
himself, meeting here more serious mystery than any he had sought. The
next moment he broke into a harsh laugh of scorn. It was his own
reflection! At the end of the saloon, where the craft lay highest on the bar,
one of the mirrored doors, shattered doubtless in careless handling in
process of removal, had been left as useless. In this fragment he had seen
his face for one moment, and then the ripples played over the glass and the
semblance was gone, returning now again. But Floyd-Rosney had no mind
to watch these weird, illusory antics. It was horrible to him to see his face
mirrored anew, distorted in those foul depths where he had been once well
and happy and full of exuberant life and hope, with wife and child and
fortune, every desire of his heart gratified, both hands full and running over.
As he turned away he was surprised to note how the shock had shaken
his composure, his nerves. He was loath to quit his posture against the wall
of the texas that had supported him. His long, intent gaze into the swirl of
the waters had induced a tendency to vertigo, and he looked about for
something that might serve for a seat. The pilot-house was but two or three
steps above, and there were seats built into the wall, he remembered.
He made shift to clamber up the short flight. The door was still on its
hinges, but so defaced and splintered as to be not worth removing, and so
askew as to be difficult to open. With one strong effort, for Floyd-Rosney
was a powerful man, he burst it ajar, although it swung back to its previous
position, implying a like difficulty in opening it again.
He sat down on the farther side, on the bare bench, the upholstery having
disappeared, and waited to regain his composure. Once more he had
recourse to the brandy flask, now nearly empty. Once more the fires
streamed through nerve and fiber, revivifying his every impulse. He felt that
he was himself again, as he gazed through the blank spaces where the glass
was wont to be, at the vast expanse of the great river, now a glittering sheen
under a sudden cast of the sun. Beautiful chromatic suggestions were
mirrored back from the sky; a stretch of illuminated lilac, an ethereal hue
touched the vivid green of the opposite bank. A play of rose and gold was in
the westward ripples, and one bar, athwart the tawny reach, of crude,
intense vermillion betokened a cloud of scarlet, harbinger of sunset in the
offing. He could see the little house on stilts to the left hand, now like a boat
on the water. In the enforced stay here, when aground on the sand-bar, he
had time to familiarize himself with even unvalued elements of the
landscape. To the right was a bayou, the current running with great force
down its broad channel, as wide as an ordinary river, and on the other side
of the bight of the bend, lay the Aglaia. He wondered if the Cherokee Rose
was an object of the scrutiny of the skipper’s binocle. Floyd-Rosney
thought that he should be on the watch for his employer’s return, which was
doubtless the fact, as he had no other duties in hand.
Floyd-Rosney was still eyeing the craft, meditating how best to signal
his wish to be taken back to the Aglaia, when a sudden sound caught his
attention—a sound of swift steps. They came rapidly along the hurricane
deck, where he himself had found footing, mounted the short stair to the
texas, and the next moment the door of the pilot-house was burst ajar and
the face and form of Adrian Ducie appeared at the entrance.
Floyd-Rosney staggered to his feet.
“What does this mean, sir?” he cried, thickly, the veins of his forehead
swollen stiff and blue, his face scarlet, his eyes flashing fire.
The newcomer seemed surprised beyond measure. He stared at Floyd-
Rosney as if doubting his senses and could not collect his thoughts or
summon words until Floyd-Rosney blustered forth:
“Why this intrusion! Leave this place instantly!”
“It is no intrusion, and I will go at my own good pleasure. I came here
thinking to find a man with whom I have business.”
“Well, you have found him. A business that should have been settled
between us long ago!” He advanced a step, and he had his right hand in his
pocket.
“I don’t know what you mean.”
“You’ll find out, as sure as your name is Randal Ducie,” hissed Floyd-
Rosney.
“That’s exactly what it is not. I am Adrian Ducie.”
“You can’t play that game with me. I know your cursed face well
enough. I will mark it now, so that there will never be any more mistakes
between you.”
Adrian had thought he had a pistol, but it was a knife—a large clasp
knife which he had opened with difficulty because of the strength of its
spring as he fumbled with it in his pocket. He thrust violently at Ducie’s
face, who only avoided the blow by suddenly springing aside; the blade
struck the door with such force as to shiver off a fragment of the wood.
Taken at this disadvantage it was impossible for Adrian to retreat in the
precarious footing of the wreck and useless to call for help. He could only
defend himself with his bare hands.
“I call you to observe, Mr. Floyd-Rosney,” he exclaimed, “that I am
unarmed!”
“So much the better!” cried Floyd-Rosney, striking furiously with the
knife at the face he hated with such rancor.
But this time Adrian caught at the other man’s arm to deflect the blow
and there ensued a fierce struggle for the possession of the knife, the only
weapon between them. While Floyd-Rosney was the heavier and the
stronger of the combatants, Adrian was the more active and the quicker of
resource. He had almost wrested the knife from Floyd-Rosney’s grasp; in
seeking to close the blade the sharp edge was brought down on Floyd-
Rosney’s hand, and the blood spurted out. The next moment he had
regained it and he rushed at his adversary’s face—the point held high.
Pushing him back with one hand against his breast Adrian once more
deflected his aim from his eyes and face, but the point struck lower with the
full force of Floyd-Rosney’s terrific lunge, piercing the throat and severing
the jugular vein.
CHAPTER XXV
As his antagonist fell heavily to the floor, the force of the impact shaking
the crazy, ruinous superstructure of the boat with a sinister menace, Floyd-
Rosney’s first emotion was the stirring of the impulse of self-preservation.
Not one moment was wasted in indecision. He stepped deftly across the
prostrate body, wrenched the door open with a violent effort and with
satisfaction heard the dislocated spring slam it noisily behind him. There the
corpse would lie indefinitely, unless, indeed, the man whom Ducie had
professed to seek should come to keep an appointment; probably he had
already been here, and had gone, for the mustering splendors of the evening
sky betokened how the hours wore on to sunset. As Floyd-Rosney took his
way with a swift, sure step to the stair where his boat still struggled at the
end of the painter attached to the post, he noted that Ducie had followed his
example and secured his own skiff in like manner. A sudden monition of
precaution occurred to Floyd-Rosney even in his precipitation, and in
loosing his own craft he set the other adrift, reflecting that to leave it here
was to advertise the presence of its owner aboard the Cherokee Rose; the
current, sweeping as if impelled by some tremendous artificial force as of
steam or electricity, set strongly toward the shore, and the boat, swiftly
gliding on the ripples, would ultimately ground itself on the bank, affording
evidence that Ducie had landed. As without an instant’s hesitation he busied
himself in putting his plan into execution he did not think once of the
powerful lenses of the binocle of the skipper, at watch for his return on the
bow of the beautiful Aglaia, lying there in the bend of the river, not two
miles away, like a swan on the water, between the radiant evening sky, and
the irradiated stream, reflecting her white breast as she floated, a vision
suspended in soft splendors.
He had a momentary doubt of the wisdom of his course, as he took up
his oars, and the possibility of this observation occurred to him. Then he
endeavored to reassure himself. It was the only practicable procedure, he
argued. He took the chance of being unobserved, while otherwise the boat,
swinging at the stairway, would unavoidably excite curiosity and allure
investigation. Still, he would have preferred to have had that possibility in
mind, before taking incriminating action,—to have had his course a matter
of choice instead of making the best of it.
From this moment circumstances seemed contorted and difficult of
adjustment. He had not noticed in his absorption that the cut inflicted upon
him from his own knife was bleeding profusely, and beginning to sting and
smart violently. He must have unwittingly scattered drops of blood all along
the deck and stairs as he came. It was a marvel, he reflected, still optimistic
in instinctive self-defense, that none had fallen on his suit of white flannel.
He held the wounded hand in the water, hoping to stanch the flow, but the
red drops welled forth with an impetuous gush, as of a burst of tears. The
cut was not deep, but it was clear and clean, for the blade had been as sharp
as a razor. With a little time it would dry in the cicatrix and close the
wound. His back toward the Aglaia, he felt sufficiently free of espionage to
tear his linen handkerchief to shreds, using his teeth to start the rent, for
with that hand dripping not only with blood, but with bloodguiltiness, he
dared not search his pockets for his knife. He bound up the wound,
carefully, his plans forming in his mind with all minute detail as he adjusted
the bandages. He would loiter about the river, he said to himself, till the
bleeding ceased, which must be in half an hour’s time, and the hand would
then not be liable to notice. With his splendid physical condition any wound
would be swift in healing. It would be close on nightfall, he meditated, and
this was all the better, for he would board the yacht under cover of the
darkness and give orders to drop down the river to the Gulf, thence to the
open sea—his ultimate destination being some port beyond the reach of
extradition, for he had lately tested his hold on public favor, and was
resolved to risk nothing on its uncertain tenure. He could perfect his plans
when in mid-ocean. Meantime, the present claimed all his faculties.
With the fast plying oars and the strong sweep of the current the skiff
shot along with a speed that suggested a winning shell in a ‘varsity race.
When he approached within ear-shot of the Aglaia he hailed the skipper,
who promptly responded from the deck, and still at a considerable distance,
well in mid-channel, Floyd-Rosney shouted out his intentions to proceed in
the skiff a few miles further, as he wished to investigate the old Duciehurst
mansion, and ordered the Aglaia to drop down at six o’clock and pick him
up there.
As his excitement and the fever of his fury began to subside, the flow of
blood slackened perceptibly. He noticed that the saturated portion of the
bandage was growing stiff and dry; that the blood no longer continued to
spread on the fabric. He would throw it away presently and wash his hands
clear of the traces in the river.
He looked up at the massive walls of Duciehurst with a deep rancor as
he approached the old mansion. The braided currents, making diagonally
across the river, were carrying him toward it as if he were borne thither by
no will of his own, and indeed this was in some sort true.
He loathed to see it again. He wished he had never seen it. Yet in the
same instant he upbraided his attitude of mind as folly. What man of
business instincts, he argued, would revolt against a great and substantial
accession to his fortune, coming to him in regular course of law, because it
was coveted by its former owners, ousted forty years before. He felt hard hit
by untoward fate. All had been against him, from the beginning of this
accursed imbroglio. He had done what he had thought right and proper,—
what any sane and just man would endorse—and he had lost wife, child,
and heavily in estate, and was possibly destined to exile for life,—if—if
that ghastly witness on the stranded steamer should take up its testimony
against him. But no! it was silenced forever! It could not even protect the
man whom Ducie had expected to meet should that unlucky wight persist in
keeping his appointment, finding more than he bargained for, Floyd-Rosney
said grimly.
The boat was running cleverly in to his destination. The landing was
under water already, and the skiff glided over its location with never a sign
suggesting its submergence. The old levee was indicated in barely a long
ripple, washing continually above its summit, and this, too, the skiff
skimmed, undulating merely to the tossing of the waters about the
obstruction. The relative height of the ground on which the deserted
mansion stood alone protected it from inundation, although as yet the
disaster of overflow had nowhere fallen upon the land. But evidently the
water would soon be within the fine old rooms, and Floyd-Rosney, looking
with the eye of a wealthy as well as thrifty proprietor upon the scene, not
only willing but able to protect, felt with a surly sigh of frustration that but
for the impending lawsuit he would have built a stanch levee to reclaim the
old ruin, even though there was a serviceable embankment protecting the
lands in the rear.
The large arrogance of the massive cornice of the main building, the
wide spread of the wings on either side, appealed to his taste of a justified
magnificence. This structure was erected in the days of princelings who had
the opulence to sustain its pretensions, and of his acquaintance he knew no
man but himself who could afford the waste of money on its restoration.
There was something appealing to an esthetic sense in the forwardness of
the neglected vegetation about the glassless goggle-eyed ruin. In the
magnolias on either side of the wings he caught sight of the white glint of
blooms, so early though it was! the pink wands of the almond blossoms
waved here and there in the breeze. The grass of the terraces was freshly
springing. Vines draped the broken pedestals that had once upheld stone
vases, and on the façade of the tall structure the sun crept up and up as
suavely benign, as loath to leave as in the days when its splendors
dominated the Mississippi, the “show place” of all the river.
Floyd-Rosney walked slowly along the broad pavement and up the long
flight of steps to the wide doorless portal. Within shadows lurked, and
memories—how bitter! He hesitated to go in—the influence of the place
was like the thrall of a fate. He wished again he had never seen it. But he
could hear, so definitely the water transmitted the sound, the engines of the
Aglaia getting up steam, and he was conscious of the scrutiny of the
skipper’s powerful lenses.
Through all the vacant vastness swept the fresh breath of the river, so
close at hand. The light from the sinking sun, broadly aslant, fell through
the gaping windows and lay athwart the rooms in immaterial bands of
burnished gold. The illusion of motion was continuous on the grand
staircase where the motes danced in ethereal, hazy illumination. The
contrasting dun-gray shadows imparted a depth and richness to the flare of
ruddy gold, reddening dreamily as the day slowly tended to its close. All
was silence, absolute silence. As he wandered aimlessly from room to
room, his step loud in the quietude, the delicate scent of a white jessamine,
early abloom, bringing its vernal tribute of incense to the forlorn old ruin
year after year, despite half a century of neglect, thrilled his senses and
smote some chord of softer feeling. A sentiment of self-justification rose in
his breast. How was it that all had gone with him so strangely awry!
Wherein had he erred? He had but exerted his prerogative to order the
affairs of his family according to his best judgment in its interest, as any
man might and should do, and—behold, this tumult of tortures was
unloosed upon him. His wife had utilized the opportunity as a pretext to flee
to Randal Ducie, and but for this day’s work the deserted and divorced
would have been fleeced by the courts to finance the new matrimonial
venture. He had done right, he said, thrusting his white cap back from his
heated brow. He had done well.
It had not been his intention to kill an unarmed man; the fatality of the
blow had been an accident, but it was irrevocable, and it behooved him to
look to the future. No one but the skipper of the Aglaia could have known
of his entrance upon the derelict, and if he had chanced to observe it, a word
in his employee’s ear, that he had discovered the body there—murdered
probably—and did not wish to be called as witness would be sufficient for
the present; the skipper would have forgotten the whole incident before he
had entered the first day’s run at sea in the log of the Aglaia. There was no
reason to connect him with the tragedy except that the two were on the river
the same day. He had retracted, and exonerated, and handsomely eaten all
manner of humble pie, and it was to be supposed that relations had been
established as friendly as could exist between rival claimants of an estate
now to be adjudicated by the courts.
He looked down at his hand. The wound that had so perversely bled
showed only pallid lips, but no sign of red. He could not remember if he
had thoroughly wiped the gory knife and began apprehensively to search his
pockets. Not here—not there. He grew ghastly pale. His breath came quick
in suffocating gasps as he realized the truth. He had failed to repossess
himself of the knife at that supreme moment of tragedy. He had an
illuminating recollection, as if he beheld the scene anew, that the blade had
caught on some strong ligament or cartilage in the man’s throat and as the
victim swayed and fell heavily he had not sought to secure it.
“Fool! Fool!” the empty building rang with the sound, and a score of
frantic echoes shouted opprobrium upon him. He clasped his quivering
hands above his head and sought to command his thoughts. He had been too
drunk at the time to realize the fact, but the knife was a witness which
would indubitably fix the crime upon him. Like all his personal accessories
it was the handsomest thing of the kind that could be bought, and on the
silver plate on the handle was engraved, according to his wont, his
monogram. He started violently toward the hall. He must go back,—but he
could never row the distance, exhausted, as he was, against the current. He
would have the Aglaia to steam up on some pretext, and in company with
the skipper they would discover the body, when unperceived he could
repossess himself of the knife. He was terrified at the prospect of the
attempt. He felt himself already in toils. He tossed his hands above his head
and wrung them wildly. A hoarse cry of agony burst from his lips, suddenly
dying in his throat, for—was that an echo in the resounding vacancy? A
strange sound, a great pervasive sound was filling all the air, as if the old
house quavered, and groaned, and cried out in long endured anguish. There
was a rush upon the staircase; he saw through the open doors of the
drawing-rooms shadowy, flitting figures descending in crowds as if the
ancient ghosts that had found harbor here were fleeing their refuge.
Nay, only coils on coils of dust. As he rushed forth into the hall he
perceived at the end of the long perspective the great Mississippi River, as
in some strange dislocation of the angle of vision, reaching—illuminated
and splendid—to the flaunting evening sky.
And from the Mississippi River the lenses of the steam yacht Aglaia,
focused on the old mansion of Duciehurst, saw it at one moment still and
silent, majestic even, in its melancholy ruin, the sun lingering on its massive
cornice and columnated portico. The next it slid as softly from vision as an
immaterial mirage. The caving bank had gone down into the unimaginable
depths of the river, carrying on its floods a thousand acres of disintegrating
land and the turbulent waters of the liberated Mississippi were flowing deep
over the cotton fields of Duciehurst plantation, two miles inland.
In the widespread commotion of the flood it was fortunate for the
Aglaia, even though so far up stream—distant in the bight of the bend—that
steam was already up in the boilers. Forging up the river, against the
current, at her maximum speed, the yacht in the seething turmoil found no
safe anchorage till near the bar where the derelict lay. Here she swung
round and the officers sought to inaugurate measures to recover if it were
possible the body of Floyd-Rosney, who had indubitably perished in the
submergence of the mansion. The whole region was aroused and aghast at
the magnitude of the disaster. From the deck of the yacht were visible
hurrying groups as the population pressed toward the ill-fated scene. The
skipper’s megaphone was in constant requisition as being an eye-witness of
the calamity he alone could give authentic information. Randal Ducie,
hastening down to his levee, was met on the summit by the information that
his ancestral estate had ceased to exist, swept from the face of the earth as
completely as if it had never been. Its restoration had long been the object
nearest his heart, its sequestration in alien possession was the hardship of
his life. But he showed scant emotion. Some subtle, inexplicable
premonition of catastrophe infinitely heart-rending annulled the sense of
loss.
“Where’s my brother?” he demanded irrelevantly, and despite the
remonstrances of the by-standers he threw himself into a skiff at the landing
and pulled out on the tossing, turbulent tide. As the rage of the river
subsided the search was joined by others, and a wild rumor of some disaster
to Adrian Ducie quickly pervaded the vicinity. The finding of his rowboat
on the Arkansas shore did not prove his landing, according to Floyd-
Rosney’s forecast, for the craft was caught in a tangle of saw-grass in a
marshy swamp where footing was impracticable. The old negro to whom
Floyd-Rosney had spoken in the afternoon was now returning from his
errand down the river, which was gray with a slowly gathering mist, and
melancholy with a cast of the silent and pallid moon. He hove near the little
fleet of rowboats that roved the shadows and asked a question concerning
the appearance of the missing man, with whom he thought it possible he
had had some conversation an hour or so ago.
“He looks like me,” said Randal Ducie, throwing his face into high relief
with an electric flashlight, and turning with poignant hope toward the
boatman.
“Oh, no, sah! No, sah!” disconsolately admitted the old darkey, blinking
in the glare. “Nebber saw two folks more onsimilar. Mr. Ran Ducie, I
knowed you, Sah, from way back. Knowed yer daddy. Dis man looked like
he thunk I war de wum o’ de yearth, an’ de yearth war built fur him, though
I never p’sumed ter talk ter him. ’Twar him fust p’sumed ter talk ter me. He
war dressed beautified, too, with white flannel suit, an’ a white cap, an’
handsome ter kill.”
“Floyd-Rosney,” Randal muttered through his set teeth. “And where did
he go?”
“Ter de ole Cher’kee Rose, sah,” the negro pointed at the derelict, lying
on the bar, visible amidst the shadows thronging the river in the ghostly
gleams of the moon that was wont to patrol the deck, and seek out the dark
recesses of the cabin where the rise and subsidence of the water registered
its fluctuations, and to look through the windows of the pilot-house where
the steersman at the wheel once took his bearings.
It was a stupendous moment in a man’s life when Randal Ducie stood in
the shattered old pilot-house and looked down into his own dead face, as it
were, ghastly pale and silent, under the moon’s desolate light. The tie
between the brothers had been more than the love of women, and the heart
of the whole countryside bled for Randal’s grief. The extraordinary
resemblance of the two, their fraternal devotion, their exile from the home
of their fathers, and its wrongful detention in the possession of others, the
destruction of the property by the caving bank, the greatest disaster the
country had known for a half century, when its restoration to its rightful
heirs seemed imminent, all appealed with tender commiseration to the heart
of the world, albeit not easily touched, and a flood of condolence poured in
unregarded upon Randal where he sat in his solitary home with bowed head
and bated pulses, scarcely living himself, admitting no business, seeing no
friend, opening no letter.
The knife that Floyd-Rosney had left piercing the dead man’s throat had
fixed the crime upon him, together with the testimony at the inquest of the
old negro boatman, who had seen him take his way to the derelict, and that
of the skipper who had watched him through the binocle of the Aglaia
descend the steps, unloose both the boats that swung on the tide, secured to
a post, and set one adrift while he rowed the other, the appurtenance of the
Aglaia.
It was well, Randal felt, taking in these proceedings the only interest he
could scourge his mind to entertain, that he was not called upon to
prosecute on circumstantial evidence some forlorn water rat, or some
friendless negro for the millionaire’s crime, as doubtless Floyd-Rosney had
contemplated. Though the death of the gentle and genial Adrian went
unavenged, save by the heavy hand of Heaven itself, it wrought no calamity
to others, except in his incomparable loss.
CHAPTER XXVI
One evening, late in the summer, the melancholy recluse, who might
have forgotten, so seldom did he speak, the sound of his own voice, strolled
out to evade the intensity of the heat in the hope of a breath of air from the
river. But no, it lay like a sheet of glass, blank of incident—no breeze, no
cloud, a pallid monotony of twilight. He had passed through the lawn and
came out upon the levee which in the dead levels of that country seems of
considerable elevation. He loitered along the summit, finding in the higher
ground some amelioration of the motionless atmosphere, for it ceased to
harass him, and with his heavy brooding thoughts for company he walked
on and on, till at length he was aroused by the perception that in his
absorption he had passed the limits of his own domain, and was trespassing
on the precincts of a neighboring plantation. This fact was brought to his
notice by seeing a bench on the levee which he had not caused to be placed
there, and behind it was a mass of Cherokee rose hedge, the growth of
which he did not approve on these protective embankments. On it were
many waxy white blooms, closing with the waning day, amidst the glossy,
deeply green foliage, and seated on the bench was a lady gowned in fleecy
white.
He scarcely gave her a glance, and with a sense of intrusion he gravely
lifted his hat as he was turning away. But she sprang up precipitately and
came toward him.
“Oh, Randal, Randal,” she exclaimed in a voice of poignant sympathy,
and said no more. She had burst into a tempest of sobs and cries, and as he
came toward her and held out his hand, he felt her tears raining down on it
as she pressed it between both her soft palms.
“Oh, I know you don’t—you can’t—care for my sympathy,” Hildegarde
sobbed out brokenly. “It is nothing to you or to him, but Randal, he was not
a man for one friend, one mourner. Everybody loved him that knew him.”
She had collapsed in her former place on the bench, her arm over its
back, her head bent upon it, her slender figure shaken by her sobs.
“But he would care for your sympathy, he would value your tears, shed
for his sake,” Randal said, suddenly. He walked to the bench and sat down
beside her. “Only a few hours before—before—he was speaking to me of
you. How lovely——”
He paused in embarrassment, remembering Adrian’s protest how gladly
he would see his brother make her the chatelaine of Duciehurst,—oh,
dreams, dreams!—all shattered and gone!
“Did he—did he, really?”
She lifted her eyes, swimming with tears and irradiated with smiles, that
seemed to shine in the dull twilight.
“Oh, how I treasure the words!” Then after a long pause—“I was afraid
to speak to you, Randal. I do everything wrong!”
“You? You do everything right,” he declared.
“I am all impulse, you know,” she explained.
“Which is so much better than being all design,” he interpolated.
“And so I speak without consideration, and might—might hurt people’s
feelings.”
“Never—never in the world,” he insisted.
“I am so glad you forgive it, if it is intrusiveness. But I am staying down
here at my aunt’s; she has been very ill. And I have so longed to say just
one word to you—to call you by telephone—or,—something. I would see
your solitary light burning across the lake, so late, so late—you know we
have been watchers here, too,—and I would think of you, shut in with your
sorrow, and no human pity can comfort you. So I could only send my
prayers for you. Did you feel my prayers?”
They were very real to her in her simple faith, very important,
necessarily efficacious.
“No,” he said, honestly. But as her face fell he added: “Perhaps they will
be answered.”
“Oh, assuredly,” she cried, tremulously, and her sincerity touched him.
“Whenever your light shines late from your east window remember that
I am praying that you may have the grace to turn your thoughts joyfully to
the blessed memories you have of your brother, and the happy hours that
were in mercy vouchsafed to you, and what he was to you, and what you
were to him, and what you will be to each other on the day of the great
Reunion. So that you may have strength to take up your duties in life again,
in usefulness and contentment—like the man you were born to be, and the
man you are. Then shall my prayers be answered, and the memory of your
brother will become a blessing, and not a blight.”
There was some responsive chord in that manly heart of his vibrating
strongly to this appeal. Only the next day, struggling with an averse distaste
and wincing from the sights and sounds of the former routine, he went out
to supervise the weighing of the cotton in the fields, now beginning to open
with a fair promise. He felt strangely grateful for the hearty greetings of the
laborers, and an humble appeal to right some little injustice only within his
power made his hands seem strong, and renewed his sense of a duty in the
world.
The next day, collapsing on his resolution, it was difficult to force
himself to take out his fine horse and drive as of yore to the neighboring
town, attending a meeting of the planters of the vicinity, all agog, always,
on the subject of the operations of the levee board.
When Sunday came, with, oh, how faint a spirit, he took his downcast
way to the little neighborhood church, built in a dense grove, full of
shadows and the sentiment of holy peace, called St. John’s in the
Wilderness, and his broken and contrite heart seemed all poignantly
lacerated anew and bleeding, and found no comfort. It had all the agony of
renunciation to think of his brother—his own other self, his twin existence
—as translated to that far, spiritual sphere, which we cannot realize, or
formulate aught of its conditions. His brother, alive, well, strong, loving and
beloved, fighting his way dauntlessly through inadequate resources and
restrictions, making and building of his own inherent values a place for
himself in the world—that vital presence quenched! That loyal, generous,
gentle heart to beat never again. It was a thought to make the senses reel.
He wondered that reason did not fail before its contemplation. He felt his
eyes grow hot and burn in their sockets, and only mechanically and from
force of habit could he follow the service. Once, as his unseeing gaze turned
restlessly from the chancel they fell upon Hildegarde, seated in her uncle’s
pew. Her eyes were downcast, her face was sweetly solemn. A sense of
calm radiated from her expression, her look of aloofness from the world.
There arose in his mind the thought of Adrian’s faith in her genuine graces
of character, which belittled even her charm and beauty, his wish that she
might share the splendor of Ran’s restoration to fortune, when it should
come full-handed to them, that she might grace the high estate of the lady of
Duciehurst—oh, poor Duciehurst! He could but look upon her with
different eyes for the thought. It was as a bond between them.
He had regained his composure, grave and dejected—all unlike his
former self—by the time the sermon was ended, and he waited for her at the
door; together they walked silently to her uncle’s home under the deep rich
shadows of the primeval woods.
Even trifles are of moment in the stagnation of interest in a country
neighborhood. Some vague rumor of the little incident that these two had
been thus seen publicly together penetrated beyond the purview of the
parishioners of St. John’s in the Wilderness. The association of names came
thus to the ears of Paula Floyd-Rosney, and urged her to an action which
she had been contemplating, but had relegated to a future propitious
opportunity. It forced precipitancy upon her. If she intended to move at all
time must be taken into account, and the untoward chance of interference
with her plans. She was now indeed the arbiter of her own destiny, she told
herself. Her suit for divorce had been abated by reason of the death of
Floyd-Rosney, and she was in the enjoyment of one-half of his princely
estate in Mississippi—where the right of dower has been annulled and a
child’s part substituted as the share of the wife—and also the “widow’s
third” in Tennessee, for he had died intestate. She was young, and her spirits
rebounded with the prospect of the rehabilitation of her happiness. Her
heart bore, it is true, some sorry scars which it would carry to the judgment
day. But she could not feel, she could not even feign, grief for her husband’s
fate; she knew it was liberation for her and his child. She had donned, in
deference to the urgency of Mrs. Majoribanks, a fashionable version of
widow’s weeds, and she had intended to allow the traditional time of
mourning to expire before she made haste to gather the treasures of youth
and love that she had so recklessly thrown away. She had not even regret
for the disaster of Duciehurst. She regarded its destruction as the solution of
a problem. She would not have wished to win in the lawsuit the estate she
felt was morally and equitably the property of her former lover. It was
delightful to her to be in the position to bestow, and not to receive. She was
in case to make brave amends for her fickle desertion of Ran Ducie at the
summons of wealth and splendor. She would go back to him a prize beyond
computation—the woman he loved and had always loved, but endowed like
a princess and looking like a queen. The expectation embellished her almost
out of recognition; her closest friends and casual guests—for she had
returned to her own home, from which she had fled—could but exclaim as
her beauty expanded. “How I loved him!” she would whisper to herself, and
sometimes she wondered if those five dread years under the yoke were not
heavy payment for the fortune she was bringing him. The consciousness of
this great wealth made her the more confident, the more plausible in the
letter she wrote him. Though she had feared supplantation, it was only
because he might be in ignorance of her attitude toward him.
It took the form of a letter of condolence. She declared she yearned to
express her deep sympathy for him, although she had felt he might not care
to hear from her on account of her connection with the hand that struck the
blow which had so sorely afflicted him. But she conjured him, by their love
for each other, so precious in the days that were past, to forbear thinking of
her in that wise. The villain who had gone had no hold on her heart. He had
destroyed her life. She could confess to Randal now that every day of the
years and every hour of the days had been one long penance for her
faithless desertion of him, her casting away his precious heart, worth more
than all the gold of Ophir. She had never regretted it but once, and that was
always, and unceasingly. She was possessed, she supposed,—or rather,
consider that she was so young, so unsophisticated, so blinded by the glare
of wealth and dizzy with the specious wiles of the world. Oh, to live the old
days over again! But he must not hate her—he must not associate her with
the name as detestable to her as to him. He must remember, instead, how
sweet was the simple story of their love, and date his thoughts of her from
its emotions. One thing she begged of him—let her hear from him, and
soon.
In all her formulations of the possible result of this letter she never
anticipated the event. She had been prepared for delay. Some little time he
must have to decide upon his course, his phrases, complicated as the whole
incident was with the memory of the murderous Floyd-Rosney. When by
return mail she noted the large white missive, with her name in his well-
remembered, decided, dashing chirography, her heart plunged, and for a
moment she almost thought it had ceased to beat. Her hands trembled
violently as she tore open the envelope. Within was her own letter and on
the reverse side of the last sheet were penned these words:
“This letter should be in your own possession. The story to which you
allude I read to the last page, and the book is closed.”
CHAPTER XXVII
As the months wore on into winter Randal Ducie, in the pursuance of the
effort to rehabilitate his broken and maimed life, was often in Memphis. His
old associates had an eager welcome for him, for his candid and genial
nature was supplemented by a tireless energy and some special acumen and
active experience in the line in which these endowments were now needed.
The levee crisis was acute, and the planters were eager to formulate an
adequate and practical defense against the encroachments of the river, with
State or Federal aid, rather than have the Delta serve, as they claimed, as an
experiment station for the Government. Cotton was their objective,—not
science.
Sometimes a poignant pang smote the heart of the lonely man as some
absorbed and eager acquaintance greeted him, from force of habit, with the
old look of inquiry as to his identity, one of those who used formerly to ask
inadvertently, “Is this you, or your brother?” eliciting in those happy days
the delighted response “Of course, it is my brother.”
Alas, how Randal wished now that it was his brother,—to be himself
lying in that quiet grave to which he was sure their ill-fated resemblance
had consigned Adrian in the flower of his youth, and that it was he who was
here among these streets of busy men with many a long year of life before
him.
“But you should thank God that you are privileged to suffer in his stead,”
Hildegarde would argue with him. “He would have had all this torture to
endure if you had been the one called away.”
Shortly after his arrival in Memphis he had gravitated to her father’s
house, where he often sat for hours in the library in the quiet atmosphere of
the books, her face pensive, illumined by the flash and sparkle of the fire as
she worked with dainty, deft fingers on a bit of embroidery. Informal visits
these, and often other members of the family gathered around the hearth,—
her father, talking levee-board, and the stage of the river, the price of cotton
and the dangers of overproduction; her college-boy brother, a football
expert, a famous halfback with the latest sensations of the gridiron on
Thanksgiving-day; her mother, soft and sweet, with that frank look of
Hildegarde in her duller eyes, for which Randal loved her. He found the
only comfort he knew in this group. Once, however, the young girl’s
unthinking candor almost stunned him.
“Such an odd thing,” she said one day when all were present; she was
evidently coming from far reaches of her reverie; she had been carefully
matching the skeins for the embroidered gentian blooming under the
benison of her touch, and he had a fleeting thought that she might have
rivaled nature had she compared them to the tint of her eyes. “I met Mrs.
Floyd-Rosney yesterday at the Jennison reception, and she asked me such a
strange question.”
She paused, but he would not inquire, and the others, realizing the
malapropos subject, could not sufficiently command their embarrassment.
But the transparent Hildegarde needed no urgency.
“Mrs. Floyd-Rosney asked me,” she said, laying all the skeins together
in her right hand while she looked up with bright interest, “if you had ever
told me of the contents of the letter she wrote to you some months ago.”
“And what did you answer?” asked Randal, breaking the awkward
silence.
“Why, of course I told her that you had never mentioned the letter,”
replied Hildegarde, with a flash of surprise. “I told her the truth.”
“You did! Why, you amaze me!” exclaimed Randal, with a touch of his
old gayety, and with the laugh that rippled around the circle the incident
passed.
Yet this incident put him on his guard. He had long since lost every trace
of the sentiment he had once felt for this woman. From the moment he had
received his rejection, years ago, he had realized that he had been mistaken
from the first in her nature. With many men the contemplation of the
magnitude of the temptation, the splendor of the opportunity as Floyd-
Rosney’s wife, might have served to condone in a degree her defection. Not
so with Randal Ducie. He had a very honest self-respect. He had been
trained at his mother’s knee to reverence the high ideals of life. To him,
Love was a sacred thing, Marriage was the ordinance of God, and a
mercenary motive a profanation. He had been poignantly wounded in the
disappointment, humiliated, in some sort, yet he looked upon the discovery
that she was vulnerable to this specious lure of gain as an escape, and he set
all the strong will of his stanchly endowed nature to recover from the
influence she had exerted in his life. Now, so long afterward, when he had
not only reason to condemn and resent her part in his own past, but to detest
the very sight of her, the sound of the name she bore, he could not imagine
how she could be the victim of the obsession that she was aught to him but
a hateful living lie, a presentment of avarice. He wondered at the persuasion
of a woman, perceived by him only in this instance, but often noticed
elsewhere by the observant in such matters, as to the unlimited power of her
attractions. She can never believe no ember burns amidst the ashes of a
former attachment, dulled by time perhaps, covered from sight, but
smouldering still, and with fresh fuel ready to flame forth anew. He could
not understand on what was based her conviction of the permanence of his
attachment. On her true faith to bind them together till death?—it had been
tested and found wanting. On her gifts of intellect?—the supposition was an
absurdity; she was indubitably a bright and a cultivated woman, but Randal
had been educated too definitely in the masculine American methods to
think of sitting at the feet of any woman. On her beauty?—where was the
traditional delicacy of the feminine perceptions! Did she imagine him a
Turk at heart? Her beauty might attract—it could never hold. In the old days
of his fond affection if she had been visited by some disfiguring, defacing
affliction she would have been the same to him, equally dear, and but that
she herself had stripped off the mask and proclaimed the disguise that had
befooled him she would have been the lady of his heart, the cherished
treasure of his life to the day of his death.
Now he could but wish that she would withhold her withering hand from
such poor values as she and hers had left him in life. He did not understand
her latest demonstration. But for Hildegarde’s pellucid candor he might
never have dreamed of Mrs. Floyd-Rosney’s covert interest in a proposition
made to him by the senior partner of a firm of prominent jewelers, looking
to the purchase of the diamond necklace found among the jewels at
Duciehurst, now lying in a safety deposit vault. Ducie curtly refused to
entertain an offer. Then he as curtly asked:
“But why should you think I would wish to sell it?”
Mr. Dazzle was visibly embarrassed, but still rational.
“The idea was suggested to me, as the stones are of great—well—ahem
—considerable value, and you have no ladies in your family.”
“Not at present,” said Randal, stiffly.
Welcome to our website – the ideal destination for book lovers and
knowledge seekers. With a mission to inspire endlessly, we offer a
vast collection of books, ranging from classic literary works to
specialized publications, self-development books, and children's
literature. Each book is a new journey of discovery, expanding
knowledge and enriching the soul of the reade

Our website is not just a platform for buying books, but a bridge
connecting readers to the timeless values of culture and wisdom. With
an elegant, user-friendly interface and an intelligent search system,
we are committed to providing a quick and convenient shopping
experience. Additionally, our special promotions and home delivery
services ensure that you save time and fully enjoy the joy of reading.

Let us accompany you on the journey of exploring knowledge and


personal growth!

textbookfull.com

You might also like