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