summaryrefslogtreecommitdiffstats
path: root/include/haproxy/stick_table.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/haproxy/stick_table.h')
-rw-r--r--include/haproxy/stick_table.h63
1 files changed, 61 insertions, 2 deletions
diff --git a/include/haproxy/stick_table.h b/include/haproxy/stick_table.h
index 3200437..2c5e7a2 100644
--- a/include/haproxy/stick_table.h
+++ b/include/haproxy/stick_table.h
@@ -29,7 +29,9 @@
#include <haproxy/freq_ctr.h>
#include <haproxy/sample-t.h>
#include <haproxy/stick_table-t.h>
+#include <haproxy/thread.h>
#include <haproxy/ticks.h>
+#include <haproxy/xxhash.h>
extern struct stktable *stktables_list;
extern struct pool_head *pool_head_stk_ctr;
@@ -191,6 +193,19 @@ static inline void *stktable_data_ptr_idx(struct stktable *t, struct stksess *ts
return __stktable_data_ptr(t, ts, type) + idx*stktable_type_size(stktable_data_types[type].std_type);
}
+/* return a shard number for key <key> of len <len> present in table <t>, for
+ * use with the tree indexing. The value will be from 0 to
+ * CONFIG_HAP_TBL_BUCKETS-1.
+ */
+static inline uint stktable_calc_shard_num(const struct stktable *t, const void *key, size_t len)
+{
+#if CONFIG_HAP_TBL_BUCKETS > 1
+ return XXH32(key, len, t->hash_seed) % CONFIG_HAP_TBL_BUCKETS;
+#else
+ return 0;
+#endif
+}
+
/* kill an entry if it's expired and its ref_cnt is zero */
static inline int __stksess_kill_if_expired(struct stktable *t, struct stksess *ts)
{
@@ -202,14 +217,26 @@ static inline int __stksess_kill_if_expired(struct stktable *t, struct stksess *
static inline void stksess_kill_if_expired(struct stktable *t, struct stksess *ts, int decrefcnt)
{
+ uint shard;
+ size_t len;
if (decrefcnt && HA_ATOMIC_SUB_FETCH(&ts->ref_cnt, 1) != 0)
return;
if (t->expire != TICK_ETERNITY && tick_is_expired(ts->expire, now_ms)) {
- HA_RWLOCK_WRLOCK(STK_TABLE_LOCK, &t->lock);
+ if (t->type == SMP_T_STR)
+ len = strlen((const char *)ts->key.key);
+ else
+ len = t->key_size;
+
+ shard = stktable_calc_shard_num(t, ts->key.key, len);
+
+ /* make the compiler happy when shard is not used without threads */
+ ALREADY_CHECKED(shard);
+
+ HA_RWLOCK_WRLOCK(STK_TABLE_LOCK, &t->shards[shard].sh_lock);
__stksess_kill_if_expired(t, ts);
- HA_RWLOCK_WRUNLOCK(STK_TABLE_LOCK, &t->lock);
+ HA_RWLOCK_WRUNLOCK(STK_TABLE_LOCK, &t->shards[shard].sh_lock);
}
}
@@ -401,4 +428,36 @@ static inline int stkctr_inc_bytes_out_ctr(struct stkctr *stkctr, unsigned long
return 1;
}
+/* Add <inc> to the number of cumulated front glitches in the tracked counter
+ * <stkctr>. It returns 0 if the entry pointer does not exist and nothing is
+ * performed. Otherwise it returns 1.
+ */
+static inline int stkctr_add_glitch_ctr(struct stkctr *stkctr, uint inc)
+{
+ struct stksess *ts;
+ void *ptr1, *ptr2;
+
+ ts = stkctr_entry(stkctr);
+ if (!ts)
+ return 0;
+
+ HA_RWLOCK_WRLOCK(STK_SESS_LOCK, &ts->lock);
+
+ ptr1 = stktable_data_ptr(stkctr->table, ts, STKTABLE_DT_GLITCH_CNT);
+ if (ptr1)
+ stktable_data_cast(ptr1, std_t_uint) += inc;
+
+ ptr2 = stktable_data_ptr(stkctr->table, ts, STKTABLE_DT_GLITCH_RATE);
+ if (ptr2)
+ update_freq_ctr_period(&stktable_data_cast(ptr2, std_t_frqp),
+ stkctr->table->data_arg[STKTABLE_DT_GLITCH_RATE].u, inc);
+
+ HA_RWLOCK_WRUNLOCK(STK_SESS_LOCK, &ts->lock);
+
+ /* If data was modified, we need to touch to re-schedule sync */
+ if (ptr1 || ptr2)
+ stktable_touch_local(stkctr->table, ts, 0);
+ return 1;
+}
+
#endif /* _HAPROXY_STICK_TABLE_H */