diff options
Diffstat (limited to 'database/engine/pagecache.h')
-rw-r--r-- | database/engine/pagecache.h | 131 |
1 files changed, 71 insertions, 60 deletions
diff --git a/database/engine/pagecache.h b/database/engine/pagecache.h index b938b9e0..2f4d6b33 100644 --- a/database/engine/pagecache.h +++ b/database/engine/pagecache.h @@ -60,18 +60,19 @@ struct rrdeng_page_descr { volatile unsigned long pg_cache_descr_state; /* page information */ - usec_t start_time; - usec_t end_time; - uint32_t page_length; + usec_t start_time_ut; + usec_t end_time_ut; + uint32_t update_every_s:24; uint8_t type; + uint32_t page_length; }; #define PAGE_INFO_SCRATCH_SZ (8) struct rrdeng_page_info { uint8_t scratch[PAGE_INFO_SCRATCH_SZ]; /* scratch area to be used by page-cache users */ - usec_t start_time; - usec_t end_time; + usec_t start_time_ut; + usec_t end_time_ut; uint32_t page_length; }; @@ -80,6 +81,11 @@ typedef int pg_cache_page_info_filter_t(struct rrdeng_page_descr *); #define PAGE_CACHE_MAX_PRELOAD_PAGES (256) +struct pg_alignment { + uint32_t page_length; + uint32_t refcount; +}; + /* maps time ranges to pages */ struct pg_cache_page_index { uuid_t id; @@ -89,6 +95,7 @@ struct pg_cache_page_index { */ Pvoid_t JudyL_array; Word_t page_count; + unsigned short refcount; unsigned short writers; uv_rwlock_t lock; @@ -96,13 +103,17 @@ struct pg_cache_page_index { * Only one effective writer, data deletion workqueue. * It's also written during the DB loading phase. */ - usec_t oldest_time; + usec_t oldest_time_ut; /* * Only one effective writer, data collection thread. * It's also written by the data deletion workqueue when data collection is disabled for this metric. */ - usec_t latest_time; + usec_t latest_time_ut; + + struct rrdengine_instance *ctx; + struct pg_alignment *alignment; + uint32_t latest_update_every_s; struct pg_cache_page_index *prev; }; @@ -152,93 +163,93 @@ struct page_cache { /* TODO: add statistics */ unsigned populated_pages; }; -extern void pg_cache_wake_up_waiters_unsafe(struct rrdeng_page_descr *descr); -extern void pg_cache_wake_up_waiters(struct rrdengine_instance *ctx, struct rrdeng_page_descr *descr); -extern void pg_cache_wait_event_unsafe(struct rrdeng_page_descr *descr); -extern unsigned long pg_cache_wait_event(struct rrdengine_instance *ctx, struct rrdeng_page_descr *descr); -extern void pg_cache_replaceQ_insert(struct rrdengine_instance *ctx, +void pg_cache_wake_up_waiters_unsafe(struct rrdeng_page_descr *descr); +void pg_cache_wake_up_waiters(struct rrdengine_instance *ctx, struct rrdeng_page_descr *descr); +void pg_cache_wait_event_unsafe(struct rrdeng_page_descr *descr); +unsigned long pg_cache_wait_event(struct rrdengine_instance *ctx, struct rrdeng_page_descr *descr); +void pg_cache_replaceQ_insert(struct rrdengine_instance *ctx, struct rrdeng_page_descr *descr); -extern void pg_cache_replaceQ_delete(struct rrdengine_instance *ctx, +void pg_cache_replaceQ_delete(struct rrdengine_instance *ctx, struct rrdeng_page_descr *descr); -extern void pg_cache_replaceQ_set_hot(struct rrdengine_instance *ctx, +void pg_cache_replaceQ_set_hot(struct rrdengine_instance *ctx, struct rrdeng_page_descr *descr); -extern struct rrdeng_page_descr *pg_cache_create_descr(void); -extern int pg_cache_try_get_unsafe(struct rrdeng_page_descr *descr, int exclusive_access); -extern void pg_cache_put_unsafe(struct rrdeng_page_descr *descr); -extern void pg_cache_put(struct rrdengine_instance *ctx, struct rrdeng_page_descr *descr); -extern void pg_cache_insert(struct rrdengine_instance *ctx, struct pg_cache_page_index *index, +struct rrdeng_page_descr *pg_cache_create_descr(void); +int pg_cache_try_get_unsafe(struct rrdeng_page_descr *descr, int exclusive_access); +void pg_cache_put_unsafe(struct rrdeng_page_descr *descr); +void pg_cache_put(struct rrdengine_instance *ctx, struct rrdeng_page_descr *descr); +void pg_cache_insert(struct rrdengine_instance *ctx, struct pg_cache_page_index *index, struct rrdeng_page_descr *descr); -extern uint8_t pg_cache_punch_hole(struct rrdengine_instance *ctx, struct rrdeng_page_descr *descr, +uint8_t pg_cache_punch_hole(struct rrdengine_instance *ctx, struct rrdeng_page_descr *descr, uint8_t remove_dirty, uint8_t is_exclusive_holder, uuid_t *metric_id); -extern usec_t pg_cache_oldest_time_in_range(struct rrdengine_instance *ctx, uuid_t *id, - usec_t start_time, usec_t end_time); -extern void pg_cache_get_filtered_info_prev(struct rrdengine_instance *ctx, struct pg_cache_page_index *page_index, - usec_t point_in_time, pg_cache_page_info_filter_t *filter, +usec_t pg_cache_oldest_time_in_range(struct rrdengine_instance *ctx, uuid_t *id, + usec_t start_time_ut, usec_t end_time_ut); +void pg_cache_get_filtered_info_prev(struct rrdengine_instance *ctx, struct pg_cache_page_index *page_index, + usec_t point_in_time_ut, pg_cache_page_info_filter_t *filter, struct rrdeng_page_info *page_info); -extern struct rrdeng_page_descr *pg_cache_lookup_unpopulated_and_lock(struct rrdengine_instance *ctx, uuid_t *id, - usec_t start_time); -extern unsigned - pg_cache_preload(struct rrdengine_instance *ctx, uuid_t *id, usec_t start_time, usec_t end_time, +struct rrdeng_page_descr *pg_cache_lookup_unpopulated_and_lock(struct rrdengine_instance *ctx, uuid_t *id, + usec_t start_time_ut); +unsigned + pg_cache_preload(struct rrdengine_instance *ctx, uuid_t *id, usec_t start_time_ut, usec_t end_time_ut, struct rrdeng_page_info **page_info_arrayp, struct pg_cache_page_index **ret_page_indexp); -extern struct rrdeng_page_descr * +struct rrdeng_page_descr * pg_cache_lookup(struct rrdengine_instance *ctx, struct pg_cache_page_index *index, uuid_t *id, - usec_t point_in_time); -extern struct rrdeng_page_descr * + usec_t point_in_time_ut); +struct rrdeng_page_descr * pg_cache_lookup_next(struct rrdengine_instance *ctx, struct pg_cache_page_index *index, uuid_t *id, - usec_t start_time, usec_t end_time); -extern struct pg_cache_page_index *create_page_index(uuid_t *id); -extern void init_page_cache(struct rrdengine_instance *ctx); -extern void free_page_cache(struct rrdengine_instance *ctx); -extern void pg_cache_add_new_metric_time(struct pg_cache_page_index *page_index, struct rrdeng_page_descr *descr); -extern void pg_cache_update_metric_times(struct pg_cache_page_index *page_index); -extern unsigned long pg_cache_hard_limit(struct rrdengine_instance *ctx); -extern unsigned long pg_cache_soft_limit(struct rrdengine_instance *ctx); -extern unsigned long pg_cache_committed_hard_limit(struct rrdengine_instance *ctx); - -extern void rrdeng_page_descr_aral_go_singlethreaded(void); -extern void rrdeng_page_descr_aral_go_multithreaded(void); -extern void rrdeng_page_descr_use_malloc(void); -extern void rrdeng_page_descr_use_mmap(void); -extern bool rrdeng_page_descr_is_mmap(void); -extern struct rrdeng_page_descr *rrdeng_page_descr_mallocz(void); -extern void rrdeng_page_descr_freez(struct rrdeng_page_descr *descr); + usec_t start_time_ut, usec_t end_time_ut); +struct pg_cache_page_index *create_page_index(uuid_t *id, struct rrdengine_instance *ctx); +void init_page_cache(struct rrdengine_instance *ctx); +void free_page_cache(struct rrdengine_instance *ctx); +void pg_cache_add_new_metric_time(struct pg_cache_page_index *page_index, struct rrdeng_page_descr *descr); +void pg_cache_update_metric_times(struct pg_cache_page_index *page_index); +unsigned long pg_cache_hard_limit(struct rrdengine_instance *ctx); +unsigned long pg_cache_soft_limit(struct rrdengine_instance *ctx); +unsigned long pg_cache_committed_hard_limit(struct rrdengine_instance *ctx); + +void rrdeng_page_descr_aral_go_singlethreaded(void); +void rrdeng_page_descr_aral_go_multithreaded(void); +void rrdeng_page_descr_use_malloc(void); +void rrdeng_page_descr_use_mmap(void); +bool rrdeng_page_descr_is_mmap(void); +struct rrdeng_page_descr *rrdeng_page_descr_mallocz(void); +void rrdeng_page_descr_freez(struct rrdeng_page_descr *descr); static inline void - pg_cache_atomic_get_pg_info(struct rrdeng_page_descr *descr, usec_t *end_timep, uint32_t *page_lengthp) + pg_cache_atomic_get_pg_info(struct rrdeng_page_descr *descr, usec_t *end_time_ut_p, uint32_t *page_lengthp) { - usec_t end_time, old_end_time; + usec_t end_time_ut, old_end_time_ut; uint32_t page_length; if (NULL == descr->extent) { /* this page is currently being modified, get consistent info locklessly */ do { - end_time = descr->end_time; + end_time_ut = descr->end_time_ut; __sync_synchronize(); - old_end_time = end_time; + old_end_time_ut = end_time_ut; page_length = descr->page_length; __sync_synchronize(); - end_time = descr->end_time; + end_time_ut = descr->end_time_ut; __sync_synchronize(); - } while ((end_time != old_end_time || (end_time & 1) != 0)); + } while ((end_time_ut != old_end_time_ut || (end_time_ut & 1) != 0)); - *end_timep = end_time; + *end_time_ut_p = end_time_ut; *page_lengthp = page_length; } else { - *end_timep = descr->end_time; + *end_time_ut_p = descr->end_time_ut; *page_lengthp = descr->page_length; } } /* The caller must hold a reference to the page and must have already set the new data */ -static inline void pg_cache_atomic_set_pg_info(struct rrdeng_page_descr *descr, usec_t end_time, uint32_t page_length) +static inline void pg_cache_atomic_set_pg_info(struct rrdeng_page_descr *descr, usec_t end_time_ut, uint32_t page_length) { - fatal_assert(!(end_time & 1)); + fatal_assert(!(end_time_ut & 1)); __sync_synchronize(); - descr->end_time |= 1; /* mark start of uncertainty period by adding 1 microsecond */ + descr->end_time_ut |= 1; /* mark start of uncertainty period by adding 1 microsecond */ __sync_synchronize(); descr->page_length = page_length; __sync_synchronize(); - descr->end_time = end_time; /* mark end of uncertainty period */ + descr->end_time_ut = end_time_ut; /* mark end of uncertainty period */ } #endif /* NETDATA_PAGECACHE_H */ |