]>
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_fwd.h" | |
4 | #include <map> | |
5 | ||
6 | #ifndef COMMON_OBJECT_H | |
7 | #define COMMON_OBJECT_H | |
8 | ||
9 | enum { | |
10 | RANDOMWRITEFULL, | |
11 | DELETED, | |
12 | CLONERANGE | |
13 | }; | |
14 | ||
15 | bool test_object_contents(); | |
16 | ||
17 | class ObjectContents { | |
18 | uint64_t _size; | |
19 | std::map<uint64_t, unsigned int> seeds; | |
20 | interval_set<uint64_t> written; | |
21 | bool _exists; | |
22 | public: | |
23 | class Iterator { | |
24 | ObjectContents *parent; | |
25 | std::map<uint64_t, unsigned int>::iterator iter; | |
26 | unsigned int current_state; | |
27 | int current_val; | |
28 | uint64_t pos; | |
29 | private: | |
30 | unsigned int get_state(uint64_t pos); | |
31 | public: | |
32 | explicit Iterator(ObjectContents *parent) : | |
33 | parent(parent), iter(parent->seeds.end()), | |
34 | current_state(0), current_val(0), pos(-1) { | |
35 | seek_to_first(); | |
36 | } | |
37 | char operator*() { | |
38 | return parent->written.contains(pos) ? | |
39 | static_cast<char>(current_val % 256) : '\0'; | |
40 | } | |
41 | uint64_t get_pos() { | |
42 | return pos; | |
43 | } | |
44 | void seek_to(uint64_t _pos) { | |
45 | if (pos > _pos || | |
46 | (iter != parent->seeds.end() && _pos >= iter->first)) { | |
47 | iter = parent->seeds.upper_bound(_pos); | |
48 | --iter; | |
49 | current_state = iter->second; | |
50 | current_val = rand_r(¤t_state); | |
51 | pos = iter->first; | |
52 | ++iter; | |
53 | } | |
54 | while (pos < _pos) ++(*this); | |
55 | } | |
56 | ||
57 | void seek_to_first() { | |
58 | seek_to(0); | |
59 | } | |
60 | Iterator &operator++() { | |
61 | ++pos; | |
62 | if (iter != parent->seeds.end() && pos >= iter->first) { | |
11fdf7f2 | 63 | ceph_assert(pos == iter->first); |
7c673cae FG |
64 | current_state = iter->second; |
65 | ++iter; | |
66 | } | |
67 | current_val = rand_r(¤t_state); | |
68 | return *this; | |
69 | } | |
70 | bool valid() { | |
71 | return pos < parent->size(); | |
72 | } | |
73 | friend class ObjectContents; | |
74 | }; | |
75 | ||
76 | ObjectContents() : _size(0), _exists(false) { | |
77 | seeds[0] = 0; | |
78 | } | |
79 | ||
11fdf7f2 TL |
80 | explicit ObjectContents(bufferlist::const_iterator &bp) { |
81 | decode(_size, bp); | |
82 | decode(seeds, bp); | |
83 | decode(written, bp); | |
84 | decode(_exists, bp); | |
7c673cae FG |
85 | } |
86 | ||
87 | void clone_range(ObjectContents &other, | |
88 | interval_set<uint64_t> &intervals); | |
89 | void write(unsigned int seed, | |
90 | uint64_t from, | |
91 | uint64_t len); | |
92 | Iterator get_iterator() { | |
93 | return Iterator(this); | |
94 | } | |
95 | ||
96 | uint64_t size() const { return _size; } | |
97 | ||
98 | bool exists() { return _exists; } | |
99 | ||
100 | void debug(std::ostream &out) { | |
101 | out << "_size is " << _size << std::endl; | |
102 | out << "seeds is: ("; | |
103 | for (std::map<uint64_t, unsigned int>::iterator i = seeds.begin(); | |
104 | i != seeds.end(); | |
105 | ++i) { | |
106 | out << "[" << i->first << "," << i->second << "], "; | |
107 | } | |
108 | out << ")" << std::endl; | |
109 | out << "written is " << written << std::endl; | |
110 | out << "_exists is " << _exists << std::endl; | |
111 | } | |
112 | ||
113 | void encode(bufferlist &bl) const { | |
11fdf7f2 TL |
114 | using ceph::encode; |
115 | encode(_size, bl); | |
116 | encode(seeds, bl); | |
117 | encode(written, bl); | |
118 | encode(_exists, bl); | |
7c673cae FG |
119 | } |
120 | }; | |
121 | ||
122 | #endif |