]> git.proxmox.com Git - ceph.git/blame - ceph/src/erasure-code/shec/ErasureCodeShecTableCache.cc
update sources to v12.1.0
[ceph.git] / ceph / src / erasure-code / shec / ErasureCodeShecTableCache.cc
CommitLineData
7c673cae
FG
1// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2// vim: ts=8 sw=2 smarttab
3/*
4 * Ceph - scalable distributed file system
5 *
6 * Copyright (C) 2014 FUJITSU LIMITED
7 * Copyright (C) 2014 CERN (Switzerland)
8 *
9 * Author: Takanori Nakao <nakao.takanori@jp.fujitsu.com>
10 * Author: Takeshi Miyamae <miyamae.takeshi@jp.fujitsu.com>
11 * Author: Andreas-Joachim Peters <Andreas.Joachim.Peters@cern.ch>
12 *
13 * This library is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU Lesser General Public
15 * License as published by the Free Software Foundation; either
16 * version 2.1 of the License, or (at your option) any later version.
17 *
18 */
19
20// -----------------------------------------------------------------------------
21#include "ErasureCodeShecTableCache.h"
7c673cae
FG
22#include "common/debug.h"
23// -----------------------------------------------------------------------------
31f18b77 24using namespace std;
7c673cae
FG
25
26// -----------------------------------------------------------------------------
27#define dout_context g_ceph_context
28#define dout_subsys ceph_subsys_osd
29#undef dout_prefix
30#define dout_prefix _tc_prefix(_dout)
31// -----------------------------------------------------------------------------
32
33// -----------------------------------------------------------------------------
34
35static ostream&
36_tc_prefix(std::ostream* _dout) {
37 return *_dout << "ErasureCodeShecTableCache: ";
38}
39
40// -----------------------------------------------------------------------------
41
42ErasureCodeShecTableCache::~ErasureCodeShecTableCache()
43{
44 Mutex::Locker lock(codec_tables_guard);
45
46 // clean-up all allocated tables
47 {
48 codec_technique_tables_t::const_iterator ttables_it;
49 codec_tables_t::const_iterator tables_it;
50 codec_tables_t_::const_iterator tables_it_;
51 codec_tables_t__::const_iterator tables_it__;
52 codec_table_t::const_iterator table_it;
53
54 for (ttables_it = encoding_table.begin(); ttables_it != encoding_table.end(); ++ttables_it) {
55 for (tables_it = ttables_it->second.begin(); tables_it != ttables_it->second.end(); ++tables_it) {
56 for (tables_it_ = tables_it->second.begin(); tables_it_ != tables_it->second.end(); ++tables_it_) {
57 for (tables_it__ = tables_it_->second.begin(); tables_it__ != tables_it_->second.end(); ++tables_it__) {
58 for (table_it = tables_it__->second.begin(); table_it != tables_it__->second.end(); ++table_it) {
59 if (table_it->second) {
60 if (*(table_it->second)) {
61 delete *(table_it->second);
62 }
63 delete table_it->second;
64 }
65 }
66 }
67 }
68 }
69 }
70 }
71
72 {
73 std::map<int, lru_map_t*>::const_iterator lru_map_it;
74 std::map<int, lru_list_t*>::const_iterator lru_list_it;
75
76 for (lru_map_it = decoding_tables.begin();
77 lru_map_it != decoding_tables.end();
78 ++lru_map_it) {
79 if (lru_map_it->second) {
80 delete lru_map_it->second;
81 }
82 }
83
84 for (lru_list_it = decoding_tables_lru.begin();
85 lru_list_it != decoding_tables_lru.end();
86 ++lru_list_it) {
87 if (lru_list_it->second) {
88 delete lru_list_it->second;
89 }
90 }
91 }
92}
93
94ErasureCodeShecTableCache::lru_map_t*
95ErasureCodeShecTableCache::getDecodingTables(int technique) {
96 // the caller must hold the guard mutex:
97 // => Mutex::Locker lock(codec_tables_guard);
98
99 // create an lru_map if not yet allocated
100 if (!decoding_tables[technique]) {
101 decoding_tables[technique] = new lru_map_t;
102 }
103 return decoding_tables[technique];
104}
105
106ErasureCodeShecTableCache::lru_list_t*
107ErasureCodeShecTableCache::getDecodingTablesLru(int technique) {
108 // the caller must hold the guard mutex:
109 // => Mutex::Locker lock(codec_tables_guard);
110
111 // create an lru_list if not yet allocated
112 if (!decoding_tables_lru[technique]) {
113 decoding_tables_lru[technique] = new lru_list_t;
114 }
115 return decoding_tables_lru[technique];
116}
117
118int**
119ErasureCodeShecTableCache::getEncodingTable(int technique, int k, int m, int c, int w)
120{
121 Mutex::Locker lock(codec_tables_guard);
122 return getEncodingTableNoLock(technique,k,m,c,w);
123}
124
125// -----------------------------------------------------------------------------
126
127int**
128ErasureCodeShecTableCache::getEncodingTableNoLock(int technique, int k, int m, int c, int w)
129{
130 // create a pointer to store an encoding table address
131 if (!encoding_table[technique][k][m][c][w]) {
132 encoding_table[technique][k][m][c][w] = new (int*);
133 *encoding_table[technique][k][m][c][w] = 0;
134 }
135 return encoding_table[technique][k][m][c][w];
136}
137
138int*
139ErasureCodeShecTableCache::setEncodingTable(int technique, int k, int m, int c, int w, int* ec_in_table)
140{
141 Mutex::Locker lock(codec_tables_guard);
142 int** ec_out_table = getEncodingTableNoLock(technique, k, m, c, w);
143 if (*ec_out_table) {
144 // somebody might have deposited this table in the meanwhile, so clean
145 // the input table and return the stored one
146 free (ec_in_table);
147 return *ec_out_table;
148 } else {
149 // we store the provided input table and return this one
150 *encoding_table[technique][k][m][c][w] = ec_in_table;
151 return ec_in_table;
152 }
153}
154
155Mutex*
156ErasureCodeShecTableCache::getLock()
157{
158 return &codec_tables_guard;
159}
160
161uint64_t
162ErasureCodeShecTableCache::getDecodingCacheSignature(int k, int m, int c, int w,
163 int *erased, int *avails) {
164 uint64_t signature = 0;
165 signature = (uint64_t)k;
166 signature |= ((uint64_t)m << 6);
167 signature |= ((uint64_t)c << 12);
168 signature |= ((uint64_t)w << 18);
169
170 for (int i=0; i < k+m; i++) {
171 signature |= ((uint64_t)(avails[i] ? 1 : 0) << (24+i));
172 }
173 for (int i=0; i < k+m; i++) {
174 signature |= ((uint64_t)(erased[i] ? 1 : 0) << (44+i));
175 }
176 return signature;
177}
178
179bool
180ErasureCodeShecTableCache::getDecodingTableFromCache(int* decoding_matrix,
181 int* dm_row,
182 int* dm_column,
183 int* minimum,
184 int technique,
185 int k,
186 int m,
187 int c,
188 int w,
189 int* erased,
190 int* avails) {
191 // --------------------------------------------------------------------------
192 // LRU decoding matrix cache
193 // --------------------------------------------------------------------------
194
195 uint64_t signature = getDecodingCacheSignature(k, m, c, w, erased, avails);
196 Mutex::Locker lock(codec_tables_guard);
197
198 dout(20) << "[ get table ] = " << signature << dendl;
199
200 // we try to fetch a decoding table from an LRU cache
201 lru_map_t* decode_tbls_map =
202 getDecodingTables(technique);
203
204 lru_list_t* decode_tbls_lru =
205 getDecodingTablesLru(technique);
206
207 lru_map_t::iterator decode_tbls_map_it = decode_tbls_map->find(signature);
208 if (decode_tbls_map_it == decode_tbls_map->end()) {
209 return false;
210 }
211
212 dout(20) << "[ cached table ] = " << signature << dendl;
213 // copy parameters out of the cache
214
215 memcpy(decoding_matrix,
216 decode_tbls_map_it->second.second.decoding_matrix,
217 k * k * sizeof(int));
218 memcpy(dm_row,
219 decode_tbls_map_it->second.second.dm_row,
220 k * sizeof(int));
221 memcpy(dm_column,
222 decode_tbls_map_it->second.second.dm_column,
223 k * sizeof(int));
224 memcpy(minimum,
225 decode_tbls_map_it->second.second.minimum,
226 (k+m) * sizeof(int));
227
228 // find item in LRU queue and push back
229 decode_tbls_lru->splice(decode_tbls_lru->end(),
230 *decode_tbls_lru,
231 decode_tbls_map_it->second.first);
232 return true;
233}
234
235void
236ErasureCodeShecTableCache::putDecodingTableToCache(int* decoding_matrix,
237 int* dm_row,
238 int* dm_column,
239 int* minimum,
240 int technique,
241 int k,
242 int m,
243 int c,
244 int w,
245 int* erased,
246 int* avails) {
247 // --------------------------------------------------------------------------
248 // LRU decoding matrix cache
249 // --------------------------------------------------------------------------
250
251 Mutex::Locker lock(codec_tables_guard);
252
253 uint64_t signature = getDecodingCacheSignature(k, m, c, w, erased, avails);
254 dout(20) << "[ put table ] = " << signature << dendl;
255
256 // we store a new table to the cache
257
258 // bufferptr cachetable;
259
260 lru_map_t* decode_tbls_map =
261 getDecodingTables(technique);
262
263 lru_list_t* decode_tbls_lru =
264 getDecodingTablesLru(technique);
265
266 if (decode_tbls_map->count(signature)) {
267 dout(20) << "[ already on table ] = " << signature << dendl;
268
269 // find item in LRU queue and push back
270 decode_tbls_lru->splice(decode_tbls_lru->end(),
271 *decode_tbls_lru,
272 (*decode_tbls_map)[signature].first);
273 return;
274 }
275
276 // evt. shrink the LRU queue/map
277 if ((int)decode_tbls_lru->size() >=
278 ErasureCodeShecTableCache::decoding_tables_lru_length) {
279 dout(20) << "[ shrink lru ] = " << signature << dendl;
280 // remove from map
281 decode_tbls_map->erase(decode_tbls_lru->front());
282 // remove from lru
283 decode_tbls_lru->pop_front();
284 }
285
286 {
287 dout(20) << "[ store table ] = " << signature << dendl;
288
289 decode_tbls_lru->push_back(signature);
290
291 // allocate a new buffer
292 lru_list_t::iterator it_end = decode_tbls_lru->end();
293 --it_end;
294
295 lru_entry_t &map_value =
296 (*decode_tbls_map)[signature] =
297 std::make_pair(it_end, DecodingCacheParameter());
298 map_value.second.decoding_matrix = new int[k*k];
299 map_value.second.dm_row = new int[k];
300 map_value.second.dm_column = new int[k];
301 map_value.second.minimum = new int[k+m];
302
303 memcpy(map_value.second.decoding_matrix,
304 decoding_matrix,
305 k * k * sizeof(int));
306 memcpy(map_value.second.dm_row,
307 dm_row,
308 k * sizeof(int));
309 memcpy(map_value.second.dm_column,
310 dm_column,
311 k * sizeof(int));
312 memcpy(map_value.second.minimum,
313 minimum,
314 (k+m) * sizeof(int));
315
316 dout(20) << "[ cache size ] = " << decode_tbls_lru->size() << dendl;
317 }
318}