• Keine Ergebnisse gefunden

3.2 Existing Approaches to Longest Prefix Matching

3.2.1 Trie-Based Schemes

The classical solutions for longest prefix matching have been tries. The fol-lowing sections explain the evolution of this scheme.

Binary Trie

The binary trie represents the simplest species in this tree-like family. The name is apparently based on “retrieval” [Bri59, Fre60]. Unlike trees, branch-ing in tries is not based on a ordered comparison with the key stored in the node. Instead, bits are extracted sequentially from the search key and used to index into a pointer table, going left or right. A simple binary trie is shown in Figure 3.1. The grey nodes are terminal nodes, i.e., nodes that do contain more information on what to do if the search terminates there. White nodes only guide the search process. Assume searching for the bit sequence 011.

First, the most significant bit (0) is extracted and used to decide which way to branch from the root to the gray node directly below it to the left. This gray node is remembered as our current longest match, in case nothing better will be found. Then, the next bit (the middle1) is extracted from the search string and branched along the path labeled “1” to its white right child node. The third bit, another1, cannot be used, since there is no link labeled “1” from that node. Thus, the remembered gray node is the best match.

0 1

0 0

0

1 1

1 Root

Figure 3.1: Simple Binary Trie

This solution requires O(W) time and O(N W) memory. The average case according to the current Internet is bounded by 11 and 22 trie steps.

Path-Compressed Tries

Often, these binary tries contain long sequences of nodes without branching.

For exact matching, Gwehenberger [Gwe68] presents an algorithm to reduce these long chains of “white” nodes (compare Figure 3.1), by introducing a skip count in each node. This technique of using skip counts later became known as path compression and reduces the number of trie nodes to2N−1, independent of the data set. At about the same time, Morrison [Mor68] independently created a library indexing system based on the same idea, which he called PATRICIA. This name has stuck.

The most commonly available IP lookup implementation was imple-mented for the BSD Unix kernel by Sklower [Skl93]. It combines the idea of path path-compression and longest prefix matching. In path-compressed tries, not all of the intermediate bits are stored in the trie nodes traversed. Although this optimization reduces the work required for exact matches, it increases the cost of longest prefix matching searches: When the search reaches a terminal node, it may turn out that the entry stored there no longer matches the search argument. This then leads to expensive backtracking. Because the structure of these single-bit tries closely models the aggregation hierarchy, updates are very fast. Despite this, the search implementation requires up to 2W costly memory accesses—64 or 256 for IPv4 or IPv6, respectively.

PATRICIA exhibits the same time complexity as the binary trie, but gen-erally is faster. Since the average cost depends much stronger than the basic trie on the actual prefixes stored, the average case would be too variable to make a reasonable statement.

LC-Tries

Nilsson and Karlsson [NK98] enhance the radix trie’s path compression by level compression. Whenever a trie node does not have terminal nodes for the next t levels, the fan-out trie is compressed into a single array of size 2t andtbits are used to index into this array of pointers to nodes. Unlike all the trie variants mentioned below, this structure is still self-contained. This means that it does not require a simpler helper trie to be built from. Unfortunately, insertions and deletions can become expensive, if they require large fan-out arrays to be built or destroyed. It also does not gain as much speed advantage as the read-only tries below, yet it is quite complex to handle.

3.2. Existing Approaches to Longest Prefix Matching 27 As PATRICIA, LC-tries do not improve time complexity, although the average search depth is reduced from 19 (binary trie) to 8 (LC-trie) in the authors’ analysis.

Controlled Prefix Expansion

Srinivasan and Varghese [SV99a] improved binary tries by extracting multiple bits at a time and using them as an index into an array of pointers to child nodes. While the idea is extremely simple, the implementation is tricky. Since there is no longer a one-to-one relation between terminal nodes and database entries, updating can be painful and requires a conventional binary trie as a helper structure. Also, memory consumption can be high if the number of bits to take per step (stride) does not match the database well. But probably the idea’s biggest disadvantage is that it does only improve search speed by a constant factor and thus does not scale to longer address lengths.

The time complexity is O(W/S), where S is the stride, with memory growing to O(N ∗2S). With S being tunable, average-case numbers cannot be given.

Compact Tries

Degermark et al. [DBCP97] present a method for compactly encoding the largest forwarding databases to fit into the second-level cache of DEC Alpha [Sit92] processors. Their scheme is quite complex and shows similarities to data compression algorithms. The search requires a large number of different steps. As the operations are done in the cache and not in slow main memory, they still perform well.

Again, the time complexity remains atO(W). Due to the entirely different per-search-step operation, an average comparison with the other tries does not make sense.

All these trie variants improve the speed only by at most a constant factor.

The search acceleration for 32 bits is good, but they will run into performance problems with the migration to IPv6 addresses. These schemes can also ex-hibit bad update behavior. Many of the faster algorithms cannot be updated

dynamically and require a traditional trie as a helper structure to rebuild the fast search structure from. A good summary can also be found in [SV99b].