This invention generally relates to the field of string search devices and, in particular, to optimizing the processing speed and storage area requirements of search trees used to implement multiple pattern search operations on an input data sequence.
The problem of string searching occurs in many applications. The string search algorithm looks for a string called a “pattern” within a larger input string called the “text.” Multiple string searching refers to searching for multiple such patterns in the text string without having to search in multiple passes. In a string search, the text string is typically longer than several million bits long with the smallest unit being one octet in size. The start of a pattern string within the text is typically not known. A search method that can search for patterns when the start of patterns within the input string is not known in advance is known as unanchored searching. In an anchored search, the search algorithm is given the input string along with information on the offsets for start of the strings.
A network system attack (also referred to herein as an intrusion) is usually defined as an unauthorized or malicious use of a computer or computer network. In some cases, a network system attack may involve hundreds to thousands of unprotected network nodes in a coordinated attack, which is levied against specific or random targets. These attacks may include break-in attempts, including but not limited to, email viruses, corporate espionage, general destruction of data, and the hijacking of computers/servers to spread additional attacks. Even when a system cannot be directly broken into, denial of service attacks can be just as harmful to individuals and companies, who stake their reputations on providing reliable services over the Internet. Because of increasing usage and reliance upon network services, individuals and companies have become increasingly aware of the need to combat system attacks at every level of the network, from end hosts and network taps to edge and core routers.
Intrusion Detection Systems (or IDSs) are emerging as one of the most promising ways of providing protection to systems on a network. Intrusion detection systems automatically monitor network traffic in real-time, and can be used to alert network administrators to suspicious activity, keep logs to aid in forensics, and assist in the detection of new viruses and denial of service attacks. They can be found in end-user systems to monitor and protect against attacks from incoming traffic, or in network-tap devices that are inserted into key points of the network for diagnostic purposes. Intrusion detection systems may also be used in edge and core routers to protect the network infrastructure from distributed attacks.
Intrusion detection systems increase protection by identifying attacks with valid packet headers that pass through firewalls. Intrusion detection systems provide this capability by searching both packet headers and payloads (i.e., content) for known attack data sequences, referred to herein as “signatures,” and following prescribed actions in response to detecting a given signature. In general, the signatures and corresponding response actions supported by an intrusion detection system are referred to as a “rule-set database,” “IDS database” or simply “database.” Each rule in the database typically includes a specific set of information, such as the type of packet to search, a string of content to match (i.e., a signature), a location from which to start the search (e.g., for anchored searches), and an associated action to take if all conditions of the rule are matched. Different databases may include different sets of information, and therefore, may be tailored to particular network systems or types of attack.
At the heart of most modern intrusion detection systems is a string matching engine that compares the data arriving at the system to one or more signatures (e.g., strings or patterns) in the rule-set database and flags data containing an offending (e.g., matching) signature. As data is generally searched in real time in ever-faster network devices and rule databases continue to grow at a tremendous rate, string matching engines require rapidly increasing memory capacity and processing power to keep pace. Consequently, to avoid the escalating costs associated with ever-increasing hardware demands, designers have endeavored to improve the efficiency of the string matching methodology itself.
For example,
Each state in the search tree 100A can be viewed as representing a prefix of one or more of the signatures K1-K4. For example, state S3 represents a match between an input string and the prefix “rai” of signatures K1 and K2). Each of the states having two or more success transitions is referred to herein as a branch node, and each sequence of states subsequent to the branch node is referred to as a sub-branch. Thus, the strings that share a common prefix also share a corresponding set of parent states in the search tree. For example, search tree 100A includes three branches originating at root node S0. The first branch includes an initial state S1 and subsequent states S2-S7 and S14, where states S5-S7 form a first sub-branch at branch S4 that together with states S1-S4 represents K1=“raining,” and state S14 forms a second sub-branch at S4 that together with states S1-S4 represent K2=“rains.” The second branch includes an initial state S8 and subsequent states S9-S13 that represents K3=“damns.” The third branch includes an initial state S15 and subsequent states S16-S19 that represent K4=“nsdaq.” Further, the distance of a state from the root node in the goto graph is referred to as the depth of that state. For example, states S1, S8, and S15 have a depth of 1, states S2, S9, and S16 have a depth of 2, and so on.
For search trees such as goto graph 100A of
During search operations between an input text string and the signatures K1-K4, a string search engine (not shown in
For example, during a string search operation between an input string S1=“rains” and the signatures K1-K4 according to the search tree 100A of
When a failure transition is taken from a current state of the search tree 100A to the root node, the cursor is decremented (e.g., rewound) a number of positions in the input string equal to the number of states between the current state and the root node (e.g., the depth of the current state), minus one. For example, during a search operation between the input string S2=“rainy” and the signatures K1-K4 implemented according to search tree 100A, edge failure occurs at state S4 because the current character at S4, which is “y,” does not match either the “s” or the “i” success transition from state S4. Thus, at state S4, where C=4 and CC=“y,” the failure transition from S4 to the root node S0 (not shown for simplicity) is taken, and the cursor is rewound by 3 positions (e.g., from C=4 to C=1) to identify CC=“a” as the next input character to be examined, which requires characters “a,” “i,” and “n” of the input string to be re-processed by the search engine. Accordingly, because edge failure at any non-root state of search tree 100A requires returning to the root node S0 and rewinding the cursor according to the number of prior state transitions traversed into the tree (e.g., according to depth of the current state), string search operations implemented according to search tree 100A may require substantial reprocessing of data.
String search processing speeds may be improved by replacing some failure transitions to the root node S0 in search tree 100A with failure edges to non-root states. More specifically, the search tree 100A may be modified using the well-known Aho-Corasick (AC) scheme so that instead of returning to the root node upon edge failure, the search engine may transition to another non-root state that constitutes an accumulated prefix within the path in which edge failure occurs. For example,
For one example, during string search operations performed according to the basic goto-failure graph 100B, if edge failure occurs at state S12 (e.g., because the cursor data is not an “s”), the search engine, having traversed the path “drain” in the second branch and thus already detected the prefix “rain” associated with the first branch, may transition directly from state S12 to S4 via failure edge 114 (e.g., without returning to the root node and then traversing through states S1-S4). Upon the failure transition 114 from S12 to S4, which corresponds to detection of the prefix “rain” of the signature K2=“rains,” the cursor remains constant at C=4 (e.g., to identify “n” as CC), and the back pointer is incremented by one position from BP=0 to BP=1 (e.g., to identify “r” as the first character in a potentially matching string). Thus, the matching pattern “rains” within the input string “drains” may be subsequently detected at state S14 without having to return to root node S0 upon edge failure at state S12. This is in contrast to the non-optimized search tree 100A, which upon edge failure from state S12 to the root node S0 would require rewinding the cursor by four positions and then require re-processing the first four characters “r,” “a,” “i,” and “n” of the input string. In this manner, transition to a non-root node in response to edge failure may save substantial data reprocessing and thus increase search speeds.
Note that search trees of the type shown in
It is known that a string search engine operating according to basic AC goto-failure state graphs such as search tree 100B of
Basic AC goto-failure state graphs that process one input character at a time, such as search tree 100B of
Although achieving nearly double the worst-case processing speed of search operations as the goto-failure state graph 100B of
As a result, for modern IDS applications in which a signature definition includes a large number of signatures, it is impractical to build a hardware implementation of a corresponding fully-expanded AC DFA search tree because of storage limitations of currently available memory devices. For example, to store state information for a fully-expanded state graph that embodies thousands of signatures each including dozens of characters, several million storage entries may be required, which is not feasible to implement using today's semiconductor storage devices.
Therefore, for modern string search operations, there is a need to dynamically balance processing speeds with storage area requirements to maximize the processing speeds achieved using a semiconductor storage device of a given size.
The present invention is illustrated by way of example and not intended to be limited by the figures of the accompanying drawings, where:
Like reference numerals refer to corresponding parts throughout the drawing figures.
In the following description, numerous specific details are set forth such as examples of specific, components, circuits, and processes to provide a thorough understanding of the present invention. It will be apparent, however, to one skilled in the art that these specific details need not be employed to practice the present invention. In other instances, well known components or methods have not been described in detail in order to avoid unnecessarily obscuring the present invention. As used herein, the terms “search tree” and “state graph” refer to state diagrams that embody one or more signatures to be searched for in an input string during string search operations, and are thus interchangeable. Further, the term “success transition,” which refers herein to a goto transition from a current state to a next state in a search tree, is also commonly referred to as a “success edge.”
String matching apparatus and methods that achieve increased processing speeds without exponential increases in memory storage requirements are disclosed herein in various embodiments. More specifically, in accordance with some embodiments of the present invention, a method and/or apparatus may be used to selectively modify a search tree embodying a plurality of signatures to be compared with an input string of characters to create a modified search tree that requires a minimum amount of storage area for a specified minimum processing speed. For some embodiments, a minimum processing speed is first specified for a finite state machine configured to implement a search tree embodying a desired signature definition. Then, a number of pairs of failure size (F) and success size (S) parameter values are identified that result in a worst-case processing speed that is greater than the specified minimum processing speed, where F indicates a minimum number of input characters traversed on failure transitions and S indicates a maximum number of input characters traversed on success transitions. Next, the search tree is modified to create a number of modified search trees, each characterized by a corresponding one of the identified pairs of F and S values. Then, an amount of storage area required to store each modified search tree is calculated, and thereafter the modified search tree that requires the least amount of storage area is selected for implementation by the finite state machine. For another embodiment, a given amount of storage area may be specified, and the search tree may be selectively modified in accordance with present embodiments to achieve a maximum processing speed for the specified storage area. For yet another embodiment, any one of the modified search trees corresponding to the identified F and S parameter pairs may be selected for implementation by the finite state machine.
For some embodiments, a string search engine may employ a next search size (NSS) bitmap to determine how many input characters are to be initially compared with the success transitions at the associated state of the search tree, and if the compare operation results in edge failure, whether to compare one or more groups of fewer input characters (e.g., overlapping substrings of the input string) to the success transitions at the associated state during one or more successive compare operations. As explained in detail below, the NSS bitmap not only allows the number of input characters initially compared with the success transitions at a given state to be dynamically adjusted, but also allows for one or more subsequent iterative compare operations between decreasing numbers of input characters (e.g., overlapping substrings of decreasing size) and the success transitions upon initial mismatch results at a given state of the search tree.
For one example, the state entry (STEN) for state S4 of the goto-failure graph 100B may be represented as STEN4={0; i,5; s,14; 0}, where FS=0 indicates that the root node S0 is the fail state of S4; ST[0]=“i,5” indicates that state S4 includes an “i” success transition to a next state S5; ST[1]=“s,14” indicates that state S4 includes an “s” success transition to a next state S14; and OC=0 indicates that state S4 does not include an output code. For another example, the state entry for state S13 of goto-failure graph 100B of
Table 210 also shows the number of memory bytes required to store each of the state entries for the basic AC search tree 100B. More specifically, for the state entries depicted in Table 210, each FS field requires 1 byte of memory storage area, each success character requires 1 byte of memory storage area, each next state requires 1 byte of memory storage area, and each output code requires 1 byte of memory storage area. Thus, for example, S4's state entry STEN4={15; i,5; s,14; 0} requires 6 bytes, while S19's state entry STEN19={0; 0; K4} requires 3 bytes. Accordingly, the state entries for states S0-S19 of the goto-failure graph 100B, as depicted in Table 210 of
Some embodiments of the present invention are discussed below in the context of a search engine that employs an SRAM (or DRAM) device to store the state information for search trees that embody the signature definition to be searched for during string search operations. For example,
Search logic 310 includes control logic 312 and compare logic 314. Control logic 312, which includes an input port to receive an input string from a network connection (not shown for simplicity) and an output port to provide search results to the network connection, controls search operations between the input string and the signatures embodied by the search tree and stored as state entries in state memory 320. Compare logic 314, which is coupled to state memory 320 and to control logic 312, implements the string search operation using a state transition scheme embodied by the search tree stored in state memory 320. Further, although not shown in
For example, during search operations, compare logic 314 provides a current state (CS) value as an address to state memory 320, which in response thereto outputs a corresponding state entry (STEN) to compare logic 314. Compare logic 314 then compares the current character (CC) extracted from the input string by control logic 312 (e.g., in response to the cursor values) to the success characters (SC) of the success transition fields in the retrieved state entry (STEN) to determine the next state in the search tree. If the cursor data matches one of the state's success transitions, the corresponding next state (NS) value is read from the state entry, and the next state value is used as an address to retrieve the corresponding “next” state entry from state memory 320. For example, if the state machine is in state S1 of search tree 100B, a cursor data value CC=“a” results in a match with the “a” success transition 102, and the state machine transitions from state S1 to state S2 via the “a” success transition by reading the NS=2 value from the success transition field of S1's state entry, and then retrieving the state entry for S2 from state memory 320 using NS=2 as a read address.
Otherwise, if the cursor data does not match any of the success transitions at the current state, the fail state (FS) value is read from the state entry, and the fail state value is used as an address to retrieve the corresponding “fail” state entry from state memory 320. The retrieved fail state entry is then used as the current state for the next search cycle. For example, if the state machine is in state S1 of search tree 100B, a cursor data value other than CC=“a” results in edge failure, and thus the FS=0 value from S1's state entry is used to load the state entry for S0 as the next current state, thereby facilitating the state machine's transition from state S1 to the root node S0 (e.g., via the failure transition 110). Further, if the current state entry contains a non-zero output code (OC) indicating a signature match, the output code is provided to control logic 312 for outputting information corresponding to the signature match to the network connection.
For some embodiments, compare logic 314 includes a cache memory 316 that stores the state entry for the root node S0, as depicted in
As described above, the cursor (C) points to the current character of the input data, and the back pointer (BP) points to the first character in a potentially matching string within the input string. Thus, the distance (e.g., the number of characters positions) between the back pointer (BP) and the cursor (C) indicates the prefix match length (PML) of the potentially matching string, where PML=C−BP. Further, as discussed above, when the back pointer moves forward on a failure transition to another state, the distance between the back pointer and the cursor is reduced, thereby reducing the PML. Thus, in accordance with some embodiments of the present invention, the number of character positions that the back pointer moves forward on a failure transition is denoted as the removed prefix length (RPL) associated with the failure transition. As a result, when the string search engine takes a failure transition from a first state to a second state, the PML of the input string at the second state is equal to the PML of the input string at the first state minus the RPL of the failure transition.
To aid in the understanding of the concepts of PML and RPL as related to C and BP, consider a search operation between an input string S1=“rainy” and signatures K1-K4 using the goto-failure graph 100B. During the search operation, the search engine successively transitions from state S0 to state S4 via success transitions “r,” “a,” “i,” and “n,” where at state S4, the cursor C=4 and the back pointer BP=0. Thus, the PML associated with state S4 is PML=C−BP=4−0=4, which corresponds with the 4 character prefix “rain.” Thereafter, upon edge failure at S4 (i.e., the next input character “y” does not match the “i” or “s” success transitions from S4, the state machine fails to state S15, and the back pointer is incremented by 3 positions from BP=0 to BP=3 to identify “n” as the first character of a potentially matching string. Thus, the failure transition 115 from state S4 to S15 has an RPL=3 because the back pointer is incremented by 3 characters on the failure transition 115 (and also because the prefix match “rain” associated with state S4 is 3 characters longer than the prefix match “n” associated with state S15, and thus three characters are “removed” from the prefix match length upon edge failure from state S4 to S15 via failure transition 115). The RPL value of a failure transition may also be described as the difference between the depth of the source state and the depth of the fail state. For example, referring again to
Further, in accordance with some embodiments of the present invention, the maximum number of characters in the input string that the cursor (C) traverses on a success transition is denoted herein as the success size (S) parameter of the search tree, and the worst-case number of characters (e.g., the fewest number of characters) that the back pointer BP traverses on a failure edge to a non-root state is denoted herein as the failure size (F) parameter of the search tree. Thus, to process Y characters of an input string, the cursor requires Y/S processing cycles, and the back pointer requires Y/F processing cycles. Therefore, in accordance with the present invention, the worst-case speed (P) to process Y characters of the input string may be expressed below as:
For example, because a search engine operating according to the goto-failure graph 100B of
By comparison, because a search engine operating according to the fully expanded state graph 100C of
characters per processing cycle.
However, as mentioned above, to achieve a “full” speed of P≈1.0 characters per cycle using a state graph having S=1, as depicted in
Thus, in accordance with some embodiments of the present invention, the S and/or F parameter values associated with a selected state graph may be manipulated to generate a limited expansion state graph that achieves an acceptable balance between worst-case processing speed P and the storage area required to store the state entries that implement the state machine. More specifically, for some embodiments, the state transitions of a given goto-failure state graph may be selectively modified to achieve a given minimum processing speed for a maximum storage amount. For example,
In operation, optimization engine 351 calculates a plurality of various F and S parameter pair values that result in a worst-case processing speed that is greater than Pmin. Then, for each F and S parameter pair, optimization engine 351 modifies the state entries of the goto-failure state graph stored in memory 352 to create a modified state graph that operates according to the F and S parameter pair, and then calculates the amount of memory required to store the modified state graph. For some embodiments, optimization engine 351 is responsive to a parameter select pair signal SEL_PAIR provided, for example, by the user. For some embodiments, SEL_PAIR may instruct optimization engine 351 to calculate the required storage area for a specified number of F and S parameter pairs. For other embodiments, SEL_PAIR may instruct optimization engine 351 to calculate the required storage area for one or more selected F and S parameter pairs.
Next, one or more pairs of F and S parameter values that result in at least the desired minimum worst-case processing speed are identified (step 402). For example, optimization engine 351 calculates a plurality of F and S parameters pairs that result in a worst-case processing speed that is greater than Pmin using the equation
For this example, several possible pairs of F and S parameter values that result in the selected worst-case processing speed of 0.7 characters are listed below in Table 1 (for simplicity, Table 1 does not list all possible F and S parameters pairs that result in a worst-case speed that is greater than 0.7 characters per cycle).
For example, using the processing speed equation described above, the F=1 and S=4 parameter pair achieves a worst-case processing speed of 1*4/(1+4)=4/5=0.8 characters per cycle, and the F=4 and S=1 parameter pair also achieves a worst-case processing speed of 4*1/(4+1)=4/5=0.8 characters per cycle. For another example, the F=1 and S=3 parameter pair achieves a worst-case processing speed of 1*3/(1+3)=3/4=0.75 characters per cycle, and the F=3 and S=1 parameter pair also achieves a worst-case processing speed of 3*1/(3+1)=3/4=0.75 characters per cycle.
Then, for each identified F and S parameter pair, the basic goto-failure state graph is optimized (e.g., modified) to create a modified state graph that operates according to the selected F and S parameter values pair (step 403). For example, optimization engine 351 selectively modifies (e.g., by adding, changing, and/or deleting) the state transitions of the basic goto-failure state graph 1008 to create a number of modified state graphs, each of which operates according to (e.g., and is thus characterized by) a corresponding F and S parameter pair.
Next, the memory area required to store the state information for each modified state graph is calculated (step 404). For example, for each selected F and S parameter pair, optimization engine 351 calculates the memory area required to store all of the state entries for the state graph modified to operate according to the selected F and S parameter pair.
Finally, the modified search tree that requires the least amount of storage area is identified, and the corresponding F and S parameter pair is selected as the optimum parameter pair (step 405). For example, optimization engine 351 compares the storage area requirements for all the modified search trees that result in a worst-case processing speed that is greater than Pmin, and identifies the parameter pair associated with the modified state graph that requires the least amount of storage area to store its state information. In this manner, embodiments of the present invention allow the worst-case processing speed of the basic search tree to be increased with an acceptable increase in storage area requirements, thereby allowing for an effective optimization between processing speed and storage area requirements. Of course, for other embodiments, the modified search tree corresponding to any of the identified F and S pairs may be selected for implementation by the finite state machine (FSM).
Thereafter, a finite state machine (e.g., such as search engine 300 of
A first embodiment of the present invention performed by the optimization circuit 350 of
Next, a value of F is selected that indicates a desired minimum number of characters to be traversed (e.g., by the back pointer) on failure transitions to non-root states (step 502). For this example, the worst-case failure size parameter is selected to be F=4, which achieves a worst-case processing speed of
characters per cycle. Alternatively, the desired worst-case processing speed may be selected for a search tree characterized by a given S value, and then a value of F that results in the desired worst-case processing speed for the given S value may be calculated using the above equation, for example, where
Then, the basic state graph is selectively modified in accordance with the present invention to create a limited expansion state graph for which all failure transitions to non-root nodes are characterized by the selected F parameter (e.g., so that all failure transitions to non-root states have an RPL that is greater than or equal to the selected F parameter value) (step 503). For this example, the state entries of the basic goto-failure graph 100B are selectively modified until all failure transitions to non-root nodes have an RPL that is greater than or equal to F=4.
More specifically, to create the limited expansion state graph from the basic goto-failure graph, the RPL value of each failure transition in the basic goto-failure graph is first calculated (step 503a). This calculation may be used to identify those states that may be modified in accordance with the present invention to increase processing speeds, as described in detail below. For this example, the RPL values associated with the failure transitions from states S1-S19 of the goto-failure graph 100B of
Next, all states in the basic goto-failure graph for which the failure transition has an RPL value that is less than the selected F parameter value are identified and designated as violating states (step 503b), for example, by comparing the RPL values of the failure transitions with the selected value of the F parameter. For the goto-failure graph 100B, states S1-S4 and S8-S17 are designated as violating states because each of their failure transitions has an RPL value that is less than F=4.
Then, for some embodiments, each violating state that fails directly to the root node is exempted from the “violating state” designation (step 503c). These states may be exempted from the “violating state” designation, regardless of the RPL values of their failure transitions, because failure to the root node S0 from these states does not adversely affect the worst-case processing speed. More specifically, because search engine 300 of
Alternatively, for other embodiments, all states that fail directly to the root node S0 may be excluded from being designated as violating states in step 503b, in which case step 503c may be eliminated. Thus, for such other embodiments, only states S4 and 9-S14 are initially designated as violating states.
Then, in accordance with the present invention, the state transition information for each of the remaining violating states is modified so that its failure transition has an RPL value that is greater than or equal to the selected F value (step 503d). For this example, the state transition information for each of the violating states S4 and S9-S14 is modified so that each of their failure transitions has an RPL z 4.
One exemplary operation for modifying the state information of each of the remaining violating states is described below with respect to the illustrative flow chart 530 of
Then, the success transitions of the selected violating state's fail state are examined to determine whether the fail state includes any success transitions that are not common (e.g., are a subset) of the selected violating state's success transitions (step 532). If not, as tested at step 533, which indicates that the fail state of the selected violating state does not include any success transitions that are not common to the violating state, the failure transition of the selected violating state is replaced with the failure transition of its fail state so that both the selected violating state and its fail state now fail to the same state (step 534).
For some embodiments, if the fail state does not include any success transitions that are not common with the success transitions of the violating state, the failure transition from the violating state is denoted as a redundant failure transition. Redundant failure transitions may be replaced with the failure transition of the fail state because failure from the violating state to the fail state via the redundant failure transition necessarily results in edge failure from the fail state. For example, referring to
Conversely, if the fail state of the selected violating state includes one or more success transitions that are not common to the violating state, as tested at step 533, then the non-common success transitions of the fail state are added as new cross edges to the selected violating state (step 535). In terms of state entry modifications, the non-common success fields of the fail state are copied to the state entries of the selected violating states. The addition of the new cross edge(s) to the violating state causes the violating state's failure transition to become a redundant failure transition, which is then replaced with the failure transition of the fail state so that both states now fail to the same state (step 534).
For example, the failure transition 114 from violating state S12 to its fail state S4 is not redundant because S4 includes an “i” success transition to S5 that is not common to the success transitions of state S12. Thus, the addition of an “i” cross edge from S12 to S5 (step 535) causes S12's failure transition 114 to become redundant, which is then replaced by S4's failure transition to S15 so that states S12 and S4 both fail to S15 (step 534).
Next, it is determined whether the fail state of the selected violating state is an output state (step 536). If so, as tested at step 537, the output code of the fail state is added to the selected violating state (step 538), and modification of the violating state is complete. This process is repeated for the designated violating states so that all failure transitions to non-root states have an RPL≧F.
Modification of the designated violating states S4 and S9-S14 of the basic goto-failure graph 100B in accordance with the exemplary embodiment described above with respect to the illustrative flow charts of
Because the back pointer now moves forward four positions over characters “r,” “a,” “i,” and “n” upon edge failure from state S4 to S0 via failure transition 601, edge failure at state S4 now has an RPL=4=F (e.g., compared to an old RPL=3), and thus state S4 is no longer a violating state. Further, replacing failure transition 115 with failure transition 601 does not increase the memory storage requirements because only the fail state (FS) field of S4's state entry is modified. More specifically, the state entry for S4 in goto-failure graph 100B is {15; i, 5; s, 14; 0}, which requires 6 bytes of memory, and the state entry for S4 in graph 600A is {0; i, 5; s, 14; 0}, which also requires 6 bytes of memory. In this manner, redundant failure transitions such as failure transition 115 may be replaced to increase processing speed without increasing memory storage requirements.
Next, violating state S12 is selected for this example. The fail state of S12 is S4, which includes an “s” success transition (i.e., to S14) and includes an “i” success transition (i.e., to S5), as well as a failure pointer to the root node S0. Because violating state S12 does not include an “i” success transition, the fail state S4 includes a success transition that is not common to S12, and thus the success transition set of fail state S4 is not a subset of the success transition set of violating state S12. Thus, in accordance with the present invention, the non-common success transition “i,5” is added to the violating state S12 as “i” cross edge 612, as shown in
Because the back pointer now moves forward five positions over characters “d,” “r,” “a,” “i,” and “n” upon edge failure from state S12 to S0 via failure transition 602, state S12 now has an RPL=5>F (e.g., compared to an old RPL=1), and thus state S12 is no longer a violating state. The addition of cross edge 612 to S12 requires the addition of one success pointer to S12's state entry, thereby increasing the memory storage area required for STEN12. More specifically, while S12's state entry for goto-failure graph 100B is {4; s,13; 0}, S12's state entry for graph 600A is {0; s,13; i,5;0}, thereby increasing the storage area required for STEN12 from 4 bytes to 6 bytes.
Note that because S4 is the original fail state of S12, and because the failure transition 114 of S12 is ultimately replaced by a failure pointer to the fail state of S4, modifying S4 prior to modifying S12 may, for this example, result in a simpler modification operation. Otherwise, if S12 were modified first, its failure pointer would be replaced by a failure pointer to S15, which is the original fail state of S4. Then, upon subsequent modification of S4, replacing its failure pointer with a failure pointer to S0 (which is the fail state of S15) would require updating the failure pointer of S12 with the new failure pointer of S4.
Next, violating state S14 is selected for this example. The fail state of S14 is state S16, which includes a “d” success transition (i.e., to S17) and a failure pointer to the root node S0. Because violating state S14 does not include a “d” success transition, the fail state S16 includes a success transition that is not common with S14, and thus the success transition set of fail state S16 is not a subset of the success transition set of violating state S14. Thus, in accordance with the present invention, the non-common success transition “d,17” is added to violating state S14 as “d” cross edge 613, as shown in
Because the back pointer now moves forward five positions over characters “r,” “a,” “i,” “n” and “s” upon edge failure from state S14 to S0 via failure transition 603, state S14 now has an RPL=5>F (e.g., compared to an old RPL=3), and thus state S14 is no longer a violating state. The addition of cross edge 613 to S14 requires the addition of one success pointer to S14's state entry, thereby increasing the memory storage area required for STEN14. More specifically, while S14's state entry for goto-failure graph 100B is {16; 0; K2}, S14's state entry for graph 600A is {0; d,17; K2}, thereby increasing the storage area required for STEN14 from 3 bytes to 4 bytes.
Next, state S13 is selected for this example. The fail state of S13 is S14, which now includes a “d” success transition (i.e., to S17) and a failure pointer 603 to S0. Because violating state S13 does not include a “d” success transition, the fail state S14 includes a success transition that is not common with S13, and thus the success transition set of fail state S14 is not a subset of the success transition set of violating state S13. Thus, in accordance with the present invention, the non-common success transition “d,17” is added to violating state S13 as “d” cross edge 614, as shown in
Because the back pointer now moves forward six positions over characters “d,” “r,” “a,” “i,” “n,” and “s” upon edge failure from state S13 to S0 via failure transition 604, edge failure at state S13 now has an RPL=6>F (e.g., compared to an old RPL=1), and thus state S13 is no longer a violating state. In addition, because state S13's previous fail state S14 is an output state, the output code of S14 is added to S13 so that state S13 now includes output codes for both K3=“drains” and K2=“rains,” as shown in
Note that because S14 is the original fail state of S13, modifying S14 prior to modifying S13 may, for this example, result in a simpler modification operation for reasons similar to those described above with respect to states S4 and S12.
The remaining violating states S9-S11 have redundant failure transitions 111-113 to states S1-S3, respectively, and therefore may be modified by replacing their failure transitions with failure pointers to the root node S0 (e.g., in a manner similar to that described above with respect to state S4). For example, the fail state of S9 is S1, which fails to the root node S0 and does not have any success transitions that are not common to S9. Thus, state S9 may be modified by replacing its failure transition 111 to S1 with a failure pointer to S0 (not shown for simplicity) so that S9 and its previous fail state S1 now both fail to the same state (e.g., the root node S0). Similarly, state S10 may be modified by replacing its failure transition 112 to S2 with a failure pointer to S0 (not shown for simplicity) so that S10 and its previous fail state S2 now both fail to the same state (e.g., the root node S0). Similarly, state S11 may be modified by replacing its failure transition 113 to S3 with a failure pointer to S0 (not shown for simplicity) so that S11 and its previous fail state S3 now both fail to the same state (e.g., the root node S0). Because the failure transitions of S9-S11 are redundant, and thus only the failure pointers of S9-S11 need to be modified to alleviate their “violating state” designation, modification of the state entries for S9-S11 does not require additional memory storage area.
Modifications to the state entries of the goto-failure state graph 100B of
Thus, for the example described above, the processing speed of the basic goto-failure state graph 100B of
For other embodiments, the redundant failure transitions of the basic goto-failure graph may be modified first (e.g., before RPL calculations are used for violating state designations), which increases processing speed without increasing memory storage requirements. For example, referring to the illustrative flow chart 530 of
Although an exemplary embodiment for selectively modifying a search tree to increase its F parameter to a selected value is described above with respect to F=4, it is to be understood that embodiments of the present invention may be used to increase the F parameter of a suitable search tree to any selected value.
Further, for other embodiments, one or more states of a basic goto-failure graph may be individually selected for modification in accordance with the present invention (e.g., without selecting a F parameter that results in a worst-case processing speed), and/or subsequent to an F parameter optimization operation described above with respect to
Referring again to
As mentioned above, the processing speed of the string search engine may also be improved by increasing the value of the S parameter of a given search tree. In accordance with some embodiments of the present invention, the processing speed of a search tree such as the basic AC goto-failure state graph may be increased by applying path compression techniques to create a path-compressed search tree that allows multiple characters to be traversed on some success transitions. Path compression involves concatenating linear (i.e., non-branching) sequences of state transitions into a single state transition with the sequence of data values that formerly formed the success transitions in the sequence of states concatenated into a string that forms the success transition in the unified state transition, which reduces the number of nodes from W*N relative to the basic Aho-Corasick scheme depicted in
More specifically, path compression techniques in accordance with present embodiments allow selected groups of states of a search tree to be compressed into corresponding single states that represent multiple characters of the signature definition. In this manner, the value of the success-size (S) parameter may be increased, which increases processing speed. Further, increasing the S parameter may reduce the number of states of the search tree, which in turn may reduce memory storage requirements of the search tree.
A second embodiment of the present invention for selectively optimizing a given basic goto-failure state graph to create path-compressed state graph by modifying the graph's state information to achieve a selected success-size parameter S is described below with respect to the illustrative flow charts of
First, referring now to
Next, a value of the S parameter is selected (e.g., calculated) that will result in a desired minimum or worst-case processing speed, for example, where
(step 703). For this example, the success size parameter is selected to be S=2, which achieves a worst-case processing speed of
characters per cycle.
Then, the basic state graph is selectively modified (e.g., compressed) in accordance with the present invention to create a path-compressed state graph that allows a string search operation to process up to S characters of an input string at a time (step 704). An exemplary path compression technique in accordance with embodiments of the present invention is described below with respect to the illustrative flow chart 720 of
First, each sequence of S states of a signature branch or path beginning at the root node is combined (e.g., compressed) into a single core state representing S data values (step 704a). For example, starting with the basic goto-failure graph 100B of
Note that when forming the path-compressed state graph 800A of
For purposes of discussion herein, the compressed states and output states that form the resulting compressed state graph may be referred to herein as original or core states of the path-compressed state graph. For example, states S0, S2, S4, S6, S7, S9, S11, S13, S14, S16, S18, and S19 are referred to herein as core states of path-compressed state graph 800A. Thus, for this example, path compression of the basic goto-failure graph 100B of
Further, for some embodiments, the failure transitions between the core states of the path-compressed state graph are retained. Thus, for this example, the failure transition from S13 to S14 and the failure transition from S14 to S16 are retained, as depicted by the dotted lines in
Next, referring again to
Then, failure transitions are restored (e.g., inserted) between the core states of the path-compressed state graph and their corresponding restored fail states (step 704c). For this example, the failure transition from core state S9 to restored fail state S1 is restored, the failure transition from core state S11 to restored fail state S3 restored, and the failure transitions from core states S4 and S6 to restored fail state S15 is restored. These restored failure transitions are shown as bold dashed lines in
Then, a success transition having up to S characters is inserted from each restored fail state to the nearest core state so that a success path exists between each of the restored fail states and one or more corresponding output states (step 704d). For this example, a 1-character success transition “a” is inserted from restored fail state S1 to core state S2, a 1-character success transition “n” is inserted from restored fail state S3 to core state S4, and a 1-character success transition “s” is inserted from restored fail state S15 to core state S16 (the inserted cross success transitions are shown as bold lines in
Finally, any cross edges from core states to states that were eliminated during path compression are modified so that the cross edges now transition to states that are present in the path-compressed search tree (step 704e). For the present example, there are no such cross edges.
Thereafter, one or more of steps 704a-704e may be repeated, as necessary, to ensure that edge failure at any of the states in the path-compressed state graph results in a direct failure to a corresponding fail state that is present in the path-compressed search tree. More specifically, for each state restored in steps 704b and 704c, the corresponding fail state must also be restored (if not already existing) to enable direct edge failure. This process is repeated until there are no more eliminated fail states.
Restoring the fail states of the core states of the path-compressed state graph prevents edge failure to states that were eliminated during path compression, which would otherwise undesirably require rewinding the cursor upon such failures. For example, if fail state S15 is not restored to the path-compressed state graph of
As mentioned above, increasing the value of the S parameter of a search tree using path compression techniques in accordance with the present invention may not only increase processing speed but also may reduce the number of states in the search tree and thus may reduce the memory area required to store the tree's state entries. For this example, the path-compressed state graph 800B of
Referring again to
For the embodiments described above with respect to
Although an exemplary embodiment for selectively compressing a search tree to increase its S parameter to a selected value is described above with respect to S=2, it is to be understood that embodiments of the present invention may be used to increase the S parameter of a suitable search tree to any selected value.
For some embodiments, when creating a path-compressed state graph from a given basic goto-failure graph, a search tree bitmap may be created that includes an inclusion bit for each state in the search tree, wherein assertion of the inclusion bit indicates that the corresponding state is to be included in the path-compressed state graph, and wherein de-assertion of the inclusion bit indicates that the corresponding state is not to be included in the path-compressed state graph. Initially, the inclusion bits for all states in the basic goto-failure graph are de-asserted. Then, referring again to the illustrative flow chart of
As described above with respect to
However, for search trees in which S>1, compare operations at some states may require the string search engine to examine less than S characters of the input string at a time. For example, referring to the S=2 path-compressed state graph 800B of
Thus, in accordance with some embodiments of the present invention, a string search engine may employ a next search size (NSS) bitmap to determine how many input characters are to be initially compared with the success transitions at the associated state of the search tree, and if the compare operation results in edge failure, whether to compare one or more groups of fewer input characters (e.g., overlapping substrings of the input string) to the success transitions at the associated state during one or more successive compare operations. More specifically, in accordance with some embodiments of the present invention, each state entry of a search tree having S>1 may include a corresponding entry of an NSS bitmap that not only allows the number of input characters initially compared with the success transitions at a given state to be dynamically adjusted, but also allows for one or more subsequent iterative compare operations between decreasing numbers of input characters (e.g., overlapping substrings of decreasing size) and the success transitions upon initial mismatch results at a given state.
For example,
For some embodiments, a bit position of each NSS bit in the bitmap entry indicates how many of the input characters are to be included in the corresponding substring of the input string. For one embodiment, the NSS bits are arranged within each bitmap entry according to decreasing substring lengths, for example, so that the first bit NSS[S] in the bitmap entry indicates whether a first substring including S of the input characters are to be compared at the associated state, the second bit NSS[S−1] in the bitmap entry indicates whether a second substring including S−1 of the input characters are to be compared at the associated state, and the last bit NSS[1] in the bitmap entry indicates whether a last substring including 1 of the input characters is to be compared at the associated state. In this manner, the NSS bitmap allows iterative compare operations to be performed to implement a longest prefix match at a given state of the search tree.
For example, for a bitmap entry 900 having S=2 bits NSS[2] and NSS[1], NSS[2] is positioned as the first bit in the bitmap entry and indicates whether a first substring including 2 of the input characters are to be compared with the success transitions at the associated state in a first compare operation, and NSS[1] is positioned as the second bit in the bitmap entry and indicates whether a second substring including 1 of the input characters is to be compared at the associated state in a second compare operation. For some embodiments, the first and second substrings overlap such that the second substring is a subset of the first substring, as described in more detail below with respect to
For some embodiments, an asserted (e.g., to logic 1) NSS bit indicates that an associated substring of a corresponding string length is to be compared at the associated state, and a de-asserted (e.g., to logic 0) NSS bit indicates that the associated substring is not to be compared at the associated state.
For another example, the NSS bitmap entry for state S4 includes NSS[2]=1 and NSS[1]=1. The first bit NSS[2]=1 instructs the string search engine to examine a first substring including 2 input characters in a first compare operation at state S4 (e.g., for a possible match with the 2-character success transition “in” to S6), and the second bit NSS[1]=1 instructs the search engine to examine a second substring including 1 input character in a second compare operation (e.g., for a possible match with the 1-character success transition “s” to S14) if the first compare operation results in edge failure.
For yet another example, the NSS bitmap entry for state S6 includes NSS[2]=0 and NSS[1]=1. The first bit NSS[2]=0 instructs the search engine to not compare a first substring including 2 input characters at state S6, and the second bit NSS[1]=1 instructs the search engine to compare a second substring including 1 input character in the first compare operation at state S6 (e.g., for a possible match with the 1-character success transition “g” to S7).
Further, note that both bits of the NSS entries for states S7, S13, S14, and S19 in bitmap 910 are de-asserted (e.g., to logic 0) because no input characters are examined at those states, as indicated in the search tree 800B of
For some embodiments, the individual NSS bitmap entries (e.g., as generally indicated by NSS bitmap entry 900 of
An exemplary search operation employing the NSS bitmap 910 of
For purposes of discussion herein, an un-examined portion of an input string 930 at the current state is depicted in
Then, the string search engine examines the first NSS bit of the bitmap entry for the current state (step 922). If the NSS bit is asserted, as tested at step 923, the string search engine compares a first substring of the input string with the success transitions of the current state in a first compare operation (step 924). Because the first NSS bit read from the S=2 bitmap entry is NSS[2], which has a bit position of 2 and thus corresponds to an input substring length L=2, the first substring 931 includes the first two unexamined characters CHAR[1] and CHAR[2] of the input string 930, as depicted in
If there is match between the first substring and one of the success transitions at the current state, as tested at step 925, the string search engine takes the matching success transition to the next state (step 926). For example, referring to the search tree of
Conversely, if there is not a match between the first substring and one of the success transitions at the current state, as tested at step 925, and if there are additional (e.g., un-examined) bits in the NSS bitmap entry, as tested at step 927, the next bit in the NSS bitmap entry is examined (step 928), and processing continues at step 923. Because the next NSS bit read from the bitmap entry is the second bit NSS[1], which has a bit position of 1 and thus corresponds to an input substring length L=1, the second substring 932 includes the first unexamined character CHAR[1] of the input string 930, as depicted in
Note that the second substring 932 includes one less unexamined input character than the first substring 931, and both the first and second substrings include the first unexamined input character CHAR[1]. As a result, the second substring 932 is a subset of the first substring 931. Thus, for some embodiments, the second substring may be formed by removing the last input character from the first substring.
If there is a match between the second substring and one of the success transitions at the current state, as tested at step 925, the string search engine takes the matching success transition to the next state (step 926). For example, if at state S4 the second substring 932 includes input character “s,” then the matching “s” success transition is taken to S14. Otherwise, if there is a mismatch, processing continues at step 927. If there are no more (e.g., un-examined) bits in the current NSS bitmap entry, as tested at step 927, iterative compare operations at the current state ends, and the failure transition is taken to the fail state of the current state.
Further, if the first NSS bit examined at step 922 is not asserted, as tested at step 923, then the associated first substring (e.g., substring 931 including CHAR[1] and CHAR[2]) is not compared with the success transitions at the current state, and processing continues at step 927 so that if the second NSS bit is asserted, then the second substring (e.g., substring 932 including CHAR[1]) is compared with the success transitions at the current state. For example, because NSS[2]=0 and NSS[1]=1 for state S6, the string search engine does not compare the first substring 931 (e.g., including two input characters) to the success transitions at S6, but rather only compares the second substring 932 (e.g., including one input character) to the success transitions at S6.
In addition, although described above with respect to string search operations between a plurality of signatures and an input string using a path-compressed search tree, for other embodiments, the NSS bitmaps described above may be used for selectively performing iterative compare operations between any searchable pattern and a number S of overlapping substrings of an input string. For these other embodiments, a bitmap having S next success size (NSS) bits is provided, wherein each NSS bit indicates whether an associated substring that includes a corresponding unique number of the input characters is to be compared with the searchable pattern in successive compare operations. Then, the successive compare operations are selectively performed in response to the NSS bits and/or the match results of previous compare operations.
As described above with respect to
More specifically, referring again to
Further, because there are no longer any failure transitions to the previously restored fail states S1 or S3, states S1 and S3 are no longer fail states for any of the core states of the path-compressed state graph 800B, and therefore may be eliminated, as shown in
Other aspects of the failure-size (F) parameter optimization techniques described above with respect to the flow charts of
For other embodiments, the basic goto-failure search tree embodying a number of signatures may be first modified to increase the failure-size parameter F, and then subsequently modified to increase the success-size parameter S. More specifically, the failure and/or success transitions of the basic goto-failure graph may be modified first to create a limited expansion state graph having an increased F parameter value (e.g., using the optimization operations described above with respect to the flow charts of
Then, the fail states of the core states of the path-compressed state graph that were eliminated during the path-compression operation of step 704a are restored (step 704b). For this example, state S15, which is the fail state of core state S6, is restored to form a modified path-compressed state graph 1100B, as shown in
Next, failure transitions from the core states of the path-compressed state graph to their restored fail states are inserted (step 704c). For this example, the failure transition from core state S6 to restored state S15 is restored, as shown by the bold dashed line in
Then, a success transition having up to S=2 characters is inserted from each restored fail state to the nearest core state (step 704d). For this example, a 1-character success transition “s” is inserted between restored fail state S15 and core state S16.
Then, cross edges from the core states of the path-compressed state graph to states that were eliminated during path compression are modified so that for each such core state a cross edge exists to another core state (step 704e). For this example, referring also to
Note the similarity between the resulting state graphs of
As mentioned above, search operations implemented according to search trees created in accordance with processing speed optimization operations of the present invention may be performed by any suitable string search engine, including SRAM-based string search engines and TCAM-based search engines. When using an SRAM-based string search engine such as engine 300 of
For one example, at the root node of any of the S=2 search trees described herein (e.g., state graphs 800A, 800B, 1000A, 1000B, 1100A and/or 1100B), if the first 2 characters of the input string are “ra,” then the state value SID=00 may be concatenated with “ra” to form a hash key HK=“00ra.” The hash key is then hashed (e.g., using an appropriate hashing function) to generate an index I1 that points to the portion of the next state information corresponding to the matching edge “ra” (which for this example identifies state S2 as the next state because the success transition “ra” leads from state S0 to S2). For another example, if the first 2 characters of the input string are “dr” when the string search engine is at the root node S0, then the state value SID=00 may be concatenated with “dr” to form a hash key HK=“00dr.” The hash key is then hashed (e.g., using an appropriate hashing function) to generate an index I2 that points to the portion of the next state information corresponding to the matching edge “dr” (which for this example identifies state S9 as the next state because the success transition “dr” leads from state S0 to S9). In this manner, the hashing function performs the look-up function to determine the next state, which is accessed from a location generated by the hashing function rather than by reading the next state from the current state entry's matching success field.
As known in the art, a TCAM-based search engine may be used to eliminate multiple memory accesses at each state of the search tree (e.g., as may be required for SRAM-based search engines of the type shown in
In the foregoing specification, the invention has been described with reference to specific exemplary embodiments thereof. It will, however, be evident that various modifications and changes may be made thereto without departing from the broader spirit and scope of the invention as set forth in the appended claims. The specification and drawings are, accordingly, to be regarded in an illustrative sense rather than a restrictive sense.
This application claims the benefit under 35 USC 119(e) of the commonly owned U.S. Provisional Application No. 60/885,607 entitled “Optimizing Multiple Pattern Search Operations” filed on Jan. 18, 2007, which is incorporated by reference herein.
Number | Name | Date | Kind |
---|---|---|---|
5051886 | Kawaguchi et al. | Sep 1991 | A |
5151697 | Bunton | Sep 1992 | A |
5278981 | Kawaguchi et al. | Jan 1994 | A |
5299206 | Beaverson et al. | Mar 1994 | A |
5386413 | McAuley et al. | Jan 1995 | A |
5414704 | Spinney | May 1995 | A |
5440715 | Wyland | Aug 1995 | A |
5440753 | Hou et al. | Aug 1995 | A |
5452451 | Akizawa et al. | Sep 1995 | A |
5469161 | Bezek | Nov 1995 | A |
5497488 | Akizawa et al. | Mar 1996 | A |
5615378 | Nishino et al. | Mar 1997 | A |
5712971 | Stanfill et al. | Jan 1998 | A |
5781431 | Duret et al. | Jul 1998 | A |
5963942 | Igata | Oct 1999 | A |
5995963 | Nanba et al. | Nov 1999 | A |
6011795 | Varghese et al. | Jan 2000 | A |
6012057 | Mayer et al. | Jan 2000 | A |
6018524 | Turner et al. | Jan 2000 | A |
6067574 | Tzeng | May 2000 | A |
6115716 | Tikkanen et al. | Sep 2000 | A |
6185524 | Carus et al. | Feb 2001 | B1 |
6311183 | Cohen | Oct 2001 | B1 |
6377942 | Hinsley et al. | Apr 2002 | B1 |
6421660 | Glaise | Jul 2002 | B1 |
6425099 | Lattmann et al. | Jul 2002 | B1 |
6487566 | Sundaresan | Nov 2002 | B1 |
6505206 | Tikkanen et al. | Jan 2003 | B1 |
6538911 | Allan et al. | Mar 2003 | B1 |
6546391 | Tsuruoka | Apr 2003 | B1 |
6560610 | Eatherton et al. | May 2003 | B1 |
6785677 | Fritchman | Aug 2004 | B1 |
6856981 | Wyschogrod et al. | Feb 2005 | B2 |
6980992 | Hursey et al. | Dec 2005 | B1 |
7058821 | Parekh et al. | Jun 2006 | B1 |
7134143 | Stellenberg et al. | Nov 2006 | B2 |
7139753 | Bass et al. | Nov 2006 | B2 |
7139837 | Parekh et al. | Nov 2006 | B1 |
7529746 | Ichiriu et al. | May 2009 | B2 |
7636717 | Gupta et al. | Dec 2009 | B1 |
7676444 | Venkatachary et al. | Mar 2010 | B1 |
20030041163 | Rhoades et al. | Feb 2003 | A1 |
20030048785 | Calvignac et al. | Mar 2003 | A1 |
20030051043 | Wyschogrod et al. | Mar 2003 | A1 |
20030065774 | Steiner et al. | Apr 2003 | A1 |
20030065800 | Wyschogrod et al. | Apr 2003 | A1 |
20040015498 | Rabaioli | Jan 2004 | A1 |
20040162826 | Wyschogrod et al. | Aug 2004 | A1 |
20040177319 | Horn | Sep 2004 | A1 |
20040267732 | Luk et al. | Dec 2004 | A1 |
20050050260 | Schacham et al. | Mar 2005 | A1 |
20050114306 | Shu et al. | May 2005 | A1 |
20060059196 | Sato et al. | Mar 2006 | A1 |
20060259508 | Sikdar et al. | Nov 2006 | A1 |
20070011734 | Balakrishnan et al. | Jan 2007 | A1 |
20070027867 | Ichino | Feb 2007 | A1 |
20070055662 | Edelman et al. | Mar 2007 | A1 |
20070130140 | Cytron et al. | Jun 2007 | A1 |
20080046423 | Khan Alicherry et al. | Feb 2008 | A1 |
20080071781 | Ninan et al. | Mar 2008 | A1 |
Number | Date | Country |
---|---|---|
0408188 | Jan 1991 | EP |
Number | Date | Country | |
---|---|---|---|
60885607 | Jan 2007 | US |