#include "cached_shortest_sequences.h" #include "find_shortest_sequences.h" #include "try_split_sequence.h" #include "segmented_sequences.h" #include std::shared_ptr CachedShortestSequences::Find( std::string_view code, std::function(char, char)> apply_cmd) { std::string cache_key(code.data(), code.size()); auto cache_iter = cache_.find(cache_key); if (cache_iter != cache_.end()) { return cache_iter->second; } auto maybe_split = TrySplitSequence(code); if (!maybe_split) { auto result_strs = FindShortestSequences(code, apply_cmd); std::vector> segmented_sequences_leaves; for (auto &result_str : result_strs) { segmented_sequences_leaves.emplace_back( std::make_shared( std::make_shared(std::move(result_str)))); } auto segmented_sequences_alts = std::make_shared( segmented_sequences_leaves); cache_.emplace(cache_key, segmented_sequences_alts); return segmented_sequences_alts; } auto segmented_sequences_product = std::make_shared( Find(maybe_split->first, apply_cmd), Find(maybe_split->second, apply_cmd)); cache_.emplace(cache_key, segmented_sequences_product); return segmented_sequences_product; } std::shared_ptr CachedShortestSequences::Find( std::shared_ptr codes, std::function(char, char)> apply_cmd) { auto segmented_cache_iter = segmented_cache_.find(codes.get()); if (segmented_cache_iter != segmented_cache_.end()) { return segmented_cache_iter->second; } auto leaf = std::dynamic_pointer_cast(codes); if (leaf != nullptr) { auto leaf_result = Find(leaf->sequence(), apply_cmd); segmented_cache_.emplace(codes.get(), leaf_result); return leaf_result; } auto alts = std::dynamic_pointer_cast(codes); if (alts != nullptr) { std::vector> alts_results; for (auto alt : alts->alternatives()) { alts_results.emplace_back(Find(alt, apply_cmd)); } auto alt_result = std::make_shared( std::move(alts_results)); segmented_cache_.emplace(codes.get(), alt_result); return alt_result; } auto product = std::dynamic_pointer_cast(codes); if (product != nullptr) { auto product_result = std::make_shared( Find(product->a(), apply_cmd), Find(product->b(), apply_cmd)); segmented_cache_.emplace(codes.get(), product_result); return product_result; } return nullptr; }