mirror_frr/lib/hash.h
Donald Sharp 8b2a6222e8 lib: Remove expansion of hash table
The hash code has the idea of stopping expanding
the hash table when certain criteria are set.
With the recent addition of `show hashtable`
we can now see that when we have a full internet
feed we've stopped expanding the table at 1k
buckets.  This results in some serious performance
issues at scale.

Since we now have the ability to see the statistics
on a hash table, let's allow it to expand.  Doing
so on a full feed showed this:

before:
   Hash table          |  Buckets   Entries   Empty   LF        SD      FLF       SD
 ----------------------+----------------------------------------------------------------
   route table hash    |  1024      1187579   0%      1159.75   34.06   1159.75   35.08
   route table hash    |  32768     76208     10%     2.33      2.80    2.58      4.03
   route table hash    |  1024      1187572   0%      1159.74   34.06   1159.74   35.08
   route table hash    |  2048      76205     0%      37.21     6.13    37.21     7.29

Showing hash table statistics for BGP
-------------------------------------

   Hash table         |  Buckets   Entries   Empty   LF       SD      FLF      SD
 ---------------------+--------------------------------------------------------------
   BGP Attributes     |  131072    251229    15%     1.92     2.48    2.25     3.33
   route table hash   |  4096      1187572   0%      289.93   17.03   289.93   17.87
   route table hash   |  32768     76205     10%     2.33     2.90    2.58     4.21

After:

   Hash table          |  Buckets   Entries   Empty   LF     SD     FLF    SD
 ----------------------+--------------------------------------------------------
   route table hash    |  1048576   1187349   32%     1.13   2.57   1.67   3.16
   route table hash    |  32768     76195     10%     2.33   2.81   2.58   4.03
   route table hash    |  1048576   1187342   32%     1.13   2.58   1.67   3.16
   route table hash    |  32768     76192     10%     2.33   2.68   2.58   3.81

Showing hash table statistics for BGP
-------------------------------------

   Hash table         |  Buckets   Entries   Empty   LF     SD     FLF    SD
 ---------------------+--------------------------------------------------------
   BGP Attributes     |  131072    251222    15%     1.92   2.64   2.25   3.58
   route table hash   |  1048576   1187342   32%     1.13   2.52   1.67   3.07
   route table hash   |  32768     76192     10%     2.33   2.86   2.58   4.12

We should see some significant performance improvements across the board
for full feeds.

Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
2017-07-27 11:08:40 -04:00

110 lines
2.8 KiB
C

/* Hash routine.
* Copyright (C) 1998 Kunihiro Ishiguro
*
* This file is part of GNU Zebra.
*
* GNU Zebra is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published
* by the Free Software Foundation; either version 2, or (at your
* option) any later version.
*
* GNU Zebra is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; see the file COPYING; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef _ZEBRA_HASH_H
#define _ZEBRA_HASH_H
#include "memory.h"
#include "frratomic.h"
DECLARE_MTYPE(HASH)
DECLARE_MTYPE(HASH_BACKET)
/* Default hash table size. */
#define HASH_INITIAL_SIZE 256 /* initial number of backets. */
#define HASH_THRESHOLD 10 /* expand when backet. */
#define HASHWALK_CONTINUE 0
#define HASHWALK_ABORT -1
struct hash_backet {
/* if this backet is the head of the linked listed, len denotes the
* number of
* elements in the list */
int len;
/* Linked list. */
struct hash_backet *next;
/* Hash key. */
unsigned int key;
/* Data. */
void *data;
};
struct hashstats {
/* number of empty hash buckets */
_Atomic uint_fast32_t empty;
/* sum of squares of bucket length */
_Atomic uint_fast32_t ssq;
};
struct hash {
/* Hash backet. */
struct hash_backet **index;
/* Hash table size. Must be power of 2 */
unsigned int size;
/* Key make function. */
unsigned int (*hash_key)(void *);
/* Data compare function. */
int (*hash_cmp)(const void *, const void *);
/* Backet alloc. */
unsigned long count;
struct hashstats stats;
/* hash name */
char *name;
};
#define hashcount(X) ((X)->count)
extern struct hash *hash_create(unsigned int (*)(void *),
int (*)(const void *, const void *),
const char *);
extern struct hash *hash_create_size(unsigned int, unsigned int (*)(void *),
int (*)(const void *, const void *),
const char *);
extern void *hash_get(struct hash *, void *, void *(*)(void *));
extern void *hash_alloc_intern(void *);
extern void *hash_lookup(struct hash *, void *);
extern void *hash_release(struct hash *, void *);
extern void hash_iterate(struct hash *, void (*)(struct hash_backet *, void *),
void *);
extern void hash_walk(struct hash *, int (*)(struct hash_backet *, void *),
void *);
extern void hash_clean(struct hash *, void (*)(void *));
extern void hash_free(struct hash *);
extern unsigned int string_hash_make(const char *);
extern void hash_cmd_init(void);
#endif /* _ZEBRA_HASH_H */