mirror of
https://github.com/neovim/neovim.git
synced 2025-09-11 13:58:18 +00:00
shada: Use hash for searching for history entries
This commit is contained in:
@@ -350,6 +350,8 @@ typedef struct hm_llist_entry {
|
|||||||
struct hm_llist_entry *prev; ///< Pointer to previous entry or NULL.
|
struct hm_llist_entry *prev; ///< Pointer to previous entry or NULL.
|
||||||
} HMLListEntry;
|
} HMLListEntry;
|
||||||
|
|
||||||
|
KHASH_MAP_INIT_STR(hmll_entries, HMLListEntry *)
|
||||||
|
|
||||||
/// Sized linked list structure for history merger
|
/// Sized linked list structure for history merger
|
||||||
typedef struct {
|
typedef struct {
|
||||||
HMLListEntry *entries; ///< Pointer to the start of the allocated array of
|
HMLListEntry *entries; ///< Pointer to the start of the allocated array of
|
||||||
@@ -362,6 +364,9 @@ typedef struct {
|
|||||||
size_t size; ///< Number of allocated entries.
|
size_t size; ///< Number of allocated entries.
|
||||||
size_t free_entries_size; ///< Number of non-NULL entries in free_entries.
|
size_t free_entries_size; ///< Number of non-NULL entries in free_entries.
|
||||||
size_t num_entries; ///< Number of entries already used.
|
size_t num_entries; ///< Number of entries already used.
|
||||||
|
khash_t(hmll_entries) contained_entries; ///< Hash mapping all history entry
|
||||||
|
///< strings to corresponding entry
|
||||||
|
///< pointers.
|
||||||
} HMLList;
|
} HMLList;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@@ -480,6 +485,7 @@ static inline void hmll_init(HMLList *const hmll, const size_t size)
|
|||||||
.size = size,
|
.size = size,
|
||||||
.free_entries_size = 0,
|
.free_entries_size = 0,
|
||||||
.num_entries = 0,
|
.num_entries = 0,
|
||||||
|
.contained_entries = KHASH_EMPTY_TABLE(hmll_entries),
|
||||||
};
|
};
|
||||||
hmll->last_free_element = hmll->entries;
|
hmll->last_free_element = hmll->entries;
|
||||||
}
|
}
|
||||||
@@ -512,6 +518,10 @@ static inline void hmll_remove(HMLList *const hmll,
|
|||||||
} else {
|
} else {
|
||||||
hmll->free_entries[hmll->free_entries_size++] = hmll_entry;
|
hmll->free_entries[hmll->free_entries_size++] = hmll_entry;
|
||||||
}
|
}
|
||||||
|
const khiter_t k = kh_get(hmll_entries, &hmll->contained_entries,
|
||||||
|
hmll_entry->data.data.history_item.string);
|
||||||
|
assert(k != kh_end(&hmll->contained_entries));
|
||||||
|
kh_del(hmll_entries, &hmll->contained_entries, k);
|
||||||
if (hmll_entry->next == NULL) {
|
if (hmll_entry->next == NULL) {
|
||||||
hmll->last = hmll_entry->prev;
|
hmll->last = hmll_entry->prev;
|
||||||
} else {
|
} else {
|
||||||
@@ -558,6 +568,12 @@ static inline void hmll_insert(HMLList *const hmll,
|
|||||||
}
|
}
|
||||||
target_entry->data = data;
|
target_entry->data = data;
|
||||||
target_entry->can_free_entry = can_free_entry;
|
target_entry->can_free_entry = can_free_entry;
|
||||||
|
int kh_ret;
|
||||||
|
const khiter_t k = kh_put(hmll_entries, &hmll->contained_entries,
|
||||||
|
data.data.history_item.string, &kh_ret);
|
||||||
|
if (kh_ret > 0) {
|
||||||
|
kh_val(&hmll->contained_entries, k) = target_entry;
|
||||||
|
}
|
||||||
hmll->num_entries++;
|
hmll->num_entries++;
|
||||||
target_entry->prev = hmll_entry;
|
target_entry->prev = hmll_entry;
|
||||||
if (hmll_entry == NULL) {
|
if (hmll_entry == NULL) {
|
||||||
@@ -591,6 +607,7 @@ static inline void hmll_insert(HMLList *const hmll,
|
|||||||
static inline void hmll_dealloc(HMLList *const hmll)
|
static inline void hmll_dealloc(HMLList *const hmll)
|
||||||
FUNC_ATTR_NONNULL_ALL
|
FUNC_ATTR_NONNULL_ALL
|
||||||
{
|
{
|
||||||
|
kh_dealloc(hmll_entries, &hmll->contained_entries);
|
||||||
xfree(hmll->entries);
|
xfree(hmll->entries);
|
||||||
xfree(hmll->free_entries);
|
xfree(hmll->free_entries);
|
||||||
}
|
}
|
||||||
@@ -985,14 +1002,14 @@ static void hms_insert(HistoryMergerState *const hms_p, const ShadaEntry entry,
|
|||||||
const bool no_iter, const bool can_free_entry)
|
const bool no_iter, const bool can_free_entry)
|
||||||
{
|
{
|
||||||
HMLList *const hmll = &hms_p->hmll;
|
HMLList *const hmll = &hms_p->hmll;
|
||||||
HMLL_FORALL(hmll, cur_entry) {
|
const khiter_t k = kh_get(hmll_entries, &hms_p->hmll.contained_entries,
|
||||||
if (STRCMP(cur_entry->data.data.history_item.string,
|
entry.data.history_item.string);
|
||||||
entry.data.history_item.string) == 0) {
|
if (k != kh_end(&hmll->contained_entries)) {
|
||||||
if (entry.timestamp > cur_entry->data.timestamp) {
|
HMLListEntry *const cur_entry = kh_val(&hmll->contained_entries, k);
|
||||||
hmll_remove(hmll, cur_entry);
|
if (entry.timestamp > cur_entry->data.timestamp) {
|
||||||
} else {
|
hmll_remove(hmll, cur_entry);
|
||||||
return;
|
} else {
|
||||||
}
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!no_iter) {
|
if (!no_iter) {
|
||||||
|
Reference in New Issue
Block a user