restyle pager & lru module to match project style

Reduces lint errors from 65 to 25 (-63%). Line count from 1439 to 1218 (-15%).

Another step in resolving issue #2902.
This commit is contained in:
Kurtis Rader 2016-05-02 11:54:01 -07:00
parent ed8d1040ba
commit 13d7432368
3 changed files with 541 additions and 762 deletions

239
src/lru.h
View File

@ -1,257 +1,198 @@
/** \file lru.h
Least-recently-used cache implementation
*/
// Least-recently-used cache implementation.
#ifndef FISH_LRU_H
#define FISH_LRU_H
#include <assert.h>
#include <wchar.h>
#include <list>
#include <map>
#include <set>
#include <list>
#include "common.h"
/** A predicate to compare dereferenced pointers */
struct dereference_less_t
{
/// A predicate to compare dereferenced pointers.
struct dereference_less_t {
template <typename ptr_t>
bool operator()(ptr_t p1, ptr_t p2) const
{
bool operator()(ptr_t p1, ptr_t p2) const {
return *p1 < *p2;
}
};
class lru_node_t
{
template<class T> friend class lru_cache_t;
class lru_node_t {
template <class T>
friend class lru_cache_t;
/** Our linked list pointer */
/// Our linked list pointer.
lru_node_t *prev, *next;
public:
/** The key used to look up in the cache */
public:
/// The key used to look up in the cache.
const wcstring key;
/** Constructor */
explicit lru_node_t(const wcstring &pkey) : prev(NULL), next(NULL), key(pkey) { }
/// Constructor.
explicit lru_node_t(const wcstring &pkey) : prev(NULL), next(NULL), key(pkey) {}
/** Virtual destructor that does nothing for classes that inherit lru_node_t */
/// Virtual destructor that does nothing for classes that inherit lru_node_t.
virtual ~lru_node_t() {}
/** operator< for std::set */
bool operator<(const lru_node_t &other) const
{
return key < other.key;
}
/// operator< for std::set
bool operator<(const lru_node_t &other) const { return key < other.key; }
};
template<class node_type_t>
class lru_cache_t
{
private:
/** Max node count. This may be (transiently) exceeded by add_node_without_eviction, which is used from background threads. */
template <class node_type_t>
class lru_cache_t {
private:
/// Max node count. This may be (transiently) exceeded by add_node_without_eviction, which is
/// used from background threads.
const size_t max_node_count;
/** Count of nodes */
/// Count of nodes.
size_t node_count;
/** The set of nodes */
/// The set of nodes.
typedef std::set<lru_node_t *, dereference_less_t> node_set_t;
node_set_t node_set;
void promote_node(node_type_t *node)
{
/* We should never promote the mouth */
void promote_node(node_type_t *node) {
// We should never promote the mouth.
assert(node != &mouth);
/* First unhook us */
// First unhook us.
node->prev->next = node->next;
node->next->prev = node->prev;
/* Put us after the mouth */
// Put us after the mouth.
node->next = mouth.next;
node->next->prev = node;
node->prev = &mouth;
mouth.next = node;
}
void evict_node(node_type_t *condemned_node)
{
/* We should never evict the mouth */
void evict_node(node_type_t *condemned_node) {
// We should never evict the mouth.
assert(condemned_node != NULL && condemned_node != &mouth);
/* Remove it from the linked list */
// Remove it from the linked list.
condemned_node->prev->next = condemned_node->next;
condemned_node->next->prev = condemned_node->prev;
/* Remove us from the set */
// Remove us from the set.
node_set.erase(condemned_node);
node_count--;
/* Tell ourselves */
// Tell ourselves.
this->node_was_evicted(condemned_node);
}
void evict_last_node(void)
{
/* Simple */
evict_node((node_type_t *)mouth.prev);
}
void evict_last_node(void) { evict_node((node_type_t *)mouth.prev); }
static lru_node_t *get_previous(lru_node_t *node)
{
return node->prev;
}
static lru_node_t *get_previous(lru_node_t *node) { return node->prev; }
protected:
/** Head of the linked list */
protected:
/// Head of the linked list.
lru_node_t mouth;
/** Overridable callback for when a node is evicted */
virtual void node_was_evicted(node_type_t *node) { }
/// Overridable callback for when a node is evicted.
virtual void node_was_evicted(node_type_t *node) {}
public:
/** Constructor */
explicit lru_cache_t(size_t max_size = 1024) : max_node_count(max_size), node_count(0), mouth(wcstring())
{
/* Hook up the mouth to itself: a one node circularly linked list! */
public:
/// Constructor
explicit lru_cache_t(size_t max_size = 1024)
: max_node_count(max_size), node_count(0), mouth(wcstring()) {
// Hook up the mouth to itself: a one node circularly linked list!
mouth.prev = mouth.next = &mouth;
}
/** Note that we do not evict nodes in our destructor (even though they typically need to be deleted by their creator). */
virtual ~lru_cache_t() { }
/// Note that we do not evict nodes in our destructor (even though they typically need to be
/// deleted by their creator).
virtual ~lru_cache_t() {}
/** Returns the node for a given key, or NULL */
node_type_t *get_node(const wcstring &key)
{
/// Returns the node for a given key, or NULL.
node_type_t *get_node(const wcstring &key) {
node_type_t *result = NULL;
/* Construct a fake node as our key */
// Construct a fake node as our key.
lru_node_t node_key(key);
/* Look for it in the set */
// Look for it in the set.
node_set_t::iterator iter = node_set.find(&node_key);
/* If we found a node, promote and return it */
if (iter != node_set.end())
{
result = static_cast<node_type_t*>(*iter);
// If we found a node, promote and return it.
if (iter != node_set.end()) {
result = static_cast<node_type_t *>(*iter);
promote_node(result);
}
return result;
}
/** Evicts the node for a given key, returning true if a node was evicted. */
bool evict_node(const wcstring &key)
{
/* Construct a fake node as our key */
/// Evicts the node for a given key, returning true if a node was evicted.
bool evict_node(const wcstring &key) {
// Construct a fake node as our key.
lru_node_t node_key(key);
/* Look for it in the set */
// Look for it in the set.
node_set_t::iterator iter = node_set.find(&node_key);
if (iter == node_set.end())
return false;
if (iter == node_set.end()) return false;
/* Evict the given node */
evict_node(static_cast<node_type_t*>(*iter));
// Evict the given node.
evict_node(static_cast<node_type_t *>(*iter));
return true;
}
/** Adds a node under the given key. Returns true if the node was added, false if the node was not because a node with that key is already in the set. */
bool add_node(node_type_t *node)
{
/* Add our node without eviction */
if (! this->add_node_without_eviction(node))
return false;
/// Adds a node under the given key. Returns true if the node was added, false if the node was
/// not because a node with that key is already in the set.
bool add_node(node_type_t *node) {
// Add our node without eviction.
if (!this->add_node_without_eviction(node)) return false;
/* Evict */
while (node_count > max_node_count)
evict_last_node();
/* Success */
while (node_count > max_node_count) evict_last_node(); // evict
return true;
}
/** Adds a node under the given key without triggering eviction. Returns true if the node was added, false if the node was not because a node with that key is already in the set. */
bool add_node_without_eviction(node_type_t *node)
{
/// Adds a node under the given key without triggering eviction. Returns true if the node was
/// added, false if the node was not because a node with that key is already in the set.
bool add_node_without_eviction(node_type_t *node) {
assert(node != NULL && node != &mouth);
/* Try inserting; return false if it was already in the set */
if (! node_set.insert(node).second)
return false;
// Try inserting; return false if it was already in the set.
if (!node_set.insert(node).second) return false;
/* Add the node after the mouth */
// Add the node after the mouth.
node->next = mouth.next;
node->next->prev = node;
node->prev = &mouth;
mouth.next = node;
/* Update the count. This may push us over the maximum node count. */
// Update the count. This may push us over the maximum node count.
node_count++;
/* Success */
return true;
}
/** Counts nodes */
size_t size(void)
{
return node_count;
}
/// Counts nodes.
size_t size(void) { return node_count; }
/** Evicts all nodes */
void evict_all_nodes(void)
{
while (node_count > 0)
{
/// Evicts all nodes.
void evict_all_nodes(void) {
while (node_count > 0) {
evict_last_node();
}
}
/** Iterator for walking nodes, from least recently used to most */
class iterator
{
/// Iterator for walking nodes, from least recently used to most.
class iterator {
lru_node_t *node;
public:
explicit iterator(lru_node_t *val) : node(val) { }
void operator++()
{
node = lru_cache_t::get_previous(node);
}
void operator++(int x)
{
node = lru_cache_t::get_previous(node);
}
bool operator==(const iterator &other)
{
return node == other.node;
}
bool operator!=(const iterator &other)
{
return !(*this == other);
}
node_type_t *operator*()
{
return static_cast<node_type_t *>(node);
}
public:
explicit iterator(lru_node_t *val) : node(val) {}
void operator++() { node = lru_cache_t::get_previous(node); }
void operator++(int x) { node = lru_cache_t::get_previous(node); }
bool operator==(const iterator &other) { return node == other.node; }
bool operator!=(const iterator &other) { return !(*this == other); }
node_type_t *operator*() { return static_cast<node_type_t *>(node); }
};
iterator begin()
{
return iterator(mouth.prev);
}
iterator end()
{
return iterator(&mouth);
}
iterator begin() { return iterator(mouth.prev); }
iterator end() { return iterator(&mouth); }
};
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1,26 +1,23 @@
/** \file pager.h
Pager support
*/
// Pager support.
#ifndef FISH_PAGER_H
#define FISH_PAGER_H
#include <stdbool.h>
#include <stddef.h>
#include <memory>
#include <string>
#include <vector>
#include <memory>
#include <stdbool.h>
#include "common.h"
#include "complete.h"
#include "screen.h"
#include "reader.h"
#include "screen.h"
#define PAGER_SELECTION_NONE ((size_t)(-1))
/* Represents rendering from the pager */
class page_rendering_t
{
public:
/// Represents rendering from the pager.
class page_rendering_t {
public:
int term_width;
int term_height;
size_t rows;
@ -35,144 +32,148 @@ public:
bool search_field_shown;
editable_line_t search_field_line;
/* Returns a rendering with invalid data, useful to indicate "no rendering" */
// Returns a rendering with invalid data, useful to indicate "no rendering".
page_rendering_t();
};
/* The space between adjacent completions */
// The space between adjacent completions.
#define PAGER_SPACER_STRING L" "
#define PAGER_SPACER_STRING_WIDTH 2
/* How many rows we will show in the "initial" pager */
// How many rows we will show in the "initial" pager.
#define PAGER_UNDISCLOSED_MAX_ROWS 4
typedef std::vector<completion_t> completion_list_t;
page_rendering_t render_completions(const completion_list_t &raw_completions, const wcstring &prefix);
page_rendering_t render_completions(const completion_list_t &raw_completions,
const wcstring &prefix);
class pager_t
{
class pager_t {
int available_term_width;
int available_term_height;
size_t selected_completion_idx;
size_t suggested_row_start;
/* Fully disclosed means that we show all completions */
// Fully disclosed means that we show all completions.
bool fully_disclosed;
/* Whether we show the search field */
// Whether we show the search field.
bool search_field_shown;
/* Returns the index of the completion that should draw selected, using the given number of columns */
// Returns the index of the completion that should draw selected, using the given number of
// columns.
size_t visual_selected_completion_index(size_t rows, size_t cols) const;
/** Data structure describing one or a group of related completions */
public:
struct comp_t
{
/** The list of all completin strings this entry applies to */
public:
/// Data structure describing one or a group of related completions.
struct comp_t {
/// The list of all completin strings this entry applies to.
wcstring_list_t comp;
/** The description */
/// The description.
wcstring desc;
/** The representative completion */
/// The representative completion.
completion_t representative;
/** On-screen width of the completion string */
/// On-screen width of the completion string.
int comp_width;
/** On-screen width of the description information */
/// On-screen width of the description information.
int desc_width;
/** Preferred total width */
/// Preferred total width.
int pref_width;
/** Minimum acceptable width */
/// Minimum acceptable width.
int min_width;
comp_t() : comp(), desc(), representative(L""), comp_width(0), desc_width(0), pref_width(0), min_width(0)
{
}
comp_t()
: comp(),
desc(),
representative(L""),
comp_width(0),
desc_width(0),
pref_width(0),
min_width(0) {}
};
private:
private:
typedef std::vector<comp_t> comp_info_list_t;
/* The filtered list of completion infos */
// The filtered list of completion infos.
comp_info_list_t completion_infos;
/* The unfiltered list. Note there's a lot of duplication here. */
// The unfiltered list. Note there's a lot of duplication here.
comp_info_list_t unfiltered_completion_infos;
wcstring prefix;
bool completion_try_print(size_t cols, const wcstring &prefix, const comp_info_list_t &lst, page_rendering_t *rendering, size_t suggested_start_row) const;
bool completion_try_print(size_t cols, const wcstring &prefix, const comp_info_list_t &lst,
page_rendering_t *rendering, size_t suggested_start_row) const;
void recalc_min_widths(comp_info_list_t * lst) const;
void recalc_min_widths(comp_info_list_t *lst) const;
void measure_completion_infos(std::vector<comp_t> *infos, const wcstring &prefix) const;
bool completion_info_passes_filter(const comp_t &info) const;
void completion_print(size_t cols, int *width_per_column, size_t row_start, size_t row_stop, const wcstring &prefix, const comp_info_list_t &lst, page_rendering_t *rendering) const;
line_t completion_print_item(const wcstring &prefix, const comp_t *c, size_t row, size_t column, int width, bool secondary, bool selected, page_rendering_t *rendering) const;
void completion_print(size_t cols, int *width_per_column, size_t row_start, size_t row_stop,
const wcstring &prefix, const comp_info_list_t &lst,
page_rendering_t *rendering) const;
line_t completion_print_item(const wcstring &prefix, const comp_t *c, size_t row, size_t column,
int width, bool secondary, bool selected,
page_rendering_t *rendering) const;
public:
/* The text of the search field */
public:
// The text of the search field.
editable_line_t search_field_line;
/* Sets the set of completions */
// Sets the set of completions.
void set_completions(const completion_list_t &comp);
/* Sets the prefix */
// Sets the prefix.
void set_prefix(const wcstring &pref);
/* Sets the terminal width and height */
// Sets the terminal width and height.
void set_term_size(int w, int h);
/* Changes the selected completion in the given direction according to the layout of the given rendering. Returns true if the selection changed. */
bool select_next_completion_in_direction(selection_direction_t direction, const page_rendering_t &rendering);
// Changes the selected completion in the given direction according to the layout of the given
// rendering. Returns true if the selection changed.
bool select_next_completion_in_direction(selection_direction_t direction,
const page_rendering_t &rendering);
/* Returns the currently selected completion for the given rendering */
// Returns the currently selected completion for the given rendering.
const completion_t *selected_completion(const page_rendering_t &rendering) const;
/* Indicates the row and column for the given rendering. Returns -1 if no selection. */
// Indicates the row and column for the given rendering. Returns -1 if no selection.
size_t get_selected_row(const page_rendering_t &rendering) const;
size_t get_selected_column(const page_rendering_t &rendering) const;
/* Produces a rendering of the completions, at the given term size */
// Produces a rendering of the completions, at the given term size.
page_rendering_t render() const;
/* Updates the rendering if it's stale */
// Updates the rendering if it's stale.
void update_rendering(page_rendering_t *rendering) const;
/* Indicates if there are no completions, and therefore nothing to render */
// Indicates if there are no completions, and therefore nothing to render.
bool empty() const;
/* Clears all completions and the prefix */
// Clears all completions and the prefix.
void clear();
/* Updates the completions list per the filter */
// Updates the completions list per the filter.
void refilter_completions();
/* Sets whether the search field is shown */
// Sets whether the search field is shown.
void set_search_field_shown(bool flag);
/* Gets whether the search field shown */
// Gets whether the search field shown.
bool is_search_field_shown() const;
/* Indicates if we are navigating our contents */
// Indicates if we are navigating our contents.
bool is_navigating_contents() const;
/* Become fully disclosed */
// Become fully disclosed.
void set_fully_disclosed(bool flag);
/* Position of the cursor */
// Position of the cursor.
size_t cursor_position() const;
/* Constructor */
// Constructor
pager_t();
};