patch 9.1.0256: Finding autocmd events is inefficient

Problem:  Finding autocmd events is inefficient
Solution: Use binary search to find events, cache last found events,
          avoid use of strlen(), add SessionWritePost autocmd,
          fix test_codestyle and avoid endless loop
          (John Marriott)

closes: #14287

Signed-off-by: John Marriott <basilisk@internode.on.net>
Signed-off-by: Christian Brabandt <cb@256bit.org>
diff --git a/src/misc2.c b/src/misc2.c
index 6df0d39..c07ed80 100644
--- a/src/misc2.c
+++ b/src/misc2.c
@@ -3069,3 +3069,45 @@
     return 0;
 #endif
 }
+
+// compare two keyvalue_T structs by case sensitive value
+    int
+cmp_keyvalue_value(const void *a, const void *b)
+{
+    keyvalue_T *kv1 = (keyvalue_T *)a;
+    keyvalue_T *kv2 = (keyvalue_T *)b;
+
+    return STRCMP(kv1->value, kv2->value);
+}
+
+// compare two keyvalue_T structs by value with length
+    int
+cmp_keyvalue_value_n(const void *a, const void *b)
+{
+    keyvalue_T *kv1 = (keyvalue_T *)a;
+    keyvalue_T *kv2 = (keyvalue_T *)b;
+
+    return STRNCMP(kv1->value, kv2->value, MAX(kv1->length, kv2->length));
+}
+
+// compare two keyvalue_T structs by case insensitive value
+    int
+cmp_keyvalue_value_i(const void *a, const void *b)
+{
+    keyvalue_T *kv1 = (keyvalue_T *)a;
+    keyvalue_T *kv2 = (keyvalue_T *)b;
+
+    return STRICMP(kv1->value, kv2->value);
+}
+
+// compare two keyvalue_T structs by case insensitive value
+// with length
+    int
+cmp_keyvalue_value_ni(const void *a, const void *b)
+{
+    keyvalue_T *kv1 = (keyvalue_T *)a;
+    keyvalue_T *kv2 = (keyvalue_T *)b;
+
+    return STRNICMP(kv1->value, kv2->value, MAX(kv1->length, kv2->length));
+}
+