* Resize the hash table. We try to maintain the number of buckets * such that the load factor is in the range 0.25 to 1.0. * * If we can't get the new memory then we silently fail. This is OK * because things will still work and we'll try again soon anyway. */
| 934 | * because things will still work and we'll try again soon anyway. |
| 935 | */ |
| 936 | static void |
| 937 | ng_bridge_rehash(priv_p priv) |
| 938 | { |
| 939 | struct ng_bridge_bucket *newTab; |
| 940 | int oldBucket, newBucket; |
| 941 | int newNumBuckets; |
| 942 | u_int newMask; |
| 943 | |
| 944 | /* Is table too full or too empty? */ |
| 945 | if (priv->numHosts > priv->numBuckets |
| 946 | && (priv->numBuckets << 1) <= MAX_BUCKETS) |
| 947 | newNumBuckets = priv->numBuckets << 1; |
| 948 | else if (priv->numHosts < (priv->numBuckets >> 2) |
| 949 | && (priv->numBuckets >> 2) >= MIN_BUCKETS) |
| 950 | newNumBuckets = priv->numBuckets >> 2; |
| 951 | else |
| 952 | return; |
| 953 | newMask = newNumBuckets - 1; |
| 954 | |
| 955 | /* Allocate and initialize new table */ |
| 956 | newTab = malloc(newNumBuckets * sizeof(*newTab), |
| 957 | M_NETGRAPH_BRIDGE, M_NOWAIT | M_ZERO); |
| 958 | if (newTab == NULL) |
| 959 | return; |
| 960 | |
| 961 | /* Move all entries from old table to new table */ |
| 962 | for (oldBucket = 0; oldBucket < priv->numBuckets; oldBucket++) { |
| 963 | struct ng_bridge_bucket *const oldList = &priv->tab[oldBucket]; |
| 964 | |
| 965 | while (!SLIST_EMPTY(oldList)) { |
| 966 | struct ng_bridge_hent *const hent |
| 967 | = SLIST_FIRST(oldList); |
| 968 | |
| 969 | SLIST_REMOVE_HEAD(oldList, next); |
| 970 | newBucket = HASH(hent->host.addr, newMask); |
| 971 | SLIST_INSERT_HEAD(&newTab[newBucket], hent, next); |
| 972 | } |
| 973 | } |
| 974 | |
| 975 | /* Replace old table with new one */ |
| 976 | if (priv->conf.debugLevel >= 3) { |
| 977 | log(LOG_INFO, "ng_bridge: %s: table size %d -> %d\n", |
| 978 | ng_bridge_nodename(priv->node), |
| 979 | priv->numBuckets, newNumBuckets); |
| 980 | } |
| 981 | free(priv->tab, M_NETGRAPH_BRIDGE); |
| 982 | priv->numBuckets = newNumBuckets; |
| 983 | priv->hashMask = newMask; |
| 984 | priv->tab = newTab; |
| 985 | return; |
| 986 | } |
| 987 | |
| 988 | /****************************************************************** |
| 989 | MISC FUNCTIONS |
no test coverage detected