23 #ifndef _LOCKFREE_HASHMAP_HPP_ 24 #define _LOCKFREE_HASHMAP_HPP_ 41 template <
class Key,
class T>
50 void init (
tran::system &transys,
size_t hash_size,
size_t freelist_block_size,
size_t freelist_block_count,
124 void *
volatile *
get_ref (T *
p,
size_t offset);
125 void *
get_ptr (T *
p,
size_t offset);
155 void list_find (
tran::index tran_index, T *list_head, Key &key,
int *behavior_flags, T *&found_node);
163 template <
typename D>
168 return ((
char *) (&fn.get_data ().m_entry)) - ((
char *) (&fn));
172 template <
class Key,
class T>
202 template <
class Key,
class T>
222 template <
class Key,
class T>
228 template <
class Key,
class T>
240 for (node_iter =
m_buckets[
i]; node_iter !=
NULL; node_iter = save_next)
258 template <
class Key,
class T>
277 template <
class Key,
class T>
292 list_find (tran_index, list_head, key, &bflags, entry);
298 template <
class Key,
class T>
305 template <
class Key,
class T>
312 template <
class Key,
class T>
322 template <
class Key,
class T>
342 template <
class Key,
class T>
357 template <
class Key,
class T>
375 template <
class Key,
class T>
404 pthread_mutex_t *mutex_p =
NULL;
446 template <
class Key,
class T>
453 template <
class Key,
class T>
460 template <
class Key,
class T>
467 template <
class Key,
class T>
474 template <
class Key,
class T>
481 template <
class Key,
class T>
487 return (
void *) (((
char *) p) + offset);
490 template <
class Key,
class T>
496 return (
void *
volatile *) (((
char *) p) + offset);
499 template <
class Key,
class T>
506 template <
class Key,
class T>
513 template <
class Key,
class T>
520 template <
class Key,
class T>
527 template <
class Key,
class T>
534 template <
class Key,
class T>
539 return &fn->get_data ().m_entry;
542 template <
class Key,
class T>
548 char *cp = (
char *) p;
553 template <
class Key,
class T>
562 template <
class Key,
class T>
569 template <
class Key,
class T>
576 template <
class Key,
class T>
583 template <
class Key,
class T>
590 template <
class Key,
class T>
591 template <
typename D>
599 os <<
", " << std::chrono::duration_cast<D> (ct_stat.
get_time ()).
count ();
604 template <
class Key,
class T>
605 template <
typename D>
622 template <
class Key,
class T>
629 template <
class Key,
class T>
636 template <
class Key,
class T>
646 template <
class Key,
class T>
653 template <
class Key,
class T>
660 bool is_local_tran =
false;
665 is_local_tran =
true;
672 fn->get_data ().m_edesc =
m_edesc;
695 template <
class Key,
class T>
708 template <
class Key,
class T>
715 template <
class Key,
class T>
723 template <
class Key,
class T>
731 template <
class Key,
class T>
741 template <
class Key,
class T>
749 template <
class Key,
class T>
753 pthread_mutex_t *no_output_mtx =
NULL;
757 template <
class Key,
class T>
765 template <
class Key,
class T>
774 #if defined (SERVER_MODE) 776 #endif // SERVER_MODE 779 template <
class Key,
class T>
785 #if defined (SERVER_MODE) 787 #endif // SERVER_MODE 792 template <
class Key,
class T>
797 #if defined (SERVER_MODE) 799 #endif // SERVER_MODE 803 template <
class Key,
class T>
809 pthread_mutex_t *entry_mutex =
NULL;
815 bool restart_search =
true;
817 while (restart_search)
819 restart_search =
false;
822 restart_search =
false;
850 restart_search =
true;
889 template <
class Key,
class T>
894 pthread_mutex_t *entry_mutex =
NULL;
898 bool restart_search =
true;
900 while (restart_search)
902 restart_search =
false;
910 while (curr_p !=
NULL)
947 restart_search =
true;
1054 if (!ATOMIC_CAS_ADDR (curr_p, (T *)
NULL, entry))
1076 restart_search =
true;
1101 template <
class Key,
class T>
1105 pthread_mutex_t *entry_mutex =
NULL;
1111 bool restart_search =
true;
1113 while (restart_search)
1115 restart_search =
false;
1118 curr_p = &list_head;
1122 while (curr !=
NULL)
1127 if (locked_entry !=
NULL && locked_entry != curr)
1157 restart_search =
true;
1179 if (!ATOMIC_CAS_ADDR (curr_p, curr, next))
1205 restart_search =
true;
1259 template <
class Key,
class T>
1265 bool inserted =
false;
1283 bflags &= ~LF_LIST_BR_RESTARTED;
1295 template <
class Key,
class T>
1301 bool erased =
false;
1306 erased =
list_delete (tran_index, list_head, key, locked_entry, &bflags);
1310 bflags &= ~LF_LIST_BR_RESTARTED;
1324 template <
class Key,
class T>
1333 template <
class Key,
class T>
1373 if (m_bucket_index < m_hashmap->
m_size)
1406 template <
class Key,
class T>
1417 template <
class Key,
class T>
1437 #endif // !_LOCKFREE_HASHMAP_HPP_ tran::descriptor * m_tdes
static bool is_address_marked(T *addr)
ct_stat_type m_stat_iterates
#define LF_LIST_BF_INSERT_GIVEN
void unlock_entry(T &tounlock)
static const index INVALID_INDEX
void *volatile * get_ref(T *p, size_t offset)
bool insert_given(tran::index tran_index, Key &key, T *&entry)
T * claim_temporary(tran::descriptor &tdes)
LF_ENTRY_INITIALIZE_FUNC f_init
void unlock_entry_mutex_force(pthread_mutex_t *&mtx)
freelist_node_data()=default
time_rep get_time(fetch_mode mode=FETCH_GLOBAL) const
void end_tran(tran::index tran_index)
bool find_or_insert(tran::index tran_index, Key &key, T *&entry)
#define pthread_mutex_unlock(a)
bool insert(tran::index tran_index, Key &key, T *&entry)
LF_ENTRY_UNINITIALIZE_FUNC f_uninit
lf_entry_descriptor * m_edesc
size_t get_element_count() const
counter_timer_statistic< amount_accumulator_atomic_statistic, time_accumulator_atomic_statistic > atomic_counter_timer_stat
void unlock_entry_mutex_if_locked(pthread_mutex_t *&mtx)
tran::descriptor & get_tran_descriptor(tran::index tran_index)
ct_stat_type m_stat_clear
static constexpr std::ptrdiff_t free_node_offset_of_data(free_node_type fn)
bool is_tran_started() const
freelist_type * m_freelist
bool list_delete(tran::index tran_index, T *&list_head, Key &key, T *locked_entry, int *behavior_flags)
std::mutex m_backbuffer_mutex
tran::table & get_transaction_table()
T * from_free_node(free_node_type *fn)
reclaimable_node * pull_saved_reclaimable()
size_t get_hash(Key &key) const
size_t get_claimed_count() const
free_node_type * to_free_node(T *p)
static T * strip_address_mark(T *addr)
amount_rep get_count(fetch_mode mode=FETCH_GLOBAL) const
void dump_stats(std::ostream &os) const
LF_ENTRY_KEY_COPY_FUNC f_key_copy
void lock_entry(T &tolock)
bool hash_insert_internal(tran::index tran_index, Key &key, int bflags, T *&entry)
LF_ENTRY_KEY_COMPARE_FUNC f_key_cmp
#define LF_LIST_BF_IS_FLAG_SET(bf, flag)
static T * set_adress_mark(T *addr)
ct_stat_type m_stat_claim
ct_stat_type m_stat_retire
void dump_stat(std::ostream &os, const char *name, const ct_stat_type &ct_stat) const
void unlock(tran::index tran_index, T *&entry)
#define LF_LIST_BF_RESTART_ON_DUPLICATE
iterator & operator=(iterator &&o)
freelist< freelist_node_data > freelist_type
void save_reclaimable(reclaimable_node *&node)
LF_ENTRY_DUPLICATE_KEY_HANDLER f_duplicate
static T * atomic_strip_address_mark(T *addr)
void safeguard_use_mutex_or_tran_started(const tran::descriptor &tdes, const pthread_mutex_t *mtx)
ct_stat_type m_stat_erase
void start_tran_if_not_started(tran::descriptor &tdes)
bool hash_erase_internal(tran::index tran_index, Key &key, int bflags, T *locked_entry)
#define LF_LIST_BF_FIND_OR_INSERT
#define LF_LIST_BF_RETURN_ON_RESTART
descriptor & get_descriptor(const index &tran_index)
int count(int &result, const cub_regex_object ®, const std::string &src, const int position, const INTL_CODESET codeset)
#define LF_LIST_BR_SET_FLAG(br, flag)
void freelist_retire(tran::index tran_index, T *&entry)
LF_ENTRY_HASH_FUNC f_hash
bool erase_locked(tran::index tran_index, Key &key, T *&locked_entry)
#define LF_LIST_BF_LOCK_ON_DELETE
void end_tran_force(tran::descriptor &tdes)
void init(tran::system &transys, size_t hash_size, size_t freelist_block_size, size_t freelist_block_count, lf_entry_descriptor &edesc)
T * find(tran::index tran_index, Key &key)
bool list_insert_internal(tran::index tran_index, T *&list_head, Key &key, int *behavior_flags, T *&found_node)
free_node * claim(tran::descriptor &tdes)
void clear(tran::index tran_index)
void start_tran(tran::index tran_index)
const size_t INVALID_INDEX
static void free_node(T_NODE_INFO *node)
void lock_entry_mutex(T &tolock, pthread_mutex_t *&mtx)
lf_entry_descriptor * m_edesc
void retire(tran::descriptor &tdes, free_node &node)
ct_stat_type m_stat_unlock
void promote_tran_force(tran::descriptor &tdes)
#define pthread_mutex_lock(a)
ct_stat_type m_stat_insert
#define LF_LIST_BR_RESTARTED
void * get_ptr_deref(T *p, size_t offset)
~freelist_node_data()=default
T * freelist_claim(tran::index tran_index)
void start_tran_force(tran::descriptor &tdes)
void save_temporary(tran::descriptor &tdes, T *&p)
typename freelist_type::free_node free_node_type
void start_tran_and_increment_id()
void end_tran_if_started(tran::descriptor &tdes)
void list_find(tran::index tran_index, T *list_head, Key &key, int *behavior_flags, T *&found_node)
bool erase(tran::index tran_index, Key &key)
T *& get_bucket(Key &key)
void * get_ptr(T *p, size_t offset)
pthread_mutex_t * get_pthread_mutexp(T *p)