1 /* 2 * Copyright (c) 2021 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 #ifndef HIPERF_HASHLIST_H 17 #define HIPERF_HASHLIST_H 18 19 #include <unordered_map> 20 21 namespace OHOS { 22 namespace Developtools { 23 namespace HiPerf { 24 class Link { 25 public: 26 Link() = default; 27 ~Link() = default; Link(const Link & link)28 Link(const Link &link) : prev_ {link.prev_}, next_ {link.next_} {} Link(Link && link)29 Link(Link &&link) : prev_ {link.prev_}, next_ {link.next_} 30 { 31 link.prev_ = nullptr; 32 link.next_ = nullptr; 33 } 34 Link &operator=(const Link &link) 35 { 36 prev_ = link.prev_; 37 next_ = link.next_; 38 return *this; 39 } 40 Link &operator=(Link &&link) 41 { 42 prev_ = link.prev_; 43 link.prev_ = nullptr; 44 next_ = link.next_; 45 link.next_ = nullptr; 46 return *this; 47 } 48 Link *prev_ {nullptr}; 49 Link *next_ {nullptr}; 50 }; 51 52 template<typename Key, typename Val> 53 class LinkNode { 54 public: 55 Link link_ {}; 56 Key key_ {}; 57 Val val_ {}; 58 59 explicit LinkNode() = default; 60 ~LinkNode() = default; 61 explicit LinkNode(const Key &key); 62 explicit LinkNode(const Key &key, const Val &val); 63 explicit LinkNode(const Key &key, Val &&val); 64 LinkNode(const LinkNode &node); 65 LinkNode(LinkNode &&node); 66 LinkNode &operator=(const LinkNode &node); 67 LinkNode &operator=(LinkNode &&node); 68 static LinkNode<Key, Val> *GetLinkNode(Val *pval); 69 static LinkNode<Key, Val> *GetLinkNode(Link *plink); 70 }; 71 72 template<typename Key, typename Val> 73 class HashList { 74 public: 75 class Iterator { 76 public: 77 Iterator() = default; 78 ~Iterator() = default; 79 explicit Iterator(LinkNode<Key, Val> *pnode, HashList *phashList); 80 explicit Iterator(const LinkNode<Key, Val> *pnode, const HashList *phashList); 81 Iterator(const Iterator &itr); 82 Iterator(Iterator &&itr); 83 Iterator &operator=(const Iterator &itr); 84 Iterator &operator=(Iterator &&itr); 85 Iterator &operator++() noexcept; 86 Iterator operator++(int) noexcept; 87 Iterator &operator--() noexcept; 88 Iterator operator--(int) noexcept; 89 bool operator<(const Iterator &itr) const noexcept; 90 bool operator==(const Iterator &itr) const noexcept; 91 Val &operator*(); 92 const Val &operator*() const; 93 Val *operator->(); 94 const Val *operator->() const; 95 void swap(HashList<Key, Val>::Iterator &other); GetNode()96 LinkNode<Key, Val> *GetNode() const 97 { 98 return pnode_; 99 } 100 101 private: IsDangled()102 bool IsDangled() const noexcept 103 { 104 return phashList_ == nullptr; 105 } 106 107 LinkNode<Key, Val> *pnode_ {nullptr}; 108 HashList *phashList_ {nullptr}; 109 }; 110 111 class ReverseIterator { 112 public: 113 ReverseIterator() = default; 114 ~ReverseIterator() = default; 115 explicit ReverseIterator(LinkNode<Key, Val> *pnode, HashList *phashList); 116 explicit ReverseIterator(const LinkNode<Key, Val> *pnode, const HashList *phashList); 117 ReverseIterator(const ReverseIterator &itr); 118 ReverseIterator(ReverseIterator &&itr); 119 ReverseIterator &operator=(const ReverseIterator &itr); 120 ReverseIterator &operator=(ReverseIterator &&itr); 121 ReverseIterator &operator++() noexcept; 122 ReverseIterator operator++(int) noexcept; 123 ReverseIterator &operator--() noexcept; 124 ReverseIterator operator--(int) noexcept; 125 bool operator<(const ReverseIterator &itr) const noexcept; 126 bool operator==(const ReverseIterator &itr) const noexcept; 127 Val &operator*(); 128 const Val &operator*() const; 129 Val *operator->(); 130 const Val *operator->() const; 131 void swap(HashList<Key, Val>::ReverseIterator &other); 132 GetNode()133 LinkNode<Key, Val> *GetNode() 134 { 135 return pnode_; 136 } 137 138 private: IsDangled()139 bool IsDangled() const noexcept 140 { 141 return phashList_ == nullptr; 142 } 143 144 LinkNode<Key, Val> *pnode_ {nullptr}; 145 HashList *phashList_ {nullptr}; 146 }; 147 148 public: 149 explicit HashList(const std::size_t numItem = 0); 150 ~HashList(); 151 152 HashList(const HashList &source) = delete; 153 HashList &operator=(const HashList &source) = delete; 154 HashList(HashList &&source); 155 HashList &operator=(HashList &&source); 156 157 // capacity size()158 inline std::size_t size() const 159 { 160 return valueTab_.size(); 161 } empty()162 inline bool empty() const 163 { 164 return (dataHead_.next_ == &dataHead_) and (dataHead_.prev_ == &dataHead_); 165 } capacity()166 inline std::size_t capacity() const 167 { 168 return numItem_; 169 } IsFull()170 inline bool IsFull() const 171 { 172 return freeHead_.next_ == &freeHead_; 173 } count(const Key & key)174 inline std::size_t count(const Key &key) const 175 { 176 return valueTab_.count(key); 177 } 178 179 int reserve(const std::size_t numItem); 180 // iterators 181 Iterator begin(); 182 const Iterator cbegin() const; 183 Iterator end(); 184 const Iterator cend() const; 185 ReverseIterator rbegin(); 186 const ReverseIterator crbegin() const; 187 ReverseIterator rend(); 188 const ReverseIterator crend() const; 189 // element access 190 Val &front(); 191 const Val &front() const; 192 Val &back(bool prepend = false); 193 Val &operator[](const Key &key); 194 // lookup 195 Iterator find(const Key &key); 196 // modifiers 197 void push_front(const Key &key, const Val &val); 198 void push_front(const Key &key, Val &&val); 199 void push_back(const Key &key, const Val &val); 200 void push_back(const Key &key, Val &&val); 201 void pop_front(); 202 void pop_back(); 203 Iterator erase(const Key &key); 204 Iterator erase(const Iterator pos); 205 Iterator erase(const Iterator first, const Iterator last); 206 207 private: 208 void MoveToHead(LinkNode<Key, Val> *&pnode); 209 void MoveToTail(LinkNode<Key, Val> *&pnode); 210 bool MoveNode(const Iterator &pos, LinkNode<Key, Val> *&pnode); 211 LinkNode<Key, Val> *AllocateNode(const Key &key); 212 LinkNode<Key, Val> *AllocateNode(const Key &key, const Val &val); 213 LinkNode<Key, Val> *AllocateNode(const Key &key, Val &&val); 214 void ReclaimNode(LinkNode<Key, Val> *&pnode); 215 216 std::size_t numItem_ {0}; 217 LinkNode<Key, Val> *pData_ {nullptr}; 218 Link dataHead_ {}; 219 Link freeHead_ {}; 220 std::unordered_map<Key, LinkNode<Key, Val> *> valueTab_ {}; 221 }; 222 } // namespace HiPerf 223 } // namespace Developtools 224 } // namespace OHOS 225 #endif // HIPERF_HASHLIST_H 226