ceph/src/osd/ECUtil.h
Daniel J. Hofmann 60b1071d64 Removed extra semicolons
Signed-off-by: Daniel J. Hofmann <daniel@trvx.org>
2014-05-09 15:07:15 +02:00

155 lines
4.6 KiB
C++

// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
// vim: ts=8 sw=2 smarttab
/*
* Ceph - scalable distributed file system
*
* Copyright (C) 2013 Inktank Storage, Inc.
*
* This is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License version 2.1, as published by the Free Software
* Foundation. See file COPYING.
*
*/
#ifndef ECUTIL_H
#define ECUTIL_H
#include <map>
#include <set>
#include "include/memory.h"
#include "erasure-code/ErasureCodeInterface.h"
#include "include/buffer.h"
#include "include/assert.h"
#include "include/encoding.h"
#include "common/Formatter.h"
namespace ECUtil {
const uint64_t CHUNK_ALIGNMENT = 64;
const uint64_t CHUNK_INFO = 8;
const uint64_t CHUNK_PADDING = 8;
const uint64_t CHUNK_OVERHEAD = 16; // INFO + PADDING
class stripe_info_t {
const uint64_t stripe_size;
const uint64_t stripe_width;
const uint64_t chunk_size;
public:
stripe_info_t(uint64_t stripe_size, uint64_t stripe_width)
: stripe_size(stripe_size), stripe_width(stripe_width),
chunk_size(stripe_width / stripe_size) {
assert(stripe_width % stripe_size == 0);
}
uint64_t get_stripe_width() const {
return stripe_width;
}
uint64_t get_chunk_size() const {
return chunk_size;
}
uint64_t logical_to_prev_chunk_offset(uint64_t offset) const {
return (offset / stripe_width) * chunk_size;
}
uint64_t logical_to_next_chunk_offset(uint64_t offset) const {
return ((offset + stripe_width - 1)/ stripe_width) * chunk_size;
}
uint64_t logical_to_prev_stripe_offset(uint64_t offset) const {
return offset - (offset % stripe_width);
}
uint64_t logical_to_next_stripe_offset(uint64_t offset) const {
return ((offset % stripe_width) ?
(offset - (offset % stripe_width) + stripe_width) :
offset);
}
uint64_t aligned_logical_offset_to_chunk_offset(uint64_t offset) const {
assert(offset % stripe_width == 0);
return (offset / stripe_width) * chunk_size;
}
uint64_t aligned_chunk_offset_to_logical_offset(uint64_t offset) const {
assert(offset % chunk_size == 0);
return (offset / chunk_size) * stripe_width;
}
pair<uint64_t, uint64_t> aligned_offset_len_to_chunk(
pair<uint64_t, uint64_t> in) const {
return make_pair(
aligned_logical_offset_to_chunk_offset(in.first),
aligned_logical_offset_to_chunk_offset(in.second));
}
pair<uint64_t, uint64_t> offset_len_to_stripe_bounds(
pair<uint64_t, uint64_t> in) const {
uint64_t off = logical_to_prev_stripe_offset(in.first);
uint64_t len = logical_to_next_stripe_offset(
(in.first - off) + in.second);
return make_pair(off, len);
}
};
int decode(
const stripe_info_t &sinfo,
ErasureCodeInterfaceRef &ec_impl,
map<int, bufferlist> &to_decode,
bufferlist *out);
int decode(
const stripe_info_t &sinfo,
ErasureCodeInterfaceRef &ec_impl,
map<int, bufferlist> &to_decode,
map<int, bufferlist*> &out);
int encode(
const stripe_info_t &sinfo,
ErasureCodeInterfaceRef &ec_impl,
bufferlist &in,
const set<int> &want,
map<int, bufferlist> *out);
class HashInfo {
uint64_t total_chunk_size;
vector<uint32_t> cumulative_shard_hashes;
public:
HashInfo() : total_chunk_size(0) {}
HashInfo(unsigned num_chunks)
: total_chunk_size(0),
cumulative_shard_hashes(num_chunks, -1) {}
void append(uint64_t old_size, map<int, bufferlist> &to_append) {
assert(to_append.size() == cumulative_shard_hashes.size());
assert(old_size == total_chunk_size);
uint64_t size_to_append = to_append.begin()->second.length();
for (map<int, bufferlist>::iterator i = to_append.begin();
i != to_append.end();
++i) {
assert(size_to_append == i->second.length());
assert((unsigned)i->first < cumulative_shard_hashes.size());
uint32_t new_hash = i->second.crc32c(cumulative_shard_hashes[i->first]);
cumulative_shard_hashes[i->first] = new_hash;
}
total_chunk_size += size_to_append;
}
void clear() {
total_chunk_size = 0;
cumulative_shard_hashes = vector<uint32_t>(
cumulative_shard_hashes.size(),
-1);
}
void encode(bufferlist &bl) const;
void decode(bufferlist::iterator &bl);
void dump(Formatter *f) const;
static void generate_test_instances(list<HashInfo*>& o);
uint32_t get_chunk_hash(int shard) const {
assert((unsigned)shard < cumulative_shard_hashes.size());
return cumulative_shard_hashes[shard];
}
uint64_t get_total_chunk_size() const {
return total_chunk_size;
}
};
typedef ceph::shared_ptr<HashInfo> HashInfoRef;
bool is_hinfo_key_string(const string &key);
const string &get_hinfo_key();
}
WRITE_CLASS_ENCODER(ECUtil::HashInfo)
#endif