]>
git.proxmox.com Git - ceph.git/blob - ceph/src/include/compact_map.h
2 * Ceph - scalable distributed file system
4 * Copyright (C) 2015 Red Hat, Inc
6 * This is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License version 2.1, as published by the Free Software
9 * Foundation. See file COPYING.
12 #ifndef CEPH_COMPACT_MAP_H
13 #define CEPH_COMPACT_MAP_H
21 template <class Key
, class T
, class Map
>
22 class compact_map_base
{
24 std::unique_ptr
<Map
> map
;
25 void alloc_internal() {
29 void free_internal() {
33 class const_iterator_base
{
34 const compact_map_base
*map
;
36 const_iterator_base() : map(0) { }
37 const_iterator_base(const compact_map_base
* m
) : map(m
) { }
38 const_iterator_base(const compact_map_base
*m
, const It
& i
) : map(m
), it(i
) { }
39 friend class compact_map_base
;
40 friend class iterator_base
;
42 const_iterator_base(const const_iterator_base
& o
) {
46 bool operator==(const const_iterator_base
& o
) const {
47 return (map
== o
.map
) && (!map
->map
|| it
== o
.it
);
49 bool operator!=(const const_iterator_base
& o
) const {
50 return !(*this == o
);;
52 const_iterator_base
& operator=(const const_iterator_base
& o
) {
57 const_iterator_base
& operator++() {
61 const_iterator_base
& operator--() {
65 const std::pair
<const Key
,T
>& operator*() {
68 const std::pair
<const Key
,T
>* operator->() {
69 return it
.operator->();
75 const compact_map_base
* map
;
77 iterator_base() : map(0) { }
78 iterator_base(compact_map_base
* m
) : map(m
) { }
79 iterator_base(compact_map_base
* m
, const It
& i
) : map(m
), it(i
) { }
80 friend class compact_map_base
;
82 iterator_base(const iterator_base
& o
) {
86 bool operator==(const iterator_base
& o
) const {
87 return (map
== o
.map
) && (!map
->map
|| it
== o
.it
);
89 bool operator!=(const iterator_base
& o
) const {
90 return !(*this == o
);;
92 iterator_base
& operator=(const iterator_base
& o
) {
97 iterator_base
& operator++() {
101 iterator_base
operator++(int) {
102 iterator_base tmp
= *this;
106 iterator_base
& operator--() {
110 std::pair
<const Key
,T
>& operator*() {
113 std::pair
<const Key
,T
>* operator->() {
114 return it
.operator->();
116 operator const_iterator_base
<It
>() const {
117 return const_iterator_base
<It
>(map
, it
);
122 class iterator
: public iterator_base
<typename
Map::iterator
> {
125 iterator(const iterator_base
<typename
Map::iterator
>& o
)
126 : iterator_base
<typename
Map::iterator
>(o
) { }
127 iterator(compact_map_base
* m
) : iterator_base
<typename
Map::iterator
>(m
) { }
128 iterator(compact_map_base
* m
, const typename
Map::iterator
& i
)
129 : iterator_base
<typename
Map::iterator
>(m
, i
) { }
131 class const_iterator
: public const_iterator_base
<typename
Map::const_iterator
> {
134 const_iterator(const iterator_base
<typename
Map::const_iterator
>& o
)
135 : const_iterator_base
<typename
Map::const_iterator
>(o
) { }
136 const_iterator(const compact_map_base
* m
) : const_iterator_base
<typename
Map::const_iterator
>(m
) { }
137 const_iterator(const compact_map_base
* m
, const typename
Map::const_iterator
& i
)
138 : const_iterator_base
<typename
Map::const_iterator
>(m
, i
) { }
140 class reverse_iterator
: public iterator_base
<typename
Map::reverse_iterator
> {
142 reverse_iterator() { }
143 reverse_iterator(const iterator_base
<typename
Map::reverse_iterator
>& o
)
144 : iterator_base
<typename
Map::reverse_iterator
>(o
) { }
145 reverse_iterator(compact_map_base
* m
) : iterator_base
<typename
Map::reverse_iterator
>(m
) { }
146 reverse_iterator(compact_map_base
* m
, const typename
Map::reverse_iterator
& i
)
147 : iterator_base
<typename
Map::reverse_iterator
>(m
, i
) { }
149 class const_reverse_iterator
: public const_iterator_base
<typename
Map::const_reverse_iterator
> {
151 const_reverse_iterator() { }
152 const_reverse_iterator(const iterator_base
<typename
Map::const_reverse_iterator
>& o
)
153 : iterator_base
<typename
Map::const_reverse_iterator
>(o
) { }
154 const_reverse_iterator(const compact_map_base
* m
) : const_iterator_base
<typename
Map::const_reverse_iterator
>(m
) { }
155 const_reverse_iterator(const compact_map_base
* m
, const typename
Map::const_reverse_iterator
& i
)
156 : const_iterator_base
<typename
Map::const_reverse_iterator
>(m
, i
) { }
158 compact_map_base(const compact_map_base
& o
) {
164 compact_map_base() {}
165 ~compact_map_base() {}
168 return !map
|| map
->empty();
170 size_t size() const {
171 return map
? map
->size() : 0;
173 bool operator==(const compact_map_base
& o
) const {
174 return (empty() && o
.empty()) || (map
&& o
.map
&& *map
== *o
.map
);
176 bool operator!=(const compact_map_base
& o
) const {
177 return !(*this == o
);
179 size_t count (const Key
& k
) const {
180 return map
? map
->count(k
) : 0;
182 iterator
erase (iterator p
) {
184 assert(this == p
.map
);
185 auto it
= map
->erase(p
.it
);
188 return iterator(this);
190 return iterator(this, it
);
193 return iterator(this);
196 size_t erase (const Key
& k
) {
199 size_t r
= map
->erase(k
);
207 void swap(compact_map_base
& o
) {
210 compact_map_base
& operator=(const compact_map_base
& o
) {
218 iterator
insert(const std::pair
<const Key
, T
>& val
) {
220 return iterator(this, map
->insert(val
));
222 template <class... Args
>
223 std::pair
<iterator
,bool> emplace ( Args
&&... args
) {
225 auto em
= map
->emplace(std::forward
<Args
>(args
)...);
226 return std::pair
<iterator
,bool>(iterator(this, em
.first
), em
.second
);
230 return iterator(this);
231 return iterator(this, map
->begin());
235 return iterator(this);
236 return iterator(this, map
->end());
238 reverse_iterator
rbegin() {
240 return reverse_iterator(this);
241 return reverse_iterator(this, map
->rbegin());
243 reverse_iterator
rend() {
245 return reverse_iterator(this);
246 return reverse_iterator(this, map
->rend());
248 iterator
find(const Key
& k
) {
250 return iterator(this);
251 return iterator(this, map
->find(k
));
253 iterator
lower_bound(const Key
& k
) {
255 return iterator(this);
256 return iterator(this, map
->lower_bound(k
));
258 iterator
upper_bound(const Key
& k
) {
260 return iterator(this);
261 return iterator(this, map
->upper_bound(k
));
263 const_iterator
begin() const {
265 return const_iterator(this);
266 return const_iterator(this, map
->begin());
268 const_iterator
end() const {
270 return const_iterator(this);
271 return const_iterator(this, map
->end());
273 const_reverse_iterator
rbegin() const {
275 return const_reverse_iterator(this);
276 return const_reverse_iterator(this, map
->rbegin());
278 const_reverse_iterator
rend() const {
280 return const_reverse_iterator(this);
281 return const_reverse_iterator(this, map
->rend());
283 const_iterator
find(const Key
& k
) const {
285 return const_iterator(this);
286 return const_iterator(this, map
->find(k
));
288 const_iterator
lower_bound(const Key
& k
) const {
290 return const_iterator(this);
291 return const_iterator(this, map
->lower_bound(k
));
293 const_iterator
upper_bound(const Key
& k
) const {
295 return const_iterator(this);
296 return const_iterator(this, map
->upper_bound(k
));
298 void encode(bufferlist
&bl
) const {
302 ::encode((uint32_t)0, bl
);
304 void encode(bufferlist
&bl
, uint64_t features
) const {
306 ::encode(*map
, bl
, features
);
308 ::encode((uint32_t)0, bl
);
310 void decode(bufferlist::iterator
& p
) {
315 ::decode_nohead(n
, *map
, p
);
321 template<class Key
, class T
, class Map
>
322 inline void encode(const compact_map_base
<Key
, T
, Map
>& m
, bufferlist
& bl
) {
325 template<class Key
, class T
, class Map
>
326 inline void encode(const compact_map_base
<Key
, T
, Map
>& m
, bufferlist
& bl
,
328 m
.encode(bl
, features
);
330 template<class Key
, class T
, class Map
>
331 inline void decode(compact_map_base
<Key
, T
, Map
>& m
, bufferlist::iterator
& p
) {
335 template <class Key
, class T
, class Compare
= std::less
<Key
>, class Alloc
= std::allocator
< std::pair
<const Key
, T
> > >
336 class compact_map
: public compact_map_base
<Key
, T
, std::map
<Key
,T
,Compare
,Alloc
> > {
338 T
& operator[](const Key
& k
) {
339 this->alloc_internal();
340 return (*(this->map
))[k
];
344 template <class Key
, class T
, class Compare
= std::less
<Key
>, class Alloc
= std::allocator
< std::pair
<const Key
, T
> > >
345 inline std::ostream
& operator<<(std::ostream
& out
, const compact_map
<Key
, T
, Compare
, Alloc
>& m
)
349 for (const auto &p
: m
) {
352 out
<< p
.first
<< "=" << p
.second
;
359 template <class Key
, class T
, class Compare
= std::less
<Key
>, class Alloc
= std::allocator
< std::pair
<const Key
, T
> > >
360 class compact_multimap
: public compact_map_base
<Key
, T
, std::multimap
<Key
,T
,Compare
,Alloc
> > {
363 template <class Key
, class T
, class Compare
= std::less
<Key
>, class Alloc
= std::allocator
< std::pair
<const Key
, T
> > >
364 inline std::ostream
& operator<<(std::ostream
& out
, const compact_multimap
<Key
, T
, Compare
, Alloc
>& m
)
368 for (const auto &p
: m
) {
371 out
<< p
.first
<< "=" << p
.second
;