CLEANUP: session: use an array for the stick counters

The stick counters were in two distinct sets of struct members,
causing some code to be duplicated. Now we use an array, which
enables some processing to be performed in loops. This allowed
the code to be shrunk by 700 bytes.
diff --git a/include/proto/session.h b/include/proto/session.h
index 3a1c985..3b6e1fc 100644
--- a/include/proto/session.h
+++ b/include/proto/session.h
@@ -57,23 +57,17 @@
 static inline void session_store_counters(struct session *s)
 {
 	void *ptr;
+	int i;
 
-	if (s->stkctr2_entry) {
-		ptr = stktable_data_ptr(s->stkctr2_table, s->stkctr2_entry, STKTABLE_DT_CONN_CUR);
+	for (i = 0; i < sizeof(s->stkctr) / sizeof(s->stkctr[0]); i++) {
+		if (!s->stkctr[i].entry)
+			continue;
+		ptr = stktable_data_ptr(s->stkctr[i].table, s->stkctr[i].entry, STKTABLE_DT_CONN_CUR);
 		if (ptr)
 			stktable_data_cast(ptr, conn_cur)--;
-		s->stkctr2_entry->ref_cnt--;
-		stksess_kill_if_expired(s->stkctr2_table, s->stkctr2_entry);
-		s->stkctr2_entry = NULL;
-	}
-
-	if (s->stkctr1_entry) {
-		ptr = stktable_data_ptr(s->stkctr1_table, s->stkctr1_entry, STKTABLE_DT_CONN_CUR);
-		if (ptr)
-			stktable_data_cast(ptr, conn_cur)--;
-		s->stkctr1_entry->ref_cnt--;
-		stksess_kill_if_expired(s->stkctr1_table, s->stkctr1_entry);
-		s->stkctr1_entry = NULL;
+		s->stkctr[i].entry->ref_cnt--;
+		stksess_kill_if_expired(s->stkctr[i].table, s->stkctr[i].entry);
+		s->stkctr[i].entry = NULL;
 	}
 }
 
@@ -84,26 +78,27 @@
 static inline void session_stop_backend_counters(struct session *s)
 {
 	void *ptr;
+	int i;
 
 	if (!(s->flags & (SN_BE_TRACK_SC1|SN_BE_TRACK_SC2)))
 		return;
 
-	if ((s->flags & SN_BE_TRACK_SC1) && s->stkctr1_entry) {
-		ptr = stktable_data_ptr(s->stkctr1_table, s->stkctr1_entry, STKTABLE_DT_CONN_CUR);
-		if (ptr)
-			stktable_data_cast(ptr, conn_cur)--;
-		s->stkctr1_entry->ref_cnt--;
-		stksess_kill_if_expired(s->stkctr1_table, s->stkctr1_entry);
-		s->stkctr1_entry = NULL;
-	}
+	for (i = 0; i < sizeof(s->stkctr) / sizeof(s->stkctr[0]); i++) {
+		if (!s->stkctr[i].entry)
+			continue;
 
-	if ((s->flags & SN_BE_TRACK_SC2) && s->stkctr2_entry) {
-		ptr = stktable_data_ptr(s->stkctr2_table, s->stkctr2_entry, STKTABLE_DT_CONN_CUR);
+		if ((i == 0) && !(s->flags & SN_BE_TRACK_SC1))
+			continue;
+
+		if ((i == 1) && !(s->flags & SN_BE_TRACK_SC2))
+			continue;
+
+		ptr = stktable_data_ptr(s->stkctr[i].table, s->stkctr[i].entry, STKTABLE_DT_CONN_CUR);
 		if (ptr)
 			stktable_data_cast(ptr, conn_cur)--;
-		s->stkctr2_entry->ref_cnt--;
-		stksess_kill_if_expired(s->stkctr2_table, s->stkctr2_entry);
-		s->stkctr2_entry = NULL;
+		s->stkctr[i].entry->ref_cnt--;
+		stksess_kill_if_expired(s->stkctr[i].table, s->stkctr[i].entry);
+		s->stkctr[i].entry = NULL;
 	}
 	s->flags &= ~(SN_BE_TRACK_SC1|SN_BE_TRACK_SC2);
 }
@@ -132,33 +127,18 @@
 		ts->expire = tick_add(now_ms, MS_TO_TICKS(t->expire));
 }
 
-/* Enable tracking of session counters as stkctr1 on stksess <ts>. The caller is
- * responsible for ensuring that <t> and <ts> are valid pointers. Some controls
- * are performed to ensure the state can still change.
- */
-static inline void session_track_stkctr1(struct session *s, struct stktable *t, struct stksess *ts)
-{
-	if (s->stkctr1_entry)
-		return;
-
-	ts->ref_cnt++;
-	s->stkctr1_table = t;
-	s->stkctr1_entry = ts;
-	session_start_counters(t, ts);
-}
-
-/* Enable tracking of session counters as stkctr1 on stksess <ts>. The caller is
+/* Enable tracking of session counters as <stkctr> on stksess <ts>. The caller is
  * responsible for ensuring that <t> and <ts> are valid pointers. Some controls
  * are performed to ensure the state can still change.
  */
-static inline void session_track_stkctr2(struct session *s, struct stktable *t, struct stksess *ts)
+static inline void session_track_stkctr(struct stkctr *ctr, struct stktable *t, struct stksess *ts)
 {
-	if (s->stkctr2_entry)
+	if (ctr->entry)
 		return;
 
 	ts->ref_cnt++;
-	s->stkctr2_table = t;
-	s->stkctr2_entry = ts;
+	ctr->table = t;
+	ctr->entry = ts;
 	session_start_counters(t, ts);
 }
 
@@ -166,27 +146,20 @@
 static void inline session_inc_http_req_ctr(struct session *s)
 {
 	void *ptr;
+	int i;
 
-	if (s->stkctr2_entry) {
-		ptr = stktable_data_ptr(s->stkctr2_table, s->stkctr2_entry, STKTABLE_DT_HTTP_REQ_CNT);
-		if (ptr)
-			stktable_data_cast(ptr, http_req_cnt)++;
+	for (i = 0; i < sizeof(s->stkctr) / sizeof(s->stkctr[0]); i++) {
+		if (!s->stkctr[i].entry)
+			continue;
 
-		ptr = stktable_data_ptr(s->stkctr2_table, s->stkctr2_entry, STKTABLE_DT_HTTP_REQ_RATE);
-		if (ptr)
-			update_freq_ctr_period(&stktable_data_cast(ptr, http_req_rate),
-					       s->stkctr2_table->data_arg[STKTABLE_DT_HTTP_REQ_RATE].u, 1);
-	}
-
-	if (s->stkctr1_entry) {
-		ptr = stktable_data_ptr(s->stkctr1_table, s->stkctr1_entry, STKTABLE_DT_HTTP_REQ_CNT);
+		ptr = stktable_data_ptr(s->stkctr[i].table, s->stkctr[i].entry, STKTABLE_DT_HTTP_REQ_CNT);
 		if (ptr)
 			stktable_data_cast(ptr, http_req_cnt)++;
 
-		ptr = stktable_data_ptr(s->stkctr1_table, s->stkctr1_entry, STKTABLE_DT_HTTP_REQ_RATE);
+		ptr = stktable_data_ptr(s->stkctr[i].table, s->stkctr[i].entry, STKTABLE_DT_HTTP_REQ_RATE);
 		if (ptr)
 			update_freq_ctr_period(&stktable_data_cast(ptr, http_req_rate),
-					       s->stkctr1_table->data_arg[STKTABLE_DT_HTTP_REQ_RATE].u, 1);
+					       s->stkctr[i].table->data_arg[STKTABLE_DT_HTTP_REQ_RATE].u, 1);
 	}
 }
 
@@ -194,30 +167,29 @@
 static void inline session_inc_be_http_req_ctr(struct session *s)
 {
 	void *ptr;
+	int i;
 
 	if (likely(!(s->flags & (SN_BE_TRACK_SC1|SN_BE_TRACK_SC2))))
 		return;
 
-	if ((s->flags & SN_BE_TRACK_SC2) && s->stkctr2_entry) {
-		ptr = stktable_data_ptr(s->stkctr2_table, s->stkctr2_entry, STKTABLE_DT_HTTP_REQ_CNT);
-		if (ptr)
-			stktable_data_cast(ptr, http_req_cnt)++;
+	for (i = 0; i < sizeof(s->stkctr) / sizeof(s->stkctr[0]); i++) {
+		if (!s->stkctr[i].entry)
+			continue;
 
-		ptr = stktable_data_ptr(s->stkctr2_table, s->stkctr2_entry, STKTABLE_DT_HTTP_REQ_RATE);
-		if (ptr)
-			update_freq_ctr_period(&stktable_data_cast(ptr, http_req_rate),
-					       s->stkctr2_table->data_arg[STKTABLE_DT_HTTP_REQ_RATE].u, 1);
-	}
+		if ((i == 0) && !(s->flags & SN_BE_TRACK_SC1))
+			continue;
 
-	if ((s->flags & SN_BE_TRACK_SC1) && s->stkctr1_entry) {
-		ptr = stktable_data_ptr(s->stkctr1_table, s->stkctr1_entry, STKTABLE_DT_HTTP_REQ_CNT);
+		if ((i == 1) && !(s->flags & SN_BE_TRACK_SC2))
+			continue;
+
+		ptr = stktable_data_ptr(s->stkctr[i].table, s->stkctr[i].entry, STKTABLE_DT_HTTP_REQ_CNT);
 		if (ptr)
 			stktable_data_cast(ptr, http_req_cnt)++;
 
-		ptr = stktable_data_ptr(s->stkctr1_table, s->stkctr1_entry, STKTABLE_DT_HTTP_REQ_RATE);
+		ptr = stktable_data_ptr(s->stkctr[i].table, s->stkctr[i].entry, STKTABLE_DT_HTTP_REQ_RATE);
 		if (ptr)
 			update_freq_ctr_period(&stktable_data_cast(ptr, http_req_rate),
-					       s->stkctr1_table->data_arg[STKTABLE_DT_HTTP_REQ_RATE].u, 1);
+			                       s->stkctr[i].table->data_arg[STKTABLE_DT_HTTP_REQ_RATE].u, 1);
 	}
 }
 
@@ -230,27 +202,20 @@
 static void inline session_inc_http_err_ctr(struct session *s)
 {
 	void *ptr;
+	int i;
 
-	if (s->stkctr2_entry) {
-		ptr = stktable_data_ptr(s->stkctr2_table, s->stkctr2_entry, STKTABLE_DT_HTTP_ERR_CNT);
-		if (ptr)
-			stktable_data_cast(ptr, http_err_cnt)++;
+	for (i = 0; i < sizeof(s->stkctr) / sizeof(s->stkctr[0]); i++) {
+		if (!s->stkctr[i].entry)
+			continue;
 
-		ptr = stktable_data_ptr(s->stkctr2_table, s->stkctr2_entry, STKTABLE_DT_HTTP_ERR_RATE);
-		if (ptr)
-			update_freq_ctr_period(&stktable_data_cast(ptr, http_err_rate),
-					       s->stkctr2_table->data_arg[STKTABLE_DT_HTTP_ERR_RATE].u, 1);
-	}
-
-	if (s->stkctr1_entry) {
-		ptr = stktable_data_ptr(s->stkctr1_table, s->stkctr1_entry, STKTABLE_DT_HTTP_ERR_CNT);
+		ptr = stktable_data_ptr(s->stkctr[i].table, s->stkctr[i].entry, STKTABLE_DT_HTTP_ERR_CNT);
 		if (ptr)
 			stktable_data_cast(ptr, http_err_cnt)++;
 
-		ptr = stktable_data_ptr(s->stkctr1_table, s->stkctr1_entry, STKTABLE_DT_HTTP_ERR_RATE);
+		ptr = stktable_data_ptr(s->stkctr[i].table, s->stkctr[i].entry, STKTABLE_DT_HTTP_ERR_RATE);
 		if (ptr)
 			update_freq_ctr_period(&stktable_data_cast(ptr, http_err_rate),
-					       s->stkctr1_table->data_arg[STKTABLE_DT_HTTP_ERR_RATE].u, 1);
+			                       s->stkctr[i].table->data_arg[STKTABLE_DT_HTTP_ERR_RATE].u, 1);
 	}
 }
 
diff --git a/include/types/session.h b/include/types/session.h
index 4688dbf..7b52182 100644
--- a/include/types/session.h
+++ b/include/types/session.h
@@ -96,6 +96,12 @@
  * and freed in session_free() !
  */
 
+/* stick counter */
+struct stkctr {
+	struct stksess *entry;          /* entry containing counters currently being tracked  by this session */
+	struct stktable *table;         /* table the counters above belong to (undefined if counters are null) */
+};
+
 /*
  * Note: some session flags have dependencies :
  *  - SN_DIRECT cannot exist without SN_ASSIGNED, because a server is
@@ -135,10 +141,7 @@
 	} store[8];				/* tracked stickiness values to store */
 	int store_count;
 
-	struct stksess *stkctr1_entry;          /* entry containing counters currently being tracked as set 1 by this session */
-	struct stktable *stkctr1_table;         /* table the counters above belong to (undefined if counters are null) */
-	struct stksess *stkctr2_entry;          /* entry containing counters currently being tracked as set 2 by this session */
-	struct stktable *stkctr2_table;         /* table the counters above belong to (undefined if counters are null) */
+	struct stkctr stkctr[2];                /* stick counters */
 
 	struct stream_interface si[2];          /* client and server stream interfaces */
 	struct {