char-fork/llama.cpp
git clone https://git.t4t.associates/char-fork/llama.cpp
910196f6b
char/aliceai-t5-moe
1#include "trie.h" 2 3#include "unicode.h" 4 5#include <deque> 6 7common_trie::match_result common_trie::check_at (std::string_view sv ,size_t start_pos )const { 8size_t current = 0 ;// Start at root 9size_t pos = start_pos ; 10 11// LOG_DBG("%s: checking at pos %zu, sv='%s'\n", __func__, start_pos, std::string(sv).c_str()); 12 13while (pos < sv .size ()) { 14auto result = common_parse_utf8_codepoint (sv ,pos ); 15if (result .status != utf8_parse_result::SUCCESS ) { 16break ; 17 } 18 19auto it = nodes [current ].children .find (result .codepoint ); 20if (it == nodes [current ].children .end ()) { 21// Can't continue matching 22return match_result {match_result::NO_MATCH }; 23 } 24 25current = it -> second ; 26pos += result .bytes_consumed ; 27 28// Check if we've matched a complete word 29if (nodes [current ].pattern >=0 ) { 30return match_result {match_result::COMPLETE_MATCH }; 31 } 32 } 33 34// Reached end of input while still in the trie (not at root) 35if (current != 0 ) { 36// We're in the middle of a potential match 37return match_result {match_result::PARTIAL_MATCH }; 38 } 39 40// Reached end at root (no match) 41return match_result {match_result::NO_MATCH }; 42} 43 44int32_t common_trie::insert (const std::string & word ) { 45 std::vector < uint32_t > symbols ; 46size_t pos = 0 ; 47while (pos < word .length ()) { 48auto result = common_parse_utf8_codepoint (word ,pos ); 49if (result .status != utf8_parse_result::SUCCESS ) { 50break ; 51 } 52 53symbols .push_back (result .codepoint ); 54pos += result .bytes_consumed ; 55 } 56return insert (symbols ); 57} 58 59int32_t common_trie::insert (const std::vector < uint32_t > & symbols ) { 60size_t current = 0 ; 61for (uint32_t ch :symbols ) { 62auto it = nodes [current ].children .find (ch ); 63if (it == nodes [current ].children .end ()) { 64size_t child = create_node (); 65nodes [current ].children [ch ]= child ; 66current = child ; 67 }else { 68current = it -> second ; 69 } 70 } 71if (nodes [current ].pattern < 0 ) { 72nodes [current ].pattern = n_patterns ++ ; 73 } 74return nodes [current ].pattern ; 75} 76 77common_aho_corasick::common_aho_corasick (common_trie trie ) :t (std::move (trie )) { 78const auto & nodes = t .nodes ; 79const size_t n = nodes .size (); 80 81fail .assign (n ,0 ); 82order .reserve (n ); 83 84 std::deque < size_t > queue {0 }; 85while (!queue .empty ()) { 86size_t u = queue .front (); 87queue .pop_front (); 88order .push_back (u ); 89for (const auto & [ch ,v ] :nodes [u ].children ) { 90if (u != 0 ) { 91size_t f = fail [u ]; 92while (f && nodes [f ].children .find (ch )== nodes [f ].children .end ()) { 93f = fail [f ]; 94 } 95auto it = nodes [f ].children .find (ch ); 96fail [v ]= (it != nodes [f ].children .end ()&& it -> second != v ) ?it -> second :0 ; 97 } 98queue .push_back (v ); 99 } 100 } 101 102// fail[u] points to a strictly shorter suffix, so the first pattern found on 103// the fail chain (including u itself) is the longest pattern ending at u 104match .assign (n ,-1 ); 105for (size_t u :order ) { 106match [u ]= nodes [u ].pattern >=0 ?nodes [u ].pattern : (u != 0 ?match [fail [u ]] :-1 ); 107 } 108 109for (const auto & node :nodes ) { 110for (const auto & [ch ,v ] :node .children ) { 111alphabet .insert (ch ); 112 } 113 } 114} 115 116size_t common_aho_corasick::next (size_t state ,uint32_t ch )const { 117const auto & nodes = t .nodes ; 118while (state && nodes [state ].children .find (ch )== nodes [state ].children .end ()) { 119state = fail [state ]; 120 } 121auto it = nodes [state ].children .find (ch ); 122return it != nodes [state ].children .end () ?it -> second :0 ; 123}