Fix some bugs when testing opensds ansible
[stor4nfv.git] / src / 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 "common/debug.h"
29 // -----------------------------------------------------------------------------
30
31 // -----------------------------------------------------------------------------
32 #define dout_context g_ceph_context
33 #define dout_subsys ceph_subsys_osd
34 #undef dout_prefix
35 #define dout_prefix _tc_prefix(_dout)
36 // -----------------------------------------------------------------------------
37
38 // -----------------------------------------------------------------------------
39
40 static ostream&
41 _tc_prefix(std::ostream* _dout)
42 {
43   return *_dout << "ErasureCodeIsaTableCache: ";
44 }
45
46 // -----------------------------------------------------------------------------
47
48 ErasureCodeIsaTableCache::~ErasureCodeIsaTableCache()
49 {
50   Mutex::Locker lock(codec_tables_guard);
51
52   codec_technique_tables_t::const_iterator ttables_it;
53   codec_tables_t::const_iterator tables_it;
54   codec_table_t::const_iterator table_it;
55
56   std::map<int, lru_map_t*>::const_iterator lru_map_it;
57   std::map<int, lru_list_t*>::const_iterator lru_list_it;
58
59   // clean-up all allocated tables
60   for (ttables_it = encoding_coefficient.begin(); ttables_it != encoding_coefficient.end(); ++ttables_it) {
61     for (tables_it = ttables_it->second.begin(); tables_it != ttables_it->second.end(); ++tables_it) {
62       for (table_it = tables_it->second.begin(); table_it != tables_it->second.end(); ++table_it) {
63         if (table_it->second) {
64           if (*(table_it->second)) {
65             delete *(table_it->second);
66           }
67           delete table_it->second;
68         }
69       }
70     }
71   }
72
73   for (ttables_it = encoding_table.begin(); ttables_it != encoding_table.end(); ++ttables_it) {
74     for (tables_it = ttables_it->second.begin(); tables_it != ttables_it->second.end(); ++tables_it) {
75       for (table_it = tables_it->second.begin(); table_it != tables_it->second.end(); ++table_it) {
76         if (table_it->second) {
77           if (*(table_it->second)) {
78             delete *(table_it->second);
79           }
80           delete table_it->second;
81         }
82       }
83     }
84   }
85
86   for (lru_map_it = decoding_tables.begin(); lru_map_it != decoding_tables.end(); ++lru_map_it) {
87     if (lru_map_it->second) {
88       delete lru_map_it->second;
89     }
90   }
91
92   for (lru_list_it = decoding_tables_lru.begin(); lru_list_it != decoding_tables_lru.end(); ++lru_list_it) {
93     if (lru_list_it->second) {
94       delete lru_list_it->second;
95     }
96   }
97 }
98
99 // -----------------------------------------------------------------------------
100
101 int
102 ErasureCodeIsaTableCache::getDecodingTableCacheSize(int matrixtype)
103 {
104   Mutex::Locker lock(codec_tables_guard);
105   if (decoding_tables[matrixtype])
106     return decoding_tables[matrixtype]->size();
107   else
108     return -1;
109 }
110
111 // -----------------------------------------------------------------------------
112
113 ErasureCodeIsaTableCache::lru_map_t*
114 ErasureCodeIsaTableCache::getDecodingTables(int matrix_type)
115 {
116   // the caller must hold the guard mutex:
117   // => Mutex::Locker lock(codec_tables_guard);
118
119   // create an lru_map if not yet allocated
120   if (!decoding_tables[matrix_type]) {
121     decoding_tables[matrix_type] = new lru_map_t;
122   }
123   return decoding_tables[matrix_type];
124 }
125
126 // -----------------------------------------------------------------------------
127
128 ErasureCodeIsaTableCache::lru_list_t*
129 ErasureCodeIsaTableCache::getDecodingTablesLru(int matrix_type)
130 {
131   // the caller must hold the guard mutex:
132   // => Mutex::Locker lock(codec_tables_guard);
133
134   // create an lru_list if not yet allocated
135   if (!decoding_tables_lru[matrix_type]) {
136     decoding_tables_lru[matrix_type] = new lru_list_t;
137   }
138   return decoding_tables_lru[matrix_type];
139 }
140
141 // -----------------------------------------------------------------------------
142
143 unsigned char**
144 ErasureCodeIsaTableCache::getEncodingTable(int matrix, int k, int m)
145 {
146   Mutex::Locker lock(codec_tables_guard);
147   return getEncodingTableNoLock(matrix,k,m);
148 }
149
150 // -----------------------------------------------------------------------------
151
152 unsigned char**
153 ErasureCodeIsaTableCache::getEncodingTableNoLock(int matrix, int k, int m)
154 {
155   // create a pointer to store an encoding table address
156   if (!encoding_table[matrix][k][m]) {
157     encoding_table[matrix][k][m] = new (unsigned char*);
158     *encoding_table[matrix][k][m] = 0;
159   }
160   return encoding_table[matrix][k][m];
161 }
162
163 // -----------------------------------------------------------------------------
164
165 unsigned char**
166 ErasureCodeIsaTableCache::getEncodingCoefficient(int matrix, int k, int m)
167 {
168   Mutex::Locker lock(codec_tables_guard);
169   return getEncodingCoefficientNoLock(matrix,k,m);
170 }
171
172 // -----------------------------------------------------------------------------
173
174 unsigned char**
175 ErasureCodeIsaTableCache::getEncodingCoefficientNoLock(int matrix, int k, int m)
176 {
177   // create a pointer to store an encoding coefficients adddress
178   if (!encoding_coefficient[matrix][k][m]) {
179     encoding_coefficient[matrix][k][m] = new (unsigned char*);
180     *encoding_coefficient[matrix][k][m] = 0;
181   }
182   return encoding_coefficient[matrix][k][m];
183 }
184
185 // -----------------------------------------------------------------------------
186
187 unsigned char*
188 ErasureCodeIsaTableCache::setEncodingTable(int matrix, int k, int m, unsigned char* ec_in_table)
189 {
190   Mutex::Locker lock(codec_tables_guard);
191   unsigned char** ec_out_table = getEncodingTableNoLock(matrix, k, m);
192   if (*ec_out_table) {
193     // somebody might have deposited this table in the meanwhile, so clean
194     // the input table and return the stored one
195     free (ec_in_table);
196     return *ec_out_table;
197   } else {
198     // we store the provided input table and return this one
199     *encoding_table[matrix][k][m] = ec_in_table;
200     return ec_in_table;
201   }
202 }
203
204 // -----------------------------------------------------------------------------
205
206 unsigned char*
207 ErasureCodeIsaTableCache::setEncodingCoefficient(int matrix, int k, int m, unsigned char* ec_in_coeff)
208 {
209   Mutex::Locker lock(codec_tables_guard);
210   unsigned char** ec_out_coeff = getEncodingCoefficientNoLock(matrix, k, m);
211   if (*ec_out_coeff) {
212     // somebody might have deposited these coefficients in the meanwhile, so clean
213     // the input coefficients and return the stored ones
214     free (ec_in_coeff);
215     return *ec_out_coeff;
216   } else {
217     // we store the provided input coefficients and return these
218     *encoding_coefficient[matrix][k][m] = ec_in_coeff;
219     return ec_in_coeff;
220   }
221 }
222
223 // -----------------------------------------------------------------------------
224
225 Mutex*
226 ErasureCodeIsaTableCache::getLock()
227 {
228   return &codec_tables_guard;
229 }
230
231 // -----------------------------------------------------------------------------
232
233 bool
234 ErasureCodeIsaTableCache::getDecodingTableFromCache(std::string &signature,
235                                                     unsigned char* &table,
236                                                     int matrixtype,
237                                                     int k,
238                                                     int m)
239 {
240   // --------------------------------------------------------------------------
241   // LRU decoding matrix cache
242   // --------------------------------------------------------------------------
243
244   dout(12) << "[ get table    ] = " << signature << dendl;
245
246   // we try to fetch a decoding table from an LRU cache
247   bool found = false;
248
249   Mutex::Locker lock(codec_tables_guard);
250
251   lru_map_t* decode_tbls_map =
252     getDecodingTables(matrixtype);
253
254   lru_list_t* decode_tbls_lru =
255     getDecodingTablesLru(matrixtype);
256
257   if (decode_tbls_map->count(signature)) {
258     dout(12) << "[ cached table ] = " << signature << dendl;
259     // copy the table out of the cache
260     memcpy(table, (*decode_tbls_map)[signature].second.c_str(), k * (m + k)*32);
261     // find item in LRU queue and push back
262     dout(12) << "[ cache size   ] = " << decode_tbls_lru->size() << dendl;
263     decode_tbls_lru->splice( (decode_tbls_lru->begin()), *decode_tbls_lru, (*decode_tbls_map)[signature].first);
264     found = true;
265   }
266
267   return found;
268 }
269
270 // -----------------------------------------------------------------------------
271
272 void
273 ErasureCodeIsaTableCache::putDecodingTableToCache(std::string &signature,
274                                                   unsigned char* &table,
275                                                   int matrixtype,
276                                                   int k,
277                                                   int m)
278 {
279   // --------------------------------------------------------------------------
280   // LRU decoding matrix cache
281   // --------------------------------------------------------------------------
282
283   dout(12) << "[ put table    ] = " << signature << dendl;
284
285   // we store a new table to the cache
286
287   bufferptr cachetable;
288
289   Mutex::Locker lock(codec_tables_guard);
290
291   lru_map_t* decode_tbls_map =
292     getDecodingTables(matrixtype);
293
294   lru_list_t* decode_tbls_lru =
295     getDecodingTablesLru(matrixtype);
296
297   // evt. shrink the LRU queue/map
298   if ((int) decode_tbls_lru->size() >= ErasureCodeIsaTableCache::decoding_tables_lru_length) {
299     dout(12) << "[ shrink lru   ] = " << signature << dendl;
300     // reuse old buffer
301     cachetable = (*decode_tbls_map)[decode_tbls_lru->back()].second;
302
303     if ((int) cachetable.length() != (k * (m + k)*32)) {
304       // we need to replace this with a different size buffer
305       cachetable = buffer::create(k * (m + k)*32);
306     }
307
308     // remove from map
309     decode_tbls_map->erase(decode_tbls_lru->back());
310     // remove from lru
311     decode_tbls_lru->pop_back();
312     // add to the head of lru
313     decode_tbls_lru->push_front(signature);
314     // add the new to the map
315     (*decode_tbls_map)[signature] = std::make_pair(decode_tbls_lru->begin(), cachetable);
316   } else {
317     dout(12) << "[ store table  ] = " << signature << dendl;
318     // allocate a new buffer
319     cachetable = buffer::create(k * (m + k)*32);
320     decode_tbls_lru->push_front(signature);
321     (*decode_tbls_map)[signature] = std::make_pair(decode_tbls_lru->begin(), cachetable);
322     dout(12) << "[ cache size   ] = " << decode_tbls_lru->size() << dendl;
323   }
324
325   // copy-in the new table
326   memcpy(cachetable.c_str(), table, k * (m + k)*32);
327 }