]> git.proxmox.com Git - ceph.git/blob - ceph/src/erasure-code/isa/ErasureCodeIsaTableCache.cc
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / erasure-code / isa / ErasureCodeIsaTableCache.cc
1 /*
2 * Ceph - scalable distributed file system
3 *
4 * Copyright (C) 2014 CERN (Switzerland)
5 *
6 * Author: Andreas-Joachim Peters <Andreas.Joachim.Peters@cern.ch>
7 *
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
12 *
13 */
14
15
16 /**
17 * @file ErasureCodeIsaTableCache.cc
18 *
19 * @brief Erasure Code Isa CODEC Table Cache
20 *
21 * The INTEL ISA-L library supports two pre-defined encoding matrices (cauchy = default, reed_sol_van = default)
22 * The default CODEC implementation using these two matrices is implemented in class ErasureCodeIsaDefault.
23 * ISA-L allows to use custom matrices which might be added later as implementations deriving from the base class ErasoreCodeIsa.
24 */
25
26 // -----------------------------------------------------------------------------
27 #include "ErasureCodeIsaTableCache.h"
28 #include "ErasureCodeIsa.h"
29 #include "common/debug.h"
30 // -----------------------------------------------------------------------------
31
32 // -----------------------------------------------------------------------------
33 #define dout_context g_ceph_context
34 #define dout_subsys ceph_subsys_osd
35 #undef dout_prefix
36 #define dout_prefix _tc_prefix(_dout)
37 // -----------------------------------------------------------------------------
38
39 // -----------------------------------------------------------------------------
40
41 static ostream&
42 _tc_prefix(std::ostream* _dout)
43 {
44 return *_dout << "ErasureCodeIsaTableCache: ";
45 }
46
47 // -----------------------------------------------------------------------------
48
49 ErasureCodeIsaTableCache::~ErasureCodeIsaTableCache()
50 {
51 Mutex::Locker lock(codec_tables_guard);
52
53 codec_technique_tables_t::const_iterator ttables_it;
54 codec_tables_t::const_iterator tables_it;
55 codec_table_t::const_iterator table_it;
56
57 std::map<int, lru_map_t*>::const_iterator lru_map_it;
58 std::map<int, lru_list_t*>::const_iterator lru_list_it;
59
60 // clean-up all allocated tables
61 for (ttables_it = encoding_coefficient.begin(); ttables_it != encoding_coefficient.end(); ++ttables_it) {
62 for (tables_it = ttables_it->second.begin(); tables_it != ttables_it->second.end(); ++tables_it) {
63 for (table_it = tables_it->second.begin(); table_it != tables_it->second.end(); ++table_it) {
64 if (table_it->second) {
65 if (*(table_it->second)) {
66 delete *(table_it->second);
67 }
68 delete table_it->second;
69 }
70 }
71 }
72 }
73
74 for (ttables_it = encoding_table.begin(); ttables_it != encoding_table.end(); ++ttables_it) {
75 for (tables_it = ttables_it->second.begin(); tables_it != ttables_it->second.end(); ++tables_it) {
76 for (table_it = tables_it->second.begin(); table_it != tables_it->second.end(); ++table_it) {
77 if (table_it->second) {
78 if (*(table_it->second)) {
79 delete *(table_it->second);
80 }
81 delete table_it->second;
82 }
83 }
84 }
85 }
86
87 for (lru_map_it = decoding_tables.begin(); lru_map_it != decoding_tables.end(); ++lru_map_it) {
88 if (lru_map_it->second) {
89 delete lru_map_it->second;
90 }
91 }
92
93 for (lru_list_it = decoding_tables_lru.begin(); lru_list_it != decoding_tables_lru.end(); ++lru_list_it) {
94 if (lru_list_it->second) {
95 delete lru_list_it->second;
96 }
97 }
98 }
99
100 // -----------------------------------------------------------------------------
101
102 int
103 ErasureCodeIsaTableCache::getDecodingTableCacheSize(int matrixtype)
104 {
105 Mutex::Locker lock(codec_tables_guard);
106 if (decoding_tables[matrixtype])
107 return decoding_tables[matrixtype]->size();
108 else
109 return -1;
110 }
111
112 // -----------------------------------------------------------------------------
113
114 ErasureCodeIsaTableCache::lru_map_t*
115 ErasureCodeIsaTableCache::getDecodingTables(int matrix_type)
116 {
117 // the caller must hold the guard mutex:
118 // => Mutex::Locker lock(codec_tables_guard);
119
120 // create an lru_map if not yet allocated
121 if (!decoding_tables[matrix_type]) {
122 decoding_tables[matrix_type] = new lru_map_t;
123 }
124 return decoding_tables[matrix_type];
125 }
126
127 // -----------------------------------------------------------------------------
128
129 ErasureCodeIsaTableCache::lru_list_t*
130 ErasureCodeIsaTableCache::getDecodingTablesLru(int matrix_type)
131 {
132 // the caller must hold the guard mutex:
133 // => Mutex::Locker lock(codec_tables_guard);
134
135 // create an lru_list if not yet allocated
136 if (!decoding_tables_lru[matrix_type]) {
137 decoding_tables_lru[matrix_type] = new lru_list_t;
138 }
139 return decoding_tables_lru[matrix_type];
140 }
141
142 // -----------------------------------------------------------------------------
143
144 unsigned char**
145 ErasureCodeIsaTableCache::getEncodingTable(int matrix, int k, int m)
146 {
147 Mutex::Locker lock(codec_tables_guard);
148 return getEncodingTableNoLock(matrix,k,m);
149 }
150
151 // -----------------------------------------------------------------------------
152
153 unsigned char**
154 ErasureCodeIsaTableCache::getEncodingTableNoLock(int matrix, int k, int m)
155 {
156 // create a pointer to store an encoding table address
157 if (!encoding_table[matrix][k][m]) {
158 encoding_table[matrix][k][m] = new (unsigned char*);
159 *encoding_table[matrix][k][m] = 0;
160 }
161 return encoding_table[matrix][k][m];
162 }
163
164 // -----------------------------------------------------------------------------
165
166 unsigned char**
167 ErasureCodeIsaTableCache::getEncodingCoefficient(int matrix, int k, int m)
168 {
169 Mutex::Locker lock(codec_tables_guard);
170 return getEncodingCoefficientNoLock(matrix,k,m);
171 }
172
173 // -----------------------------------------------------------------------------
174
175 unsigned char**
176 ErasureCodeIsaTableCache::getEncodingCoefficientNoLock(int matrix, int k, int m)
177 {
178 // create a pointer to store an encoding coefficients adddress
179 if (!encoding_coefficient[matrix][k][m]) {
180 encoding_coefficient[matrix][k][m] = new (unsigned char*);
181 *encoding_coefficient[matrix][k][m] = 0;
182 }
183 return encoding_coefficient[matrix][k][m];
184 }
185
186 // -----------------------------------------------------------------------------
187
188 unsigned char*
189 ErasureCodeIsaTableCache::setEncodingTable(int matrix, int k, int m, unsigned char* ec_in_table)
190 {
191 Mutex::Locker lock(codec_tables_guard);
192 unsigned char** ec_out_table = getEncodingTableNoLock(matrix, k, m);
193 if (*ec_out_table) {
194 // somebody might have deposited this table in the meanwhile, so clean
195 // the input table and return the stored one
196 free (ec_in_table);
197 return *ec_out_table;
198 } else {
199 // we store the provided input table and return this one
200 *encoding_table[matrix][k][m] = ec_in_table;
201 return ec_in_table;
202 }
203 }
204
205 // -----------------------------------------------------------------------------
206
207 unsigned char*
208 ErasureCodeIsaTableCache::setEncodingCoefficient(int matrix, int k, int m, unsigned char* ec_in_coeff)
209 {
210 Mutex::Locker lock(codec_tables_guard);
211 unsigned char** ec_out_coeff = getEncodingCoefficientNoLock(matrix, k, m);
212 if (*ec_out_coeff) {
213 // somebody might have deposited these coefficients in the meanwhile, so clean
214 // the input coefficients and return the stored ones
215 free (ec_in_coeff);
216 return *ec_out_coeff;
217 } else {
218 // we store the provided input coefficients and return these
219 *encoding_coefficient[matrix][k][m] = ec_in_coeff;
220 return ec_in_coeff;
221 }
222 }
223
224 // -----------------------------------------------------------------------------
225
226 Mutex*
227 ErasureCodeIsaTableCache::getLock()
228 {
229 return &codec_tables_guard;
230 }
231
232 // -----------------------------------------------------------------------------
233
234 bool
235 ErasureCodeIsaTableCache::getDecodingTableFromCache(std::string &signature,
236 unsigned char* &table,
237 int matrixtype,
238 int k,
239 int m)
240 {
241 // --------------------------------------------------------------------------
242 // LRU decoding matrix cache
243 // --------------------------------------------------------------------------
244
245 dout(12) << "[ get table ] = " << signature << dendl;
246
247 // we try to fetch a decoding table from an LRU cache
248 bool found = false;
249
250 Mutex::Locker lock(codec_tables_guard);
251
252 lru_map_t* decode_tbls_map =
253 getDecodingTables(matrixtype);
254
255 lru_list_t* decode_tbls_lru =
256 getDecodingTablesLru(matrixtype);
257
258 if (decode_tbls_map->count(signature)) {
259 dout(12) << "[ cached table ] = " << signature << dendl;
260 // copy the table out of the cache
261 memcpy(table, (*decode_tbls_map)[signature].second.c_str(), k * (m + k)*32);
262 // find item in LRU queue and push back
263 dout(12) << "[ cache size ] = " << decode_tbls_lru->size() << dendl;
264 decode_tbls_lru->splice( (decode_tbls_lru->begin()), *decode_tbls_lru, (*decode_tbls_map)[signature].first);
265 found = true;
266 }
267
268 return found;
269 }
270
271 // -----------------------------------------------------------------------------
272
273 void
274 ErasureCodeIsaTableCache::putDecodingTableToCache(std::string &signature,
275 unsigned char* &table,
276 int matrixtype,
277 int k,
278 int m)
279 {
280 // --------------------------------------------------------------------------
281 // LRU decoding matrix cache
282 // --------------------------------------------------------------------------
283
284 dout(12) << "[ put table ] = " << signature << dendl;
285
286 // we store a new table to the cache
287
288 bufferptr cachetable;
289
290 Mutex::Locker lock(codec_tables_guard);
291
292 lru_map_t* decode_tbls_map =
293 getDecodingTables(matrixtype);
294
295 lru_list_t* decode_tbls_lru =
296 getDecodingTablesLru(matrixtype);
297
298 // evt. shrink the LRU queue/map
299 if ((int) decode_tbls_lru->size() >= ErasureCodeIsaTableCache::decoding_tables_lru_length) {
300 dout(12) << "[ shrink lru ] = " << signature << dendl;
301 // reuse old buffer
302 cachetable = (*decode_tbls_map)[decode_tbls_lru->back()].second;
303
304 if ((int) cachetable.length() != (k * (m + k)*32)) {
305 // we need to replace this with a different size buffer
306 cachetable = buffer::create(k * (m + k)*32);
307 }
308
309 // remove from map
310 decode_tbls_map->erase(decode_tbls_lru->back());
311 // remove from lru
312 decode_tbls_lru->pop_back();
313 // add to the head of lru
314 decode_tbls_lru->push_front(signature);
315 // add the new to the map
316 (*decode_tbls_map)[signature] = std::make_pair(decode_tbls_lru->begin(), cachetable);
317 } else {
318 dout(12) << "[ store table ] = " << signature << dendl;
319 // allocate a new buffer
320 cachetable = buffer::create(k * (m + k)*32);
321 decode_tbls_lru->push_front(signature);
322 (*decode_tbls_map)[signature] = std::make_pair(decode_tbls_lru->begin(), cachetable);
323 dout(12) << "[ cache size ] = " << decode_tbls_lru->size() << dendl;
324 }
325
326 // copy-in the new table
327 memcpy(cachetable.c_str(), table, k * (m + k)*32);
328 }