OLD | NEW |
---|---|
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef COMPONENTS_COPRESENCE_TIMED_MAP_ | 5 #ifndef COMPONENTS_COPRESENCE_TIMED_MAP_H_ |
6 #define COMPONENTS_COPRESENCE_TIMED_MAP_ | 6 #define COMPONENTS_COPRESENCE_TIMED_MAP_H_ |
7 | 7 |
8 #include <map> | 8 #include <map> |
9 #include <queue> | 9 #include <queue> |
10 #include <utility> | 10 #include <utility> |
11 #include <vector> | 11 #include <vector> |
12 | 12 |
13 #include "base/macros.h" | 13 #include "base/macros.h" |
14 #include "base/time/default_tick_clock.h" | 14 #include "base/time/default_tick_clock.h" |
15 #include "base/time/tick_clock.h" | 15 #include "base/time/tick_clock.h" |
16 #include "base/time/time.h" | 16 #include "base/time/time.h" |
17 #include "base/timer/timer.h" | 17 #include "base/timer/timer.h" |
18 | 18 |
19 namespace copresence { | 19 namespace copresence { |
20 | 20 |
21 // TimedMap is a map with the added functionality of clearing any | 21 // TimedMap is a map with the added functionality of clearing any |
22 // key/value pair after its specified lifetime is over. | 22 // key/value pair after its specified lifetime is over. |
23 template <typename KeyType, typename ValueType> | 23 template <typename KeyType, typename ValueType> |
24 class TimedMap { | 24 class TimedMap { |
25 public: | 25 public: |
26 TimedMap(const base::TimeDelta& lifetime, size_t max_elements) | 26 TimedMap(const base::TimeDelta& lifetime, size_t max_elements) |
27 : kEmptyValue(ValueType()), | 27 : kEmptyValue(ValueType()), |
28 clock_(new base::DefaultTickClock()), | 28 clock_(new base::DefaultTickClock()), |
29 lifetime_(lifetime), | 29 lifetime_(lifetime), |
30 max_elements_(max_elements) { | 30 max_elements_(max_elements) { |
31 timer_.Start(FROM_HERE, lifetime_, this, &TimedMap::ClearExpiredTokens); | 31 timer_.Start(FROM_HERE, lifetime_, this, &TimedMap::ClearExpiredTokens); |
32 } | 32 } |
33 | 33 |
34 ~TimedMap() {} | 34 ~TimedMap() { |
35 delete clock_; | |
rkc
2014/08/09 06:41:42
No reason for this clock to not be a scoped_ptr. L
Charlie
2014/08/09 07:10:40
Done.
| |
36 } | |
35 | 37 |
36 void Add(const KeyType& key, const ValueType& value) { | 38 void Add(const KeyType& key, const ValueType& value) { |
37 map_[key] = value; | 39 map_[key] = value; |
38 expiry_queue_.push(KeyTimeTuple(key, clock_->NowTicks() + lifetime_)); | 40 expiry_queue_.push(KeyTimeTuple(key, clock_->NowTicks() + lifetime_)); |
39 while (map_.size() > max_elements_) | 41 while (map_.size() > max_elements_) |
40 ClearOldestToken(); | 42 ClearOldestToken(); |
41 } | 43 } |
42 | 44 |
43 bool HasKey(const KeyType& key) { | 45 bool HasKey(const KeyType& key) { |
44 ClearExpiredTokens(); | 46 ClearExpiredTokens(); |
45 return map_.find(key) != map_.end(); | 47 return map_.find(key) != map_.end(); |
46 } | 48 } |
47 | 49 |
48 const ValueType& GetValue(const KeyType& key) { | 50 const ValueType& GetValue(const KeyType& key) { |
49 ClearExpiredTokens(); | 51 ClearExpiredTokens(); |
50 typename std::map<KeyType, ValueType>::const_iterator elt = map_.find(key); | 52 typename std::map<KeyType, ValueType>::const_iterator elt = map_.find(key); |
51 return elt == map_.end() ? kEmptyValue : elt->second; | 53 return elt == map_.end() ? kEmptyValue : elt->second; |
52 } | 54 } |
53 | 55 |
54 void set_clock_for_testing(base::TickClock* clock) { clock_ = clock; } | 56 // TimedMap takes ownership of this clock. |
57 void set_clock_for_testing(base::TickClock* clock) { | |
rkc
2014/08/09 06:41:41
Change the clock to a scoped_ptr, pass in a scoped
Charlie
2014/08/09 06:48:23
That's what I wrote first. But then how do you cal
rkc
2014/08/09 06:53:57
Retain a bare pointer in the test. It is the clean
Charlie
2014/08/09 07:10:40
Done.
| |
58 DCHECK(clock); | |
59 delete clock_; | |
60 clock_ = clock; | |
61 } | |
55 | 62 |
56 private: | 63 private: |
57 void ClearExpiredTokens() { | 64 void ClearExpiredTokens() { |
58 while (!expiry_queue_.empty() && | 65 while (!expiry_queue_.empty() && |
59 expiry_queue_.top().second <= clock_->NowTicks()) | 66 expiry_queue_.top().second <= clock_->NowTicks()) |
60 ClearOldestToken(); | 67 ClearOldestToken(); |
61 } | 68 } |
62 | 69 |
63 void ClearOldestToken() { | 70 void ClearOldestToken() { |
64 map_.erase(expiry_queue_.top().first); | 71 map_.erase(expiry_queue_.top().first); |
(...skipping 22 matching lines...) Expand all Loading... | |
87 std::map<KeyType, ValueType> map_; | 94 std::map<KeyType, ValueType> map_; |
88 // Priority queue with our element keys ordered by the earliest expiring keys | 95 // Priority queue with our element keys ordered by the earliest expiring keys |
89 // first. | 96 // first. |
90 ExpiryQueue expiry_queue_; | 97 ExpiryQueue expiry_queue_; |
91 | 98 |
92 DISALLOW_COPY_AND_ASSIGN(TimedMap); | 99 DISALLOW_COPY_AND_ASSIGN(TimedMap); |
93 }; | 100 }; |
94 | 101 |
95 } // namespace copresence | 102 } // namespace copresence |
96 | 103 |
97 #endif // COMPONENTS_COPRESENCE_TIMED_MAP_ | 104 #endif // COMPONENTS_COPRESENCE_TIMED_MAP_H_ |
OLD | NEW |