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 #ifndef FISH_LRU_H
#define FISH_LRU_H #define FISH_LRU_H
#include <assert.h> #include <assert.h>
#include <wchar.h> #include <wchar.h>
#include <list>
#include <map> #include <map>
#include <set> #include <set>
#include <list>
#include "common.h" #include "common.h"
/** A predicate to compare dereferenced pointers */ /// A predicate to compare dereferenced pointers.
struct dereference_less_t struct dereference_less_t {
{
template <typename ptr_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; return *p1 < *p2;
} }
}; };
class lru_node_t class lru_node_t {
{ template <class T>
template<class T> friend class lru_cache_t; friend class lru_cache_t;
/** Our linked list pointer */ /// Our linked list pointer.
lru_node_t *prev, *next; lru_node_t *prev, *next;
public: public:
/** The key used to look up in the cache */ /// The key used to look up in the cache.
const wcstring key; const wcstring key;
/** Constructor */ /// Constructor.
explicit lru_node_t(const wcstring &pkey) : prev(NULL), next(NULL), key(pkey) { } 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() {} virtual ~lru_node_t() {}
/** operator< for std::set */ /// operator< for std::set
bool operator<(const lru_node_t &other) const bool operator<(const lru_node_t &other) const { return key < other.key; }
{
return key < other.key;
}
}; };
template<class node_type_t> template <class node_type_t>
class lru_cache_t class lru_cache_t {
{ private:
private: /// Max node count. This may be (transiently) exceeded by add_node_without_eviction, which is
/// used from background threads.
/** 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; const size_t max_node_count;
/** Count of nodes */ /// Count of nodes.
size_t node_count; size_t node_count;
/** The set of nodes */ /// The set of nodes.
typedef std::set<lru_node_t *, dereference_less_t> node_set_t; typedef std::set<lru_node_t *, dereference_less_t> node_set_t;
node_set_t node_set; node_set_t node_set;
void promote_node(node_type_t *node) void promote_node(node_type_t *node) {
{ // We should never promote the mouth.
/* We should never promote the mouth */
assert(node != &mouth); assert(node != &mouth);
/* First unhook us */ // First unhook us.
node->prev->next = node->next; node->prev->next = node->next;
node->next->prev = node->prev; node->next->prev = node->prev;
/* Put us after the mouth */ // Put us after the mouth.
node->next = mouth.next; node->next = mouth.next;
node->next->prev = node; node->next->prev = node;
node->prev = &mouth; node->prev = &mouth;
mouth.next = node; mouth.next = node;
} }
void evict_node(node_type_t *condemned_node) void evict_node(node_type_t *condemned_node) {
{ // We should never evict the mouth.
/* We should never evict the mouth */
assert(condemned_node != NULL && condemned_node != &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->prev->next = condemned_node->next;
condemned_node->next->prev = condemned_node->prev; condemned_node->next->prev = condemned_node->prev;
/* Remove us from the set */ // Remove us from the set.
node_set.erase(condemned_node); node_set.erase(condemned_node);
node_count--; node_count--;
/* Tell ourselves */ // Tell ourselves.
this->node_was_evicted(condemned_node); this->node_was_evicted(condemned_node);
} }
void evict_last_node(void) void evict_last_node(void) { evict_node((node_type_t *)mouth.prev); }
{
/* Simple */
evict_node((node_type_t *)mouth.prev);
}
static lru_node_t *get_previous(lru_node_t *node) static lru_node_t *get_previous(lru_node_t *node) { return node->prev; }
{
return node->prev;
}
protected: protected:
/// Head of the linked list.
/** Head of the linked list */
lru_node_t mouth; lru_node_t mouth;
/** Overridable callback for when a node is evicted */ /// Overridable callback for when a node is evicted.
virtual void node_was_evicted(node_type_t *node) { } virtual void node_was_evicted(node_type_t *node) {}
public: public:
/// Constructor
/** Constructor */ explicit lru_cache_t(size_t max_size = 1024)
explicit lru_cache_t(size_t max_size = 1024) : max_node_count(max_size), node_count(0), mouth(wcstring()) : max_node_count(max_size), node_count(0), mouth(wcstring()) {
{ // Hook up the mouth to itself: a one node circularly linked list!
/* Hook up the mouth to itself: a one node circularly linked list! */
mouth.prev = mouth.next = &mouth; 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). */ /// Note that we do not evict nodes in our destructor (even though they typically need to be
virtual ~lru_cache_t() { } /// deleted by their creator).
virtual ~lru_cache_t() {}
/// Returns the node for a given key, or NULL.
/** Returns the node for a given key, or NULL */ node_type_t *get_node(const wcstring &key) {
node_type_t *get_node(const wcstring &key)
{
node_type_t *result = NULL; 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); 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); node_set_t::iterator iter = node_set.find(&node_key);
/* If we found a node, promote and return it */ // If we found a node, promote and return it.
if (iter != node_set.end()) if (iter != node_set.end()) {
{ result = static_cast<node_type_t *>(*iter);
result = static_cast<node_type_t*>(*iter);
promote_node(result); promote_node(result);
} }
return result; return result;
} }
/** Evicts the node for a given key, returning true if a node was evicted. */ /// Evicts the node for a given key, returning true if a node was evicted.
bool evict_node(const wcstring &key) bool evict_node(const wcstring &key) {
{ // Construct a fake node as our key.
/* Construct a fake node as our key */
lru_node_t node_key(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); node_set_t::iterator iter = node_set.find(&node_key);
if (iter == node_set.end()) if (iter == node_set.end()) return false;
return false;
/* Evict the given node */ // Evict the given node.
evict_node(static_cast<node_type_t*>(*iter)); evict_node(static_cast<node_type_t *>(*iter));
return true; 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. */ /// Adds a node under the given key. Returns true if the node was added, false if the node was
bool add_node(node_type_t *node) /// not because a node with that key is already in the set.
{ bool add_node(node_type_t *node) {
/* Add our node without eviction */ // Add our node without eviction.
if (! this->add_node_without_eviction(node)) if (!this->add_node_without_eviction(node)) return false;
return false;
/* Evict */ while (node_count > max_node_count) evict_last_node(); // evict
while (node_count > max_node_count)
evict_last_node();
/* Success */
return true; 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. */ /// Adds a node under the given key without triggering eviction. Returns true if the node was
bool add_node_without_eviction(node_type_t *node) /// 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); assert(node != NULL && node != &mouth);
/* Try inserting; return false if it was already in the set */ // Try inserting; return false if it was already in the set.
if (! node_set.insert(node).second) if (!node_set.insert(node).second) return false;
return false;
/* Add the node after the mouth */ // Add the node after the mouth.
node->next = mouth.next; node->next = mouth.next;
node->next->prev = node; node->next->prev = node;
node->prev = &mouth; node->prev = &mouth;
mouth.next = node; 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++; node_count++;
/* Success */
return true; return true;
} }
/** Counts nodes */ /// Counts nodes.
size_t size(void) size_t size(void) { return node_count; }
{
return node_count;
}
/** Evicts all nodes */ /// Evicts all nodes.
void evict_all_nodes(void) void evict_all_nodes(void) {
{ while (node_count > 0) {
while (node_count > 0)
{
evict_last_node(); evict_last_node();
} }
} }
/** Iterator for walking nodes, from least recently used to most */ /// Iterator for walking nodes, from least recently used to most.
class iterator class iterator {
{
lru_node_t *node; lru_node_t *node;
public:
explicit iterator(lru_node_t *val) : node(val) { } public:
void operator++() explicit iterator(lru_node_t *val) : node(val) {}
{ void operator++() { node = lru_cache_t::get_previous(node); }
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; }
void operator++(int x) bool operator!=(const iterator &other) { return !(*this == other); }
{ node_type_t *operator*() { return static_cast<node_type_t *>(node); }
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() iterator begin() { return iterator(mouth.prev); }
{ iterator end() { return iterator(&mouth); }
return iterator(mouth.prev);
}
iterator end()
{
return iterator(&mouth);
}
}; };
#endif #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 #ifndef FISH_PAGER_H
#define FISH_PAGER_H #define FISH_PAGER_H
#include <stdbool.h>
#include <stddef.h> #include <stddef.h>
#include <memory>
#include <string> #include <string>
#include <vector> #include <vector>
#include <memory>
#include <stdbool.h>
#include "common.h" #include "common.h"
#include "complete.h" #include "complete.h"
#include "screen.h"
#include "reader.h" #include "reader.h"
#include "screen.h"
#define PAGER_SELECTION_NONE ((size_t)(-1)) #define PAGER_SELECTION_NONE ((size_t)(-1))
/* Represents rendering from the pager */ /// Represents rendering from the pager.
class page_rendering_t class page_rendering_t {
{ public:
public:
int term_width; int term_width;
int term_height; int term_height;
size_t rows; size_t rows;
@ -35,144 +32,148 @@ public:
bool search_field_shown; bool search_field_shown;
editable_line_t search_field_line; 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(); page_rendering_t();
}; };
/* The space between adjacent completions */ // The space between adjacent completions.
#define PAGER_SPACER_STRING L" " #define PAGER_SPACER_STRING L" "
#define PAGER_SPACER_STRING_WIDTH 2 #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 #define PAGER_UNDISCLOSED_MAX_ROWS 4
typedef std::vector<completion_t> completion_list_t; 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_width;
int available_term_height; int available_term_height;
size_t selected_completion_idx; size_t selected_completion_idx;
size_t suggested_row_start; size_t suggested_row_start;
/* Fully disclosed means that we show all completions */ // Fully disclosed means that we show all completions.
bool fully_disclosed; bool fully_disclosed;
/* Whether we show the search field */ // Whether we show the search field.
bool search_field_shown; 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; size_t visual_selected_completion_index(size_t rows, size_t cols) const;
/** Data structure describing one or a group of related completions */ public:
public: /// Data structure describing one or a group of related completions.
struct comp_t struct comp_t {
{ /// The list of all completin strings this entry applies to.
/** The list of all completin strings this entry applies to */
wcstring_list_t comp; wcstring_list_t comp;
/// The description.
/** The description */
wcstring desc; wcstring desc;
/// The representative completion.
/** The representative completion */
completion_t representative; completion_t representative;
/// On-screen width of the completion string.
/** On-screen width of the completion string */
int comp_width; int comp_width;
/// On-screen width of the description information.
/** On-screen width of the description information */
int desc_width; int desc_width;
/// Preferred total width.
/** Preferred total width */
int pref_width; int pref_width;
/// Minimum acceptable width.
/** Minimum acceptable width */
int min_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; 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; 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; comp_info_list_t unfiltered_completion_infos;
wcstring prefix; 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; void measure_completion_infos(std::vector<comp_t> *infos, const wcstring &prefix) const;
bool completion_info_passes_filter(const comp_t &info) 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; void completion_print(size_t cols, int *width_per_column, size_t row_start, size_t row_stop,
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; 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:
public: // The text of the search field.
/* The text of the search field */
editable_line_t search_field_line; editable_line_t search_field_line;
/* Sets the set of completions */ // Sets the set of completions.
void set_completions(const completion_list_t &comp); void set_completions(const completion_list_t &comp);
/* Sets the prefix */ // Sets the prefix.
void set_prefix(const wcstring &pref); 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); 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. */ // Changes the selected completion in the given direction according to the layout of the given
bool select_next_completion_in_direction(selection_direction_t direction, const page_rendering_t &rendering); // 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; 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_row(const page_rendering_t &rendering) const;
size_t get_selected_column(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; 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; 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; bool empty() const;
/* Clears all completions and the prefix */ // Clears all completions and the prefix.
void clear(); void clear();
/* Updates the completions list per the filter */ // Updates the completions list per the filter.
void refilter_completions(); void refilter_completions();
/* Sets whether the search field is shown */ // Sets whether the search field is shown.
void set_search_field_shown(bool flag); 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; 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; bool is_navigating_contents() const;
/* Become fully disclosed */ // Become fully disclosed.
void set_fully_disclosed(bool flag); void set_fully_disclosed(bool flag);
/* Position of the cursor */ // Position of the cursor.
size_t cursor_position() const; size_t cursor_position() const;
/* Constructor */ // Constructor
pager_t(); pager_t();
}; };