cache.h 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  1. #ifndef DBENGINE_CACHE_H
  2. #define DBENGINE_CACHE_H
  3. #include "../rrd.h"
  4. // CACHE COMPILE TIME CONFIGURATION
  5. // #define PGC_COUNT_POINTS_COLLECTED 1
  6. typedef struct pgc PGC;
  7. typedef struct pgc_page PGC_PAGE;
  8. #define PGC_NAME_MAX 23
  9. typedef enum __attribute__ ((__packed__)) {
  10. PGC_OPTIONS_NONE = 0,
  11. PGC_OPTIONS_EVICT_PAGES_INLINE = (1 << 0),
  12. PGC_OPTIONS_FLUSH_PAGES_INLINE = (1 << 1),
  13. PGC_OPTIONS_AUTOSCALE = (1 << 2),
  14. } PGC_OPTIONS;
  15. #define PGC_OPTIONS_DEFAULT (PGC_OPTIONS_EVICT_PAGES_INLINE | PGC_OPTIONS_FLUSH_PAGES_INLINE | PGC_OPTIONS_AUTOSCALE)
  16. typedef struct pgc_entry {
  17. Word_t section; // the section this belongs to
  18. Word_t metric_id; // the metric this belongs to
  19. time_t start_time_s; // the start time of the page
  20. time_t end_time_s; // the end time of the page
  21. size_t size; // the size in bytes of the allocation, outside the cache
  22. void *data; // a pointer to data outside the cache
  23. uint32_t update_every_s; // the update every of the page
  24. bool hot; // true if this entry is currently being collected
  25. uint8_t *custom_data;
  26. } PGC_ENTRY;
  27. #define PGC_CACHE_LINE_PADDING(x) uint8_t padding##x[64]
  28. struct pgc_queue_statistics {
  29. size_t entries;
  30. size_t size;
  31. PGC_CACHE_LINE_PADDING(1);
  32. size_t max_entries;
  33. size_t max_size;
  34. PGC_CACHE_LINE_PADDING(2);
  35. size_t added_entries;
  36. size_t added_size;
  37. PGC_CACHE_LINE_PADDING(3);
  38. size_t removed_entries;
  39. size_t removed_size;
  40. PGC_CACHE_LINE_PADDING(4);
  41. };
  42. struct pgc_statistics {
  43. size_t wanted_cache_size;
  44. size_t current_cache_size;
  45. PGC_CACHE_LINE_PADDING(1);
  46. size_t added_entries;
  47. size_t added_size;
  48. PGC_CACHE_LINE_PADDING(2);
  49. size_t removed_entries;
  50. size_t removed_size;
  51. PGC_CACHE_LINE_PADDING(3);
  52. size_t entries; // all the entries (includes clean, dirty, hot)
  53. size_t size; // all the entries (includes clean, dirty, hot)
  54. size_t evicting_entries;
  55. size_t evicting_size;
  56. size_t flushing_entries;
  57. size_t flushing_size;
  58. size_t hot2dirty_entries;
  59. size_t hot2dirty_size;
  60. PGC_CACHE_LINE_PADDING(4);
  61. size_t acquires;
  62. PGC_CACHE_LINE_PADDING(4a);
  63. size_t releases;
  64. PGC_CACHE_LINE_PADDING(4b);
  65. size_t acquires_for_deletion;
  66. PGC_CACHE_LINE_PADDING(4c);
  67. size_t referenced_entries; // all the entries currently referenced
  68. size_t referenced_size; // all the entries currently referenced
  69. PGC_CACHE_LINE_PADDING(5);
  70. size_t searches_exact;
  71. size_t searches_exact_hits;
  72. size_t searches_exact_misses;
  73. PGC_CACHE_LINE_PADDING(6);
  74. size_t searches_closest;
  75. size_t searches_closest_hits;
  76. size_t searches_closest_misses;
  77. PGC_CACHE_LINE_PADDING(7);
  78. size_t flushes_completed;
  79. size_t flushes_completed_size;
  80. size_t flushes_cancelled;
  81. size_t flushes_cancelled_size;
  82. #ifdef PGC_COUNT_POINTS_COLLECTED
  83. PGC_CACHE_LINE_PADDING(8);
  84. size_t points_collected;
  85. #endif
  86. PGC_CACHE_LINE_PADDING(9);
  87. size_t insert_spins;
  88. size_t evict_spins;
  89. size_t release_spins;
  90. size_t acquire_spins;
  91. size_t delete_spins;
  92. size_t flush_spins;
  93. PGC_CACHE_LINE_PADDING(10);
  94. size_t workers_search;
  95. size_t workers_add;
  96. size_t workers_evict;
  97. size_t workers_flush;
  98. size_t workers_jv2_flush;
  99. size_t workers_hot2dirty;
  100. size_t evict_skipped;
  101. size_t hot_empty_pages_evicted_immediately;
  102. size_t hot_empty_pages_evicted_later;
  103. PGC_CACHE_LINE_PADDING(11);
  104. // events
  105. size_t events_cache_under_severe_pressure;
  106. size_t events_cache_needs_space_aggressively;
  107. size_t events_flush_critical;
  108. PGC_CACHE_LINE_PADDING(12);
  109. struct {
  110. PGC_CACHE_LINE_PADDING(0);
  111. struct pgc_queue_statistics hot;
  112. PGC_CACHE_LINE_PADDING(1);
  113. struct pgc_queue_statistics dirty;
  114. PGC_CACHE_LINE_PADDING(2);
  115. struct pgc_queue_statistics clean;
  116. PGC_CACHE_LINE_PADDING(3);
  117. } queues;
  118. };
  119. typedef void (*free_clean_page_callback)(PGC *cache, PGC_ENTRY entry);
  120. typedef void (*save_dirty_page_callback)(PGC *cache, PGC_ENTRY *entries_array, PGC_PAGE **pages_array, size_t entries);
  121. typedef void (*save_dirty_init_callback)(PGC *cache, Word_t section);
  122. // create a cache
  123. PGC *pgc_create(const char *name,
  124. size_t clean_size_bytes, free_clean_page_callback pgc_free_clean_cb,
  125. size_t max_dirty_pages_per_flush, save_dirty_init_callback pgc_save_init_cb, save_dirty_page_callback pgc_save_dirty_cb,
  126. size_t max_pages_per_inline_eviction, size_t max_inline_evictors,
  127. size_t max_skip_pages_per_inline_eviction,
  128. size_t max_flushes_inline,
  129. PGC_OPTIONS options, size_t partitions, size_t additional_bytes_per_page);
  130. // destroy the cache
  131. void pgc_destroy(PGC *cache);
  132. #define PGC_SECTION_ALL ((Word_t)0)
  133. void pgc_flush_all_hot_and_dirty_pages(PGC *cache, Word_t section);
  134. // add a page to the cache and return a pointer to it
  135. PGC_PAGE *pgc_page_add_and_acquire(PGC *cache, PGC_ENTRY entry, bool *added);
  136. // get another reference counter on an already referenced page
  137. PGC_PAGE *pgc_page_dup(PGC *cache, PGC_PAGE *page);
  138. // release a page (all pointers to it are now invalid)
  139. void pgc_page_release(PGC *cache, PGC_PAGE *page);
  140. // mark a hot page dirty, and release it
  141. void pgc_page_hot_to_dirty_and_release(PGC *cache, PGC_PAGE *page);
  142. // find a page from the cache
  143. typedef enum {
  144. PGC_SEARCH_EXACT,
  145. PGC_SEARCH_CLOSEST,
  146. PGC_SEARCH_FIRST,
  147. PGC_SEARCH_NEXT,
  148. PGC_SEARCH_LAST,
  149. PGC_SEARCH_PREV,
  150. } PGC_SEARCH;
  151. PGC_PAGE *pgc_page_get_and_acquire(PGC *cache, Word_t section, Word_t metric_id, time_t start_time_s, PGC_SEARCH method);
  152. // get information from an acquired page
  153. Word_t pgc_page_section(PGC_PAGE *page);
  154. Word_t pgc_page_metric(PGC_PAGE *page);
  155. time_t pgc_page_start_time_s(PGC_PAGE *page);
  156. time_t pgc_page_end_time_s(PGC_PAGE *page);
  157. time_t pgc_page_update_every_s(PGC_PAGE *page);
  158. time_t pgc_page_fix_update_every(PGC_PAGE *page, time_t update_every_s);
  159. time_t pgc_page_fix_end_time_s(PGC_PAGE *page, time_t end_time_s);
  160. void *pgc_page_data(PGC_PAGE *page);
  161. void *pgc_page_custom_data(PGC *cache, PGC_PAGE *page);
  162. size_t pgc_page_data_size(PGC *cache, PGC_PAGE *page);
  163. bool pgc_is_page_hot(PGC_PAGE *page);
  164. bool pgc_is_page_dirty(PGC_PAGE *page);
  165. bool pgc_is_page_clean(PGC_PAGE *page);
  166. void pgc_reset_hot_max(PGC *cache);
  167. size_t pgc_get_current_cache_size(PGC *cache);
  168. size_t pgc_get_wanted_cache_size(PGC *cache);
  169. // resetting the end time of a hot page
  170. void pgc_page_hot_set_end_time_s(PGC *cache, PGC_PAGE *page, time_t end_time_s);
  171. bool pgc_page_to_clean_evict_or_release(PGC *cache, PGC_PAGE *page);
  172. typedef void (*migrate_to_v2_callback)(Word_t section, unsigned datafile_fileno, uint8_t type, Pvoid_t JudyL_metrics, Pvoid_t JudyL_extents_pos, size_t count_of_unique_extents, size_t count_of_unique_metrics, size_t count_of_unique_pages, void *data);
  173. void pgc_open_cache_to_journal_v2(PGC *cache, Word_t section, unsigned datafile_fileno, uint8_t type, migrate_to_v2_callback cb, void *data);
  174. void pgc_open_evict_clean_pages_of_datafile(PGC *cache, struct rrdengine_datafile *datafile);
  175. size_t pgc_count_clean_pages_having_data_ptr(PGC *cache, Word_t section, void *ptr);
  176. size_t pgc_count_hot_pages_having_data_ptr(PGC *cache, Word_t section, void *ptr);
  177. typedef size_t (*dynamic_target_cache_size_callback)(void);
  178. void pgc_set_dynamic_target_cache_size_callback(PGC *cache, dynamic_target_cache_size_callback callback);
  179. // return true when there is more work to do
  180. bool pgc_evict_pages(PGC *cache, size_t max_skip, size_t max_evict);
  181. bool pgc_flush_pages(PGC *cache, size_t max_flushes);
  182. struct pgc_statistics pgc_get_statistics(PGC *cache);
  183. size_t pgc_hot_and_dirty_entries(PGC *cache);
  184. struct aral_statistics *pgc_aral_statistics(void);
  185. size_t pgc_aral_structures(void);
  186. size_t pgc_aral_overhead(void);
  187. #endif // DBENGINE_CACHE_H