Add prompt layout caching to layout_cache_t

This commit is contained in:
ridiculousfish 2018-02-04 15:43:03 -08:00
parent d1436486e2
commit 1bd5946d23
3 changed files with 51 additions and 2 deletions

View file

@ -4332,8 +4332,10 @@ void test_maybe() {
do_test(m2.missing_or_empty());
}
void test_cached_esc_sequences() {
void test_layout_cache() {
layout_cache_t seqs;
// Verify escape code cache.
do_test(seqs.find_escape_code(L"abc") == 0);
seqs.add_escape_code(L"abc");
seqs.add_escape_code(L"abc");
@ -4354,6 +4356,24 @@ void test_cached_esc_sequences() {
seqs.clear();
do_test(seqs.esc_cache_size() == 0);
do_test(seqs.find_escape_code(L"abcd") == 0);
// Verify prompt layout cache.
for (size_t i = 0; i < layout_cache_t::prompt_cache_max_size; i++) {
wcstring input = std::to_wstring(i);
do_test(!seqs.find_prompt_layout(input));
seqs.add_prompt_layout(input, {i});
do_test(seqs.find_prompt_layout(input)->line_count == i);
}
size_t expected_evictee = 3;
for (size_t i = 0; i < layout_cache_t::prompt_cache_max_size; i++) {
if (i != expected_evictee)
do_test(seqs.find_prompt_layout(std::to_wstring(i))->line_count == i);
}
seqs.add_prompt_layout(L"whatever", {100});
do_test(!seqs.find_prompt_layout(std::to_wstring(expected_evictee)));
do_test(seqs.find_prompt_layout(L"whatever")->line_count == 100);
}
/// Main test.
@ -4452,7 +4472,7 @@ int main(int argc, char **argv) {
if (should_test_function("string")) test_string();
if (should_test_function("illegal_command_exit_code")) test_illegal_command_exit_code();
if (should_test_function("maybe")) test_maybe();
if (should_test_function("cached_esc_sequences")) test_cached_esc_sequences();
if (should_test_function("layout_cache")) test_layout_cache();
// history_tests_t::test_history_speed();
say(L"Encountered %d errors in low-level tests", err_count);

View file

@ -283,6 +283,27 @@ size_t escape_code_length(const wchar_t *code) {
return esc_seq_len;
}
maybe_t<prompt_layout_t> layout_cache_t::find_prompt_layout(const wcstring &input) {
auto start = prompt_cache_.begin();
auto end = prompt_cache_.end();
for (auto iter = start; iter != end; ++iter) {
if (iter->first == input) {
// Found it. Move it to the front if not already there.
if (iter != start) prompt_cache_.splice(start, prompt_cache_, iter);
return iter->second;
}
}
return none();
}
void layout_cache_t::add_prompt_layout(wcstring input, prompt_layout_t layout) {
assert(!find_prompt_layout(input) && "Should not have a prompt layout for this input");
prompt_cache_.emplace_front(std::move(input), std::move(layout));
if (prompt_cache_.size() > prompt_cache_max_size) {
prompt_cache_.pop_back();
}
}
// These are used by `calc_prompt_layout()` to avoid redundant calculations.
static const wchar_t *cached_left_prompt = wcsdup(L"");
static const wchar_t *cached_right_prompt = wcsdup(L"");

View file

@ -220,6 +220,8 @@ class layout_cache_t {
std::list<prompt_layout_pair_t> prompt_cache_;
public:
static constexpr size_t prompt_cache_max_size = 8;
/// \return the size of the escape code cache.
size_t esc_cache_size() const { return esc_cache_.size(); }
@ -246,6 +248,12 @@ class layout_cache_t {
return 0;
}
// Finds the layout for a prompt, promoting it to the front. Returns none() if not found.
maybe_t<prompt_layout_t> find_prompt_layout(const wcstring &input);
// Adds a prompt layout for a given string.
void add_prompt_layout(wcstring input, prompt_layout_t layout);
void clear() {
esc_cache_.clear();
prompt_cache_.clear();