From e6918187568dbd01842d8d1d2c808ce16a894239 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 21 Apr 2024 13:54:28 +0200 Subject: Adding upstream version 18.2.2. Signed-off-by: Daniel Baumann --- src/include/compact_map.h | 383 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 383 insertions(+) create mode 100644 src/include/compact_map.h (limited to 'src/include/compact_map.h') diff --git a/src/include/compact_map.h b/src/include/compact_map.h new file mode 100644 index 000000000..21645e3d1 --- /dev/null +++ b/src/include/compact_map.h @@ -0,0 +1,383 @@ +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2015 Red Hat, Inc + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ +#ifndef CEPH_COMPACT_MAP_H +#define CEPH_COMPACT_MAP_H + +#include "buffer.h" +#include "encoding.h" + +#include +#include + +#include "include/encoding.h" + +template +class compact_map_base { +protected: + std::unique_ptr map; + void alloc_internal() { + if (!map) + map.reset(new Map); + } + void free_internal() { + map.reset(); + } + template + class const_iterator_base { + const compact_map_base *map; + It it; + const_iterator_base() : map(0) { } + const_iterator_base(const compact_map_base* m) : map(m) { } + const_iterator_base(const compact_map_base *m, const It& i) : map(m), it(i) { } + friend class compact_map_base; + friend class iterator_base; + public: + const_iterator_base(const const_iterator_base& o) { + map = o.map; + it = o.it; + } + bool operator==(const const_iterator_base& o) const { + return (map == o.map) && (!map->map || it == o.it); + } + bool operator!=(const const_iterator_base& o) const { + return !(*this == o);; + } + const_iterator_base& operator=(const const_iterator_base& o) { + map = o.map; + it = o.it; + return *this; + } + const_iterator_base& operator++() { + ++it; + return *this; + } + const_iterator_base& operator--() { + --it; + return *this; + } + const std::pair& operator*() { + return *it; + } + const std::pair* operator->() { + return it.operator->(); + } + }; + template + class iterator_base { + private: + const compact_map_base* map; + It it; + iterator_base() : map(0) { } + iterator_base(compact_map_base* m) : map(m) { } + iterator_base(compact_map_base* m, const It& i) : map(m), it(i) { } + friend class compact_map_base; + public: + iterator_base(const iterator_base& o) { + map = o.map; + it = o.it; + } + bool operator==(const iterator_base& o) const { + return (map == o.map) && (!map->map || it == o.it); + } + bool operator!=(const iterator_base& o) const { + return !(*this == o);; + } + iterator_base& operator=(const iterator_base& o) { + map = o.map; + it = o.it; + return *this; + } + iterator_base& operator++() { + ++it; + return *this; + } + iterator_base operator++(int) { + iterator_base tmp = *this; + ++it; + return tmp; + } + iterator_base& operator--() { + --it; + return *this; + } + std::pair& operator*() { + return *it; + } + std::pair* operator->() { + return it.operator->(); + } + operator const_iterator_base() const { + return const_iterator_base(map, it); + } + }; + +public: + class iterator : public iterator_base { + public: + iterator() { } + iterator(const iterator_base& o) + : iterator_base(o) { } + iterator(compact_map_base* m) : iterator_base(m) { } + iterator(compact_map_base* m, const typename Map::iterator& i) + : iterator_base(m, i) { } + }; + class const_iterator : public const_iterator_base { + public: + const_iterator() { } + const_iterator(const iterator_base& o) + : const_iterator_base(o) { } + const_iterator(const compact_map_base* m) : const_iterator_base(m) { } + const_iterator(const compact_map_base* m, const typename Map::const_iterator& i) + : const_iterator_base(m, i) { } + }; + class reverse_iterator : public iterator_base { + public: + reverse_iterator() { } + reverse_iterator(const iterator_base& o) + : iterator_base(o) { } + reverse_iterator(compact_map_base* m) : iterator_base(m) { } + reverse_iterator(compact_map_base* m, const typename Map::reverse_iterator& i) + : iterator_base(m, i) { } + }; + class const_reverse_iterator : public const_iterator_base { + public: + const_reverse_iterator() { } + const_reverse_iterator(const iterator_base& o) + : iterator_base(o) { } + const_reverse_iterator(const compact_map_base* m) : const_iterator_base(m) { } + const_reverse_iterator(const compact_map_base* m, const typename Map::const_reverse_iterator& i) + : const_iterator_base(m, i) { } + }; + compact_map_base(const compact_map_base& o) { + if (o.map) { + alloc_internal(); + *map = *o.map; + } + } + compact_map_base() {} + ~compact_map_base() {} + + bool empty() const { + return !map || map->empty(); + } + size_t size() const { + return map ? map->size() : 0; + } + bool operator==(const compact_map_base& o) const { + return (empty() && o.empty()) || (map && o.map && *map == *o.map); + } + bool operator!=(const compact_map_base& o) const { + return !(*this == o); + } + size_t count (const Key& k) const { + return map ? map->count(k) : 0; + } + iterator erase (iterator p) { + if (map) { + ceph_assert(this == p.map); + auto it = map->erase(p.it); + if (map->empty()) { + free_internal(); + return iterator(this); + } else { + return iterator(this, it); + } + } else { + return iterator(this); + } + } + size_t erase (const Key& k) { + if (!map) + return 0; + size_t r = map->erase(k); + if (map->empty()) + free_internal(); + return r; + } + void clear() { + free_internal(); + } + void swap(compact_map_base& o) { + map.swap(o.map); + } + compact_map_base& operator=(const compact_map_base& o) { + if (o.map) { + alloc_internal(); + *map = *o.map; + } else + free_internal(); + return *this; + } + iterator insert(const std::pair& val) { + alloc_internal(); + return iterator(this, map->insert(val)); + } + template + std::pair emplace ( Args&&... args ) { + alloc_internal(); + auto em = map->emplace(std::forward(args)...); + return std::pair(iterator(this, em.first), em.second); + } + iterator begin() { + if (!map) + return iterator(this); + return iterator(this, map->begin()); + } + iterator end() { + if (!map) + return iterator(this); + return iterator(this, map->end()); + } + reverse_iterator rbegin() { + if (!map) + return reverse_iterator(this); + return reverse_iterator(this, map->rbegin()); + } + reverse_iterator rend() { + if (!map) + return reverse_iterator(this); + return reverse_iterator(this, map->rend()); + } + iterator find(const Key& k) { + if (!map) + return iterator(this); + return iterator(this, map->find(k)); + } + iterator lower_bound(const Key& k) { + if (!map) + return iterator(this); + return iterator(this, map->lower_bound(k)); + } + iterator upper_bound(const Key& k) { + if (!map) + return iterator(this); + return iterator(this, map->upper_bound(k)); + } + const_iterator begin() const { + if (!map) + return const_iterator(this); + return const_iterator(this, map->begin()); + } + const_iterator end() const { + if (!map) + return const_iterator(this); + return const_iterator(this, map->end()); + } + const_reverse_iterator rbegin() const { + if (!map) + return const_reverse_iterator(this); + return const_reverse_iterator(this, map->rbegin()); + } + const_reverse_iterator rend() const { + if (!map) + return const_reverse_iterator(this); + return const_reverse_iterator(this, map->rend()); + } + const_iterator find(const Key& k) const { + if (!map) + return const_iterator(this); + return const_iterator(this, map->find(k)); + } + const_iterator lower_bound(const Key& k) const { + if (!map) + return const_iterator(this); + return const_iterator(this, map->lower_bound(k)); + } + const_iterator upper_bound(const Key& k) const { + if (!map) + return const_iterator(this); + return const_iterator(this, map->upper_bound(k)); + } + void encode(ceph::buffer::list &bl) const { + using ceph::encode; + if (map) + encode(*map, bl); + else + encode((uint32_t)0, bl); + } + void encode(ceph::buffer::list &bl, uint64_t features) const { + using ceph::encode; + if (map) + encode(*map, bl, features); + else + encode((uint32_t)0, bl); + } + void decode(ceph::buffer::list::const_iterator& p) { + using ceph::decode; + using ceph::decode_nohead; + uint32_t n; + decode(n, p); + if (n > 0) { + alloc_internal(); + decode_nohead(n, *map, p); + } else + free_internal(); + } +}; + +template +inline void encode(const compact_map_base& m, ceph::buffer::list& bl) { + m.encode(bl); +} +template +inline void encode(const compact_map_base& m, ceph::buffer::list& bl, + uint64_t features) { + m.encode(bl, features); +} +template +inline void decode(compact_map_base& m, ceph::buffer::list::const_iterator& p) { + m.decode(p); +} + +template , class Alloc = std::allocator< std::pair > > +class compact_map : public compact_map_base > { +public: + T& operator[](const Key& k) { + this->alloc_internal(); + return (*(this->map))[k]; + } +}; + +template , class Alloc = std::allocator< std::pair > > +inline std::ostream& operator<<(std::ostream& out, const compact_map& m) +{ + out << "{"; + bool first = true; + for (const auto &p : m) { + if (!first) + out << ","; + out << p.first << "=" << p.second; + first = false; + } + out << "}"; + return out; +} + +template , class Alloc = std::allocator< std::pair > > +class compact_multimap : public compact_map_base > { +}; + +template , class Alloc = std::allocator< std::pair > > +inline std::ostream& operator<<(std::ostream& out, const compact_multimap& m) +{ + out << "{{"; + bool first = true; + for (const auto &p : m) { + if (!first) + out << ","; + out << p.first << "=" << p.second; + first = false; + } + out << "}}"; + return out; +} +#endif -- cgit v1.2.3