1 /*
2 * Copyright (C) 2009-2018 Codership Oy <info@codership.com>
3 */
4
5 #include "GCache.hpp"
6
7 static const std::string GCACHE_PARAMS_DIR ("gcache.dir");
8 static const std::string GCACHE_DEFAULT_DIR ("");
9 static const std::string GCACHE_PARAMS_RB_NAME ("gcache.name");
10 static const std::string GCACHE_DEFAULT_RB_NAME ("galera.cache");
11 static const std::string GCACHE_PARAMS_MEM_SIZE ("gcache.mem_size");
12 static const std::string GCACHE_DEFAULT_MEM_SIZE ("0");
13 static const std::string GCACHE_PARAMS_RB_SIZE ("gcache.size");
14 static const std::string GCACHE_DEFAULT_RB_SIZE ("128M");
15 static const std::string GCACHE_PARAMS_PAGE_SIZE ("gcache.page_size");
16 static const std::string GCACHE_DEFAULT_PAGE_SIZE (GCACHE_DEFAULT_RB_SIZE);
17 static const std::string GCACHE_PARAMS_KEEP_PAGES_SIZE("gcache.keep_pages_size");
18 static const std::string GCACHE_DEFAULT_KEEP_PAGES_SIZE("0");
19 #ifndef NDEBUG
20 static const std::string GCACHE_PARAMS_DEBUG ("gcache.debug");
21 static const std::string GCACHE_DEFAULT_DEBUG ("0");
22 #endif
23 static const std::string GCACHE_PARAMS_RECOVER ("gcache.recover");
24 static const std::string GCACHE_DEFAULT_RECOVER ("yes");
25
26 const std::string&
27 gcache::GCache::PARAMS_DIR (GCACHE_PARAMS_DIR);
28
29 void
register_params(gu::Config & cfg)30 gcache::GCache::Params::register_params(gu::Config& cfg)
31 {
32 cfg.add(GCACHE_PARAMS_DIR, GCACHE_DEFAULT_DIR);
33 cfg.add(GCACHE_PARAMS_RB_NAME, GCACHE_DEFAULT_RB_NAME);
34 cfg.add(GCACHE_PARAMS_MEM_SIZE, GCACHE_DEFAULT_MEM_SIZE);
35 cfg.add(GCACHE_PARAMS_RB_SIZE, GCACHE_DEFAULT_RB_SIZE);
36 cfg.add(GCACHE_PARAMS_PAGE_SIZE, GCACHE_DEFAULT_PAGE_SIZE);
37 cfg.add(GCACHE_PARAMS_KEEP_PAGES_SIZE, GCACHE_DEFAULT_KEEP_PAGES_SIZE);
38 #ifndef NDEBUG
39 cfg.add(GCACHE_PARAMS_DEBUG, GCACHE_DEFAULT_DEBUG);
40 #endif
41 cfg.add(GCACHE_PARAMS_RECOVER, GCACHE_DEFAULT_RECOVER);
42 }
43
44 static const std::string
name_value(gu::Config & cfg,const std::string & data_dir)45 name_value (gu::Config& cfg, const std::string& data_dir)
46 {
47 std::string dir(cfg.get(GCACHE_PARAMS_DIR));
48
49 /* fallback to data_dir if gcache dir is not set */
50 if (GCACHE_DEFAULT_DIR == dir && !data_dir.empty())
51 {
52 dir = data_dir;
53 cfg.set (GCACHE_PARAMS_DIR, dir);
54 }
55
56 std::string rb_name(cfg.get (GCACHE_PARAMS_RB_NAME));
57
58 /* prepend directory name to RB file name if the former is not empty and
59 * the latter is not an absolute path */
60 if ('/' != rb_name[0] && !dir.empty())
61 {
62 rb_name = dir + '/' + rb_name;
63 }
64
65 return rb_name;
66 }
67
Params(gu::Config & cfg,const std::string & data_dir)68 gcache::GCache::Params::Params (gu::Config& cfg, const std::string& data_dir)
69 :
70 rb_name_ (name_value (cfg, data_dir)),
71 dir_name_ (cfg.get(GCACHE_PARAMS_DIR)),
72 mem_size_ (cfg.get<size_t>(GCACHE_PARAMS_MEM_SIZE)),
73 rb_size_ (cfg.get<size_t>(GCACHE_PARAMS_RB_SIZE)),
74 page_size_(cfg.get<size_t>(GCACHE_PARAMS_PAGE_SIZE)),
75 keep_pages_size_(cfg.get<size_t>(GCACHE_PARAMS_KEEP_PAGES_SIZE)),
76 #ifndef NDEBUG
77 debug_ (cfg.get<int>(GCACHE_PARAMS_DEBUG)),
78 #else
79 debug_ (0),
80 #endif
81 recover_ (cfg.get<bool>(GCACHE_PARAMS_RECOVER))
82 {}
83
84 void
param_set(const std::string & key,const std::string & val)85 gcache::GCache::param_set (const std::string& key, const std::string& val)
86 {
87 if (key == GCACHE_PARAMS_RB_NAME)
88 {
89 gu_throw_error(EPERM) << "Can't change ring buffer name in runtime.";
90 }
91 else if (key == GCACHE_PARAMS_DIR)
92 {
93 gu_throw_error(EPERM) << "Can't change data dir in runtime.";
94 }
95 else if (key == GCACHE_PARAMS_MEM_SIZE)
96 {
97 size_t tmp_size = gu::Config::from_config<size_t>(val);
98
99 gu::Lock lock(mtx);
100 /* locking here serves two purposes: ensures atomic setting of config
101 * and params.ram_size and syncs with malloc() method */
102
103 config.set<size_t>(key, tmp_size);
104 params.mem_size(tmp_size);
105 mem.set_max_size(params.mem_size());
106 }
107 else if (key == GCACHE_PARAMS_RB_SIZE)
108 {
109 gu_throw_error(EPERM) << "Can't change ring buffer size in runtime.";
110 }
111 else if (key == GCACHE_PARAMS_PAGE_SIZE)
112 {
113 size_t tmp_size = gu::Config::from_config<size_t>(val);
114
115 gu::Lock lock(mtx);
116 /* locking here serves two purposes: ensures atomic setting of config
117 * and params.ram_size and syncs with malloc() method */
118
119 config.set<size_t>(key, tmp_size);
120 params.page_size(tmp_size);
121 ps.set_page_size(params.page_size());
122 }
123 else if (key == GCACHE_PARAMS_KEEP_PAGES_SIZE)
124 {
125 size_t tmp_size = gu::Config::from_config<size_t>(val);
126
127 gu::Lock lock(mtx);
128 /* locking here serves two purposes: ensures atomic setting of config
129 * and params.ram_size and syncs with malloc() method */
130
131 config.set<size_t>(key, tmp_size);
132 params.keep_pages_size(tmp_size);
133 ps.set_keep_size(params.keep_pages_size());
134 }
135 else if (key == GCACHE_PARAMS_RECOVER)
136 {
137 gu_throw_error(EINVAL) << "'" << key
138 << "' has a meaning only on startup.";
139 }
140 #ifndef NDEBUG
141 else if (key == GCACHE_PARAMS_DEBUG)
142 {
143 int d = gu::Config::from_config<int>(val);
144
145 gu::Lock lock(mtx);
146 /* locking here serves two purposes: ensures atomic setting of config
147 * and params.ram_size and syncs with malloc() method */
148
149 config.set<int>(key, d);
150 params.debug(d);
151 mem.set_debug(params.debug());
152 rb.set_debug(params.debug());
153 ps.set_debug(params.debug());
154 }
155 #endif
156 else
157 {
158 throw gu::NotFound();
159 }
160 }
161