Commit Graph

79 Commits

Author SHA1 Message Date
ba647598b4 Use SipHash hash function to mitigate HashDos attempts.
This change attempts to switch to an hash function which mitigates
the effects of the HashDoS attack (denial of service attack trying
to force data structures to worst case behavior) while at the same time
providing Redis with an hash function that does not expect the input
data to be word aligned, a condition no longer true now that sds.c
strings have a varialbe length header.

Note that it is possible sometimes that even using an hash function
for which collisions cannot be generated without knowing the seed,
special implementation details or the exposure of the seed in an
indirect way (for example the ability to add elements to a Set and
check the return in which Redis returns them with SMEMBERS) may
make the attacker's life simpler in the process of trying to guess
the correct seed, however the next step would be to switch to a
log(N) data structure when too many items in a single bucket are
detected: this seems like an overkill in the case of Redis.

SPEED REGRESION TESTS:

In order to verify that switching from MurmurHash to SipHash had
no impact on speed, a set of benchmarks involving fast insertion
of 5 million of keys were performed.

The result shows Redis with SipHash in high pipelining conditions
to be about 4% slower compared to using the previous hash function.
However this could partially be related to the fact that the current
implementation does not attempt to hash whole words at a time but
reads single bytes, in order to have an output which is endian-netural
and at the same time working on systems where unaligned memory accesses
are a problem.

Further X86 specific optimizations should be tested, the function
may easily get at the same level of MurMurHash2 if a few optimizations
are performed.
2017-02-21 17:16:35 +01:00
1ad4883710 active defrag improvements 2017-01-12 09:59:31 +01:00
67def2611f active memory defragmentation 2017-01-12 09:59:30 +01:00
670586715a dict.c: fix dictGenericDelete() return ASAP condition.
Recently we moved the "return ASAP" condition for the Delete() function
from checking .size to checking .used, which is smarter, however while
testing the first table alone always works to ensure the dict is totally
emtpy, when we test the .size field, testing .used requires testing both
T0 and T1, since a rehashing could be in progress.
2016-09-20 17:22:30 +02:00
09a50d34a2 dict.c: dictReplaceRaw() -> dictAddOrFind().
What they say about "naming things" in programming?
2016-09-14 16:43:38 +02:00
a636aeac07 Apply the new dictUnlink() where possible.
Optimizations suggested and originally implemented by @oranagra.
Re-applied by @antirez using the modified API.
2016-09-14 16:37:53 +02:00
afcbcc0e58 dict.c: introduce dictUnlink().
Notes by @antirez:

This patch was picked from a larger commit by Oran and adapted to change
the API a bit. The basic idea is to avoid double lookups when there is
to use the value of the deleted entry.

BEFORE:

    entry = dictFind( ... ); /* 1st lookup. */
    /* Do somethjing with the entry. */
    dictDelete(...);         /* 2nd lookup. */

AFTER:

    entry = dictUnlink( ... ); /* 1st lookup. */
    /* Do somethjing with the entry. */
    dictFreeUnlinkedEntry(entry); /* No lookups!. */
2016-09-14 12:18:59 +02:00
68bf45fa1e Optimize repeated keyname hashing.
(Change cherry-picked and modified by @antirez from a larger commit
provided by @oranagra in PR #3223).
2016-09-12 13:19:05 +02:00
0d179d17ba dict.c benchmark minor improvements. 2016-09-07 15:28:40 +02:00
bd6c4cade6 dict.c benchmark: mixed del/insert benchmark. 2016-09-07 12:34:53 +02:00
0f708ab2a9 dict.c benchmark: finish rehashing before testing lookups. 2016-09-07 11:06:03 +02:00
ed6a4517f5 dict.c benchmark improvements. 2016-09-07 10:53:47 +02:00
1074f73629 dict.c benchmark: take optional count argument. 2016-09-07 10:44:29 +02:00
91a59e03a8 dict.c benchmark. 2016-09-07 10:33:15 +02:00
6ed8c28230 dict.c minor optimization 2016-04-25 16:48:25 +03:00
0c05436cef Lazyfree: a first implementation of non blocking DEL. 2015-10-01 13:00:19 +02:00
0f64080dcb DEBUG HTSTATS <dbid> added.
The command reports information about the hash table internal state
representing the specified database ID.

This can be used in order to investigate rehashings, memory usage issues
and for other debugging purposes.
2015-07-14 17:15:37 +02:00
068d3c9737 dict.c: convert types to unsigned long where appropriate.
No semantical changes since to make dict.c truly able to scale over the
32 bit table size limit, the hash function shoulds and other internals
related to hash function output should be 64 bit ready.
2015-03-27 10:14:52 +01:00
9cd8333ed2 dict.c: add casting to avoid compilation warning.
rehashidx is always positive in the two code paths, since the only
negative value it could have is -1 when there is no rehashing in
progress, and the condition is explicitly checked.
2015-03-27 10:12:25 +01:00
9feee428f2 SPOP: reimplemented for speed and better distribution.
The old version of SPOP with "count" argument used an API call of dict.c
which was actually designed for a different goal, and was not capable of
good distribution. We follow a different three-cases approach optimized
for different ratiion between sets and requested number of elements.

The implementation is simpler and allowed the removal of a large amount
of code.
2015-02-11 10:52:28 +01:00
8ddc14523f dict.c: reset emptylen when bucket is not empty.
Fixed by @oranagra, thank you.
2015-02-11 10:52:27 +01:00
5792a217f8 dict.c: add dictGetSomeKeys(), specialized for eviction. 2015-02-11 10:52:27 +01:00
f25fdd6246 dict.c: avoid code repetition in dictRehash().
Avoid code repetition introduced with PR #2367, also fixes the return
value to always return 0 if there is nothing more to rehash.
2015-02-11 10:52:27 +01:00
2385630d0d dict.c/dictRehash: check again to update 2015-02-11 10:52:26 +01:00
4f427bc298 dict.c: don't try buckets that are empty for sure in dictGetRandomKey().
This is very similar to the optimization applied to dictGetRandomKeys,
but applied to the single key variant.

Related to issue #2306.
2015-02-11 10:52:26 +01:00
1bcf67a75f dict.c: dictGetRandomKeys() optimization for big->small table case.
Related to issue #2306.
2015-02-11 10:52:26 +01:00
88cd9ebc09 dict.c: dictGetRandomKeys() visit pattern optimization.
We use the invariant that the original table ht[0] is never populated up
to the index before the current rehashing index.

Related to issue #2306.
2015-02-11 10:52:26 +01:00
cd0fcf11e7 dict.c: put a bound to max work dictRehash() call can do.
Related to issue #2306.
2015-02-11 10:52:26 +01:00
777020839a dict.c: prevent useless resize to same size.
Related to issue #2306.
2015-02-11 10:52:26 +01:00
170e41464d Less blocking dictGetRandomKeys().
Related to issue #2306.
2015-02-11 10:52:26 +01:00
8aaf5075c5 dict.c: make chaining strategy more clear in dictAddRaw(). 2015-01-23 18:11:05 +01:00
ef5fc599b4 Cleanup wording of dictScan() comment
Some language in the comment was difficult
to understand, so this commit: clarifies wording, removes
unnecessary words, and relocates some dependent clauses
closer to what they actually describe.

I also tried to break up longer chains of thought
(if X, then Y, and Q, and also F, so obviously M)
into more manageable chunks for ease of understanding.
2014-09-29 06:49:08 -04:00
fc8f7ec765 Fix hash table size in comment for dictScan
Closes #1351
2014-09-29 06:49:07 -04:00
91e6b4d74e Fix dictRehash assert casting type.
Also related to #1929.
2014-08-26 10:32:44 +02:00
72aa797c89 Cast to right type in dictNext().
This closes issue #1929, the other part was fixed in the context of issue
2014-08-26 10:26:36 +02:00
18ca831830 Remove unused function
Closes #878
2014-08-18 11:12:26 +02:00
edca2b14d2 Remove warnings and improve integer sign correctness. 2014-08-13 11:44:38 +02:00
5317f5e99a Added dictGetRandomKeys() to dict.c: mass get random entries.
This new function is useful to get a number of random entries from an
hash table when we just need to do some sampling without particularly
good distribution.

It just jumps at a random place of the hash table and returns the first
N items encountered by scanning linearly.

The main usefulness of this function is to speedup Redis internal
sampling of the key space, for example for key eviction or expiry.
2014-03-20 15:50:46 +01:00
c0f8665414 FIXED a typo more thank should be more than 2014-03-04 11:21:34 +08:00
4b9ac6edd0 According to context,the size should be 16 rather than 64 2014-03-04 11:21:34 +08:00
2eb781b35b dict.c: added optional callback to dictEmpty().
Redis hash table implementation has many non-blocking features like
incremental rehashing, however while deleting a large hash table there
was no way to have a callback called to do some incremental work.

This commit adds this support, as an optiona callback argument to
dictEmpty() that is currently called at a fixed interval (one time every
65k deletions).
2013-12-10 18:46:24 +01:00
11e81a1e9a Fixed grammar: before H the article is a, not an. 2013-12-05 16:35:32 +01:00
20fb91fd31 removed not used vars in dictScan(). 2013-11-05 11:56:11 +01:00
dfeaa84d46 dictScan(): empty hash table requires special handling. 2013-10-28 11:17:18 +01:00
7bd45659b9 Fixed typos in dictScan() comment. 2013-10-25 17:05:55 +02:00
34c207227c dictScan() algorithm documented. 2013-10-25 17:01:30 +02:00
b63fbea5e4 Fix error in scan algorithm
The irrelevant bits shouldn't be masked to 1. This can result in slots being
skipped when the hash table is resized between calls to the iterator.
2013-10-25 10:50:03 +02:00
7f490b197f Add SCAN command 2013-10-25 10:49:48 +02:00
1c08302edc dictFingerprint(): cast pointers to integer of same size. 2013-08-20 11:49:55 +02:00
00ddc3500c Revert "Fixed type in dict.c comment: 265 -> 256."
This reverts commit 6253180abd.
2013-08-19 17:25:48 +02:00