1 // Copyright 2023 The Pigweed Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); you may not 4 // use this file except in compliance with the License. You may obtain a copy of 5 // the License at 6 // 7 // https://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, WITHOUT 11 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12 // License for the specific language governing permissions and limitations under 13 // the License. 14 15 #pragma once 16 #include <pw_async/dispatcher.h> 17 18 #include <unordered_map> 19 20 namespace bt { 21 22 // A set which only holds items until the expiry time given. 23 template <typename Key> 24 class ExpiringSet { 25 public: 26 virtual ~ExpiringSet() = default; ExpiringSet(pw::async::Dispatcher & pw_dispatcher)27 explicit ExpiringSet(pw::async::Dispatcher& pw_dispatcher) 28 : pw_dispatcher_(pw_dispatcher) {} 29 30 // Add an item with the key `k` to the set, until the `expiration` passes. 31 // If the key is already in the set, the expiration is updated, even if it 32 // changes the expiration. add_until(Key k,pw::chrono::SystemClock::time_point expiration)33 void add_until(Key k, pw::chrono::SystemClock::time_point expiration) { 34 elems_[k] = expiration; 35 } 36 37 // Remove an item from the set. Idempotent. remove(const Key & k)38 void remove(const Key& k) { elems_.erase(k); } 39 40 // Check if a key is in the map. 41 // Expired keys are removed when they are checked. contains(const Key & k)42 bool contains(const Key& k) { 43 auto it = elems_.find(k); 44 if (it == elems_.end()) { 45 return false; 46 } 47 if (it->second <= pw_dispatcher_.now()) { 48 elems_.erase(it); 49 return false; 50 } 51 return true; 52 } 53 54 private: 55 std::unordered_map<Key, pw::chrono::SystemClock::time_point> elems_; 56 pw::async::Dispatcher& pw_dispatcher_; 57 }; 58 59 } // namespace bt 60