aboutsummaryrefslogtreecommitdiff
path: root/src/compose/table.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/compose/table.h')
-rw-r--r--src/compose/table.h77
1 files changed, 49 insertions, 28 deletions
diff --git a/src/compose/table.h b/src/compose/table.h
index 05a415f..6be4348 100644
--- a/src/compose/table.h
+++ b/src/compose/table.h
@@ -1,5 +1,5 @@
/*
- * Copyright © 2013 Ran Benita <ran234@gmail.com>
+ * Copyright © 2013,2021 Ran Benita <ran234@gmail.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -29,36 +29,43 @@
#include "context.h"
/*
- * The compose table data structure is a simple trie. An example will
- * help. Given these sequences:
+ * The compose table data structure is a ternary search tree.
*
- * <A> <B> : "first" dead_a
- * <A> <C> <D> : "second" dead_b
- * <E> <F> : "third" dead_c
+ * Reference: https://www.drdobbs.com/database/ternary-search-trees/184410528
+ * Visualization: https://www.cs.usfca.edu/~galles/visualization/TST.html
*
- * the trie would look like:
+ * Short example. Given these sequences:
+ *
+ * <B> <C> : "first" dead_a
+ * <B> <D> <E> : "second" dead_b
+ * <A> <F> : "third" dead_c
+ *
+ * the tree would look like:
+ *
+ * -------- [<B>]---------
+ * | | #
+ * v V
+ * -- [<A>] -- [<C>] --------
+ * # | # | |
+ * v # -- [<D>] --
+ * -- [<F>] -- # | #
+ * # | # v
+ * # -- [<E>] --
+ * # | #
+ * #
*
- * [root] ---> [<A>] -----------------> [<E>] -#
- * | | |
- * # v v
- * [<B>] ---> [<C>] -# [<F>] -#
- * | | -
- * # v #
- * [<D>] -#
- * |
- * #
* where:
- * - [root] is a special empty root node.
* - [<X>] is a node for a sequence keysym <X>.
- * - right arrows are `next` pointers.
- * - down arrows are `successor` pointers.
+ * - right arrows are `hikid` pointers.
+ * - left arrows are `lokid` pointers.
+ * - down arrows are `eqkid` pointers.
* - # is a nil pointer.
*
* The nodes are all kept in a contiguous array. Pointers are represented
* as integer offsets into this array. A nil pointer is represented as 0
- * (which, helpfully, is the offset of the empty root node).
+ * (which, helpfully, is the offset of an empty dummy node).
*
- * Nodes without a successor are leaf nodes. Since a sequence cannot be a
+ * Nodes without an eqkid are leaf nodes. Since a sequence cannot be a
* prefix of another, these are exactly the nodes which terminate the
* sequences (in a bijective manner).
*
@@ -68,21 +75,35 @@
* \0 is so offset 0 points to an empty string).
*/
+/* Fits in uint16_t, also a good idea to have some limit. */
+#define MAX_COMPOSE_NODES 65535
+
struct compose_node {
xkb_keysym_t keysym;
- /* Offset into xkb_compose_table::nodes. */
- unsigned int next:31;
- bool is_leaf:1;
+
+ /* Offset into xkb_compose_table::nodes or 0. */
+ uint16_t lokid;
+ /* Offset into xkb_compose_table::nodes or 0. */
+ uint16_t hikid;
union {
- /* Offset into xkb_compose_table::nodes. */
- uint32_t successor;
+ struct {
+ uint32_t _pad:31;
+ bool is_leaf:1;
+ };
+ struct {
+ uint32_t _pad:31;
+ bool is_leaf:1;
+ /* Offset into xkb_compose_table::nodes or 0. */
+ uint16_t eqkid;
+ } internal;
struct {
/* Offset into xkb_compose_table::utf8. */
- uint32_t utf8;
+ uint32_t utf8:31;
+ bool is_leaf:1;
xkb_keysym_t keysym;
} leaf;
- } u;
+ };
};
struct xkb_compose_table {