]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- |
2 | #include "include/interval_set.h" | |
3 | #include "include/buffer.h" | |
4 | #include <list> | |
5 | #include <map> | |
6 | #include <set> | |
7 | #include <iostream> | |
8 | ||
9 | #include "Object.h" | |
10 | ||
11 | void ContDesc::encode(bufferlist &bl) const | |
12 | { | |
13 | ENCODE_START(1, 1, bl); | |
14 | ::encode(objnum, bl); | |
15 | ::encode(cursnap, bl); | |
16 | ::encode(seqnum, bl); | |
17 | ::encode(prefix, bl); | |
18 | ::encode(oid, bl); | |
19 | ENCODE_FINISH(bl); | |
20 | } | |
21 | ||
22 | void ContDesc::decode(bufferlist::iterator &bl) | |
23 | { | |
24 | DECODE_START(1, bl); | |
25 | ::decode(objnum, bl); | |
26 | ::decode(cursnap, bl); | |
27 | ::decode(seqnum, bl); | |
28 | ::decode(prefix, bl); | |
29 | ::decode(oid, bl); | |
30 | DECODE_FINISH(bl); | |
31 | } | |
32 | ||
33 | std::ostream &operator<<(std::ostream &out, const ContDesc &rhs) | |
34 | { | |
35 | return out << "(ObjNum " << rhs.objnum | |
36 | << " snap " << rhs.cursnap | |
37 | << " seq_num " << rhs.seqnum | |
7c673cae FG |
38 | << ")"; |
39 | } | |
40 | ||
41 | void AppendGenerator::get_ranges_map( | |
42 | const ContDesc &cont, std::map<uint64_t, uint64_t> &out) { | |
43 | RandWrap rand(cont.seqnum); | |
44 | uint64_t pos = off; | |
45 | uint64_t limit = off + get_append_size(cont); | |
46 | while (pos < limit) { | |
47 | uint64_t segment_length = round_up( | |
48 | rand() % (max_append_size - min_append_size), | |
49 | alignment) + min_append_size; | |
50 | assert(segment_length >= min_append_size); | |
51 | if (segment_length + pos > limit) { | |
52 | segment_length = limit - pos; | |
53 | } | |
54 | if (alignment) | |
55 | assert(segment_length % alignment == 0); | |
56 | out.insert(std::pair<uint64_t, uint64_t>(pos, segment_length)); | |
57 | pos += segment_length; | |
58 | } | |
59 | } | |
60 | ||
61 | void VarLenGenerator::get_ranges_map( | |
62 | const ContDesc &cont, std::map<uint64_t, uint64_t> &out) { | |
63 | RandWrap rand(cont.seqnum); | |
64 | uint64_t pos = 0; | |
65 | uint64_t limit = get_length(cont); | |
66 | bool include = false; | |
67 | while (pos < limit) { | |
68 | uint64_t segment_length = (rand() % (max_stride_size - min_stride_size)) + min_stride_size; | |
69 | assert(segment_length < max_stride_size); | |
70 | assert(segment_length >= min_stride_size); | |
71 | if (segment_length + pos > limit) { | |
72 | segment_length = limit - pos; | |
73 | } | |
74 | if (include) { | |
75 | out.insert(std::pair<uint64_t, uint64_t>(pos, segment_length)); | |
76 | include = false; | |
77 | } else { | |
78 | include = true; | |
79 | } | |
80 | pos += segment_length; | |
81 | } | |
82 | } | |
83 | ||
84 | void ObjectDesc::iterator::adjust_stack() { | |
85 | while (!stack.empty() && pos >= stack.front().second.next) { | |
86 | assert(pos == stack.front().second.next); | |
87 | size = stack.front().second.size; | |
88 | current = stack.front().first; | |
89 | stack.pop_front(); | |
90 | } | |
91 | ||
92 | if (stack.empty()) { | |
93 | cur_valid_till = std::numeric_limits<uint64_t>::max(); | |
94 | } else { | |
95 | cur_valid_till = stack.front().second.next; | |
96 | } | |
97 | ||
98 | while (current != layers.end() && !current->covers(pos)) { | |
99 | uint64_t next = current->next(pos); | |
100 | if (next < cur_valid_till) { | |
101 | stack.push_front( | |
102 | make_pair( | |
103 | current, | |
104 | StackState{next, size} | |
105 | ) | |
106 | ); | |
107 | cur_valid_till = next; | |
108 | } | |
109 | ||
110 | ++current; | |
111 | } | |
112 | ||
113 | if (current == layers.end()) { | |
114 | size = 0; | |
115 | } else { | |
116 | current->iter.seek(pos); | |
117 | size = std::min(size, current->get_size()); | |
118 | cur_valid_till = std::min( | |
119 | current->valid_till(pos), | |
120 | cur_valid_till); | |
121 | } | |
122 | } | |
123 | ||
124 | const ContDesc &ObjectDesc::most_recent() { | |
125 | return layers.begin()->second; | |
126 | } | |
127 | ||
128 | void ObjectDesc::update(ContentsGenerator *gen, const ContDesc &next) { | |
129 | layers.push_front(std::pair<ceph::shared_ptr<ContentsGenerator>, ContDesc>(ceph::shared_ptr<ContentsGenerator>(gen), next)); | |
130 | return; | |
131 | } | |
132 | ||
133 | bool ObjectDesc::check(bufferlist &to_check) { | |
134 | iterator objiter = begin(); | |
135 | uint64_t error_at = 0; | |
136 | if (!objiter.check_bl_advance(to_check, &error_at)) { | |
137 | std::cout << "incorrect buffer at pos " << error_at << std::endl; | |
138 | return false; | |
139 | } | |
140 | ||
141 | uint64_t size = layers.begin()->first->get_length(layers.begin()->second); | |
142 | if (to_check.length() < size) { | |
143 | std::cout << "only read " << to_check.length() | |
144 | << " out of size " << size << std::endl; | |
145 | return false; | |
146 | } | |
147 | return true; | |
148 | } | |
149 | ||
150 | bool ObjectDesc::check_sparse(const std::map<uint64_t, uint64_t>& extents, | |
151 | bufferlist &to_check) | |
152 | { | |
153 | uint64_t off = 0; | |
154 | uint64_t pos = 0; | |
155 | auto objiter = begin(); | |
156 | for (auto &&extiter : extents) { | |
157 | // verify hole | |
158 | { | |
159 | bufferlist bl; | |
160 | bl.append_zero(extiter.first - pos); | |
161 | uint64_t error_at = 0; | |
162 | if (!objiter.check_bl_advance(bl, &error_at)) { | |
163 | std::cout << "sparse read omitted non-zero data at " | |
164 | << error_at << std::endl; | |
165 | return false; | |
166 | } | |
167 | } | |
168 | ||
169 | assert(off <= to_check.length()); | |
170 | pos = extiter.first; | |
171 | objiter.seek(pos); | |
172 | ||
173 | { | |
174 | bufferlist bl; | |
175 | bl.substr_of( | |
176 | to_check, | |
177 | off, | |
178 | std::min(to_check.length() - off, extiter.second)); | |
179 | uint64_t error_at = 0; | |
180 | if (!objiter.check_bl_advance(bl, &error_at)) { | |
181 | std::cout << "incorrect buffer at pos " << error_at << std::endl; | |
182 | return false; | |
183 | } | |
184 | off += extiter.second; | |
185 | pos += extiter.second; | |
186 | } | |
187 | ||
188 | if (pos < extiter.first + extiter.second) { | |
189 | std::cout << "reached end of iterator first" << std::endl; | |
190 | return false; | |
191 | } | |
192 | } | |
193 | ||
194 | // final hole | |
195 | bufferlist bl; | |
196 | uint64_t size = layers.begin()->first->get_length(layers.begin()->second); | |
197 | bl.append_zero(size - pos); | |
198 | uint64_t error_at; | |
199 | if (!objiter.check_bl_advance(bl, &error_at)) { | |
200 | std::cout << "sparse read omitted non-zero data at " | |
201 | << error_at << std::endl; | |
202 | return false; | |
203 | } | |
204 | return true; | |
205 | } |