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