Overview
This article is based on the premise that data is volatile while logic is stable. The implementations shown are mostly code snippets, but that does not affect the completeness of the descriptions. Although the examples use the C language, the programming ideas are applicable to other languages. This article does not discuss language-specific runtime performance.
1 Concepts
The table-driven approach simply means obtaining data by table lookup. The "table" is usually an array and can be seen as a form of database. Looking up an unfamiliar Chinese character by its radical in a dictionary is a typical table-driven method: determine an index from the character glyph and map it to the correct page. Compared with scanning pages sequentially, radical lookup is much more efficient.
In programming, when data volume is small you can use conditional statements (if...else or switch...case) to obtain values. As data grows, those conditional chains become lengthy and the advantages of a table-driven approach emerge.
When using table-driven techniques, pay attention to two questions: how to perform the lookup to read the correct data, and what to store in the table (values or function pointers).
Common lookup methods include direct lookup, indexed lookup, and segmented lookup.
1.1.1 Direct lookup
Access data directly via an array index. This is essentially direct access as in a hash table.
1.1.2 Indexed lookup
If a single key conversion does not suffice to transform data (for example, words) into an index, use a separate index table that maps conversions to indices.
1.1.3 Segmented lookup
Determine the category (index) by identifying the range that contains the data. Some data naturally fall into intervals, such as grading scales.
1.2 Practical examples
Most examples in this section are taken from real projects. Tables can be one-dimensional arrays, two-dimensional arrays, or arrays of structs; table contents may be numeric values, strings, or function pointers. The table-driven idea allows many combinations of table forms and contents.
1.2.1 Character frequency
Problem: Count how many times each digit appears in a user input string of digits.
1.2.2 Month-days validation
Problem: Validate the number of days for a given year and month (distinguish between common years and leap years).
1.2.3 Name construction
Problem: Construct a service-type name string based on a bitmap of services carried by a WAN interface.
1.2.4 Value-to-name mapping
Problem: Output a string corresponding to an enum variable value, for example mapping PORT_FE (1) to "Fe".
1.2.5 Value mapping between modules
Problem: Adapt differing enum value semantics for the same parameter across modules.
1.2.6 Version control
Problem: Manage version negotiation between OLT and ONU.
1.2.7 Message handling
Problem: Call appropriate print functions based on different print commands from a terminal to control different print levels.