| 290 | const string ErasureCodeLrc::DEFAULT_KML("-1"); |
| 291 | |
| 292 | int ErasureCodeLrc::parse_kml(ErasureCodeProfile &profile, |
| 293 | ostream *ss) |
| 294 | { |
| 295 | int err = ErasureCode::parse(profile, ss); |
| 296 | const int DEFAULT_INT = -1; |
| 297 | int k, m, l; |
| 298 | err |= to_int("k", profile, &k, DEFAULT_KML, ss); |
| 299 | err |= to_int("m", profile, &m, DEFAULT_KML, ss); |
| 300 | err |= to_int("l", profile, &l, DEFAULT_KML, ss); |
| 301 | |
| 302 | if (k == DEFAULT_INT && m == DEFAULT_INT && l == DEFAULT_INT) |
| 303 | return err; |
| 304 | |
| 305 | if ((k != DEFAULT_INT || m != DEFAULT_INT || l != DEFAULT_INT) && |
| 306 | (k == DEFAULT_INT || m == DEFAULT_INT || l == DEFAULT_INT)) { |
| 307 | *ss << "All of k, m, l must be set or none of them in " |
| 308 | << profile << std::endl; |
| 309 | return ERROR_LRC_ALL_OR_NOTHING; |
| 310 | } |
| 311 | |
| 312 | const char *generated[] = { "mapping", |
| 313 | "layers", |
| 314 | "crush-steps" }; |
| 315 | |
| 316 | for (int i = 0; i < 3; i++) { |
| 317 | if (profile.count(generated[i])) { |
| 318 | *ss << "The " << generated[i] << " parameter cannot be set " |
| 319 | << "when k, m, l are set in " << profile << std::endl; |
| 320 | return ERROR_LRC_GENERATED; |
| 321 | } |
| 322 | } |
| 323 | |
| 324 | if (l == 0 || (k + m) % l) { |
| 325 | *ss << "k + m must be a multiple of l in " |
| 326 | << profile << std::endl; |
| 327 | return ERROR_LRC_K_M_MODULO; |
| 328 | } |
| 329 | |
| 330 | int local_group_count = (k + m) / l; |
| 331 | |
| 332 | if (k % local_group_count) { |
| 333 | *ss << "k must be a multiple of (k + m) / l in " |
| 334 | << profile << std::endl; |
| 335 | return ERROR_LRC_K_MODULO; |
| 336 | } |
| 337 | |
| 338 | if (m % local_group_count) { |
| 339 | *ss << "m must be a multiple of (k + m) / l in " |
| 340 | << profile << std::endl; |
| 341 | return ERROR_LRC_M_MODULO; |
| 342 | } |
| 343 | |
| 344 | string mapping; |
| 345 | for (int i = 0; i < local_group_count; i++) { |
| 346 | mapping += string(k / local_group_count, 'D') + |
| 347 | string(m / local_group_count, '_') + "_"; |
| 348 | } |
| 349 | profile["mapping"] = mapping; |