]>
Commit | Line | Data |
---|---|---|
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) 2013 Inktank Storage, Inc. | |
7 | * | |
8 | * This is free software; you can redistribute it and/or | |
9 | * modify it under the terms of the GNU Lesser General Public | |
10 | * License version 2.1, as published by the Free Software | |
11 | * Foundation. See file COPYING. | |
12 | * | |
13 | */ | |
14 | ||
15 | #ifndef ECUTIL_H | |
16 | #define ECUTIL_H | |
17 | ||
7c673cae FG |
18 | #include "erasure-code/ErasureCodeInterface.h" |
19 | #include "include/buffer_fwd.h" | |
20 | #include "include/assert.h" | |
21 | #include "include/encoding.h" | |
22 | #include "common/Formatter.h" | |
23 | ||
24 | namespace ECUtil { | |
25 | ||
7c673cae FG |
26 | class stripe_info_t { |
27 | const uint64_t stripe_width; | |
28 | const uint64_t chunk_size; | |
29 | public: | |
30 | stripe_info_t(uint64_t stripe_size, uint64_t stripe_width) | |
31 | : stripe_width(stripe_width), | |
32 | chunk_size(stripe_width / stripe_size) { | |
33 | assert(stripe_width % stripe_size == 0); | |
34 | } | |
35 | bool logical_offset_is_stripe_aligned(uint64_t logical) const { | |
36 | return (logical % stripe_width) == 0; | |
37 | } | |
38 | uint64_t get_stripe_width() const { | |
39 | return stripe_width; | |
40 | } | |
41 | uint64_t get_chunk_size() const { | |
42 | return chunk_size; | |
43 | } | |
44 | uint64_t logical_to_prev_chunk_offset(uint64_t offset) const { | |
45 | return (offset / stripe_width) * chunk_size; | |
46 | } | |
47 | uint64_t logical_to_next_chunk_offset(uint64_t offset) const { | |
48 | return ((offset + stripe_width - 1)/ stripe_width) * chunk_size; | |
49 | } | |
50 | uint64_t logical_to_prev_stripe_offset(uint64_t offset) const { | |
51 | return offset - (offset % stripe_width); | |
52 | } | |
53 | uint64_t logical_to_next_stripe_offset(uint64_t offset) const { | |
54 | return ((offset % stripe_width) ? | |
55 | (offset - (offset % stripe_width) + stripe_width) : | |
56 | offset); | |
57 | } | |
58 | uint64_t aligned_logical_offset_to_chunk_offset(uint64_t offset) const { | |
59 | assert(offset % stripe_width == 0); | |
60 | return (offset / stripe_width) * chunk_size; | |
61 | } | |
62 | uint64_t aligned_chunk_offset_to_logical_offset(uint64_t offset) const { | |
63 | assert(offset % chunk_size == 0); | |
64 | return (offset / chunk_size) * stripe_width; | |
65 | } | |
31f18b77 FG |
66 | std::pair<uint64_t, uint64_t> aligned_offset_len_to_chunk( |
67 | std::pair<uint64_t, uint64_t> in) const { | |
68 | return std::make_pair( | |
7c673cae FG |
69 | aligned_logical_offset_to_chunk_offset(in.first), |
70 | aligned_logical_offset_to_chunk_offset(in.second)); | |
71 | } | |
31f18b77 FG |
72 | std::pair<uint64_t, uint64_t> offset_len_to_stripe_bounds( |
73 | std::pair<uint64_t, uint64_t> in) const { | |
7c673cae FG |
74 | uint64_t off = logical_to_prev_stripe_offset(in.first); |
75 | uint64_t len = logical_to_next_stripe_offset( | |
76 | (in.first - off) + in.second); | |
31f18b77 | 77 | return std::make_pair(off, len); |
7c673cae FG |
78 | } |
79 | }; | |
80 | ||
81 | int decode( | |
82 | const stripe_info_t &sinfo, | |
83 | ErasureCodeInterfaceRef &ec_impl, | |
31f18b77 | 84 | std::map<int, bufferlist> &to_decode, |
7c673cae FG |
85 | bufferlist *out); |
86 | ||
87 | int decode( | |
88 | const stripe_info_t &sinfo, | |
89 | ErasureCodeInterfaceRef &ec_impl, | |
31f18b77 FG |
90 | std::map<int, bufferlist> &to_decode, |
91 | std::map<int, bufferlist*> &out); | |
7c673cae FG |
92 | |
93 | int encode( | |
94 | const stripe_info_t &sinfo, | |
95 | ErasureCodeInterfaceRef &ec_impl, | |
96 | bufferlist &in, | |
31f18b77 FG |
97 | const std::set<int> &want, |
98 | std::map<int, bufferlist> *out); | |
7c673cae FG |
99 | |
100 | class HashInfo { | |
101 | uint64_t total_chunk_size = 0; | |
31f18b77 | 102 | std::vector<uint32_t> cumulative_shard_hashes; |
7c673cae FG |
103 | |
104 | // purely ephemeral, represents the size once all in-flight ops commit | |
105 | uint64_t projected_total_chunk_size = 0; | |
106 | public: | |
107 | HashInfo() {} | |
108 | explicit HashInfo(unsigned num_chunks) : | |
109 | cumulative_shard_hashes(num_chunks, -1) {} | |
31f18b77 | 110 | void append(uint64_t old_size, std::map<int, bufferlist> &to_append); |
7c673cae FG |
111 | void clear() { |
112 | total_chunk_size = 0; | |
31f18b77 | 113 | cumulative_shard_hashes = std::vector<uint32_t>( |
7c673cae FG |
114 | cumulative_shard_hashes.size(), |
115 | -1); | |
116 | } | |
117 | void encode(bufferlist &bl) const; | |
118 | void decode(bufferlist::iterator &bl); | |
119 | void dump(Formatter *f) const; | |
31f18b77 | 120 | static void generate_test_instances(std::list<HashInfo*>& o); |
7c673cae FG |
121 | uint32_t get_chunk_hash(int shard) const { |
122 | assert((unsigned)shard < cumulative_shard_hashes.size()); | |
123 | return cumulative_shard_hashes[shard]; | |
124 | } | |
125 | uint64_t get_total_chunk_size() const { | |
126 | return total_chunk_size; | |
127 | } | |
128 | uint64_t get_projected_total_chunk_size() const { | |
129 | return projected_total_chunk_size; | |
130 | } | |
131 | uint64_t get_total_logical_size(const stripe_info_t &sinfo) const { | |
132 | return get_total_chunk_size() * | |
133 | (sinfo.get_stripe_width()/sinfo.get_chunk_size()); | |
134 | } | |
135 | uint64_t get_projected_total_logical_size(const stripe_info_t &sinfo) const { | |
136 | return get_projected_total_chunk_size() * | |
137 | (sinfo.get_stripe_width()/sinfo.get_chunk_size()); | |
138 | } | |
139 | void set_projected_total_logical_size( | |
140 | const stripe_info_t &sinfo, | |
141 | uint64_t logical_size) { | |
142 | assert(sinfo.logical_offset_is_stripe_aligned(logical_size)); | |
143 | projected_total_chunk_size = sinfo.aligned_logical_offset_to_chunk_offset( | |
144 | logical_size); | |
145 | } | |
146 | void set_total_chunk_size_clear_hash(uint64_t new_chunk_size) { | |
147 | cumulative_shard_hashes.clear(); | |
148 | total_chunk_size = new_chunk_size; | |
149 | } | |
150 | bool has_chunk_hash() const { | |
151 | return !cumulative_shard_hashes.empty(); | |
152 | } | |
153 | void update_to(const HashInfo &rhs) { | |
154 | auto ptcs = projected_total_chunk_size; | |
155 | *this = rhs; | |
156 | projected_total_chunk_size = ptcs; | |
157 | } | |
158 | }; | |
159 | ||
160 | typedef ceph::shared_ptr<HashInfo> HashInfoRef; | |
161 | ||
31f18b77 FG |
162 | bool is_hinfo_key_string(const std::string &key); |
163 | const std::string &get_hinfo_key(); | |
7c673cae FG |
164 | |
165 | } | |
166 | WRITE_CLASS_ENCODER(ECUtil::HashInfo) | |
167 | #endif |