| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| #pragma once |
| |
| #ifndef GEODE_EVENTIDMAP_H_ |
| #define GEODE_EVENTIDMAP_H_ |
| |
| #include <chrono> |
| #include <functional> |
| #include <memory> |
| #include <mutex> |
| #include <unordered_map> |
| #include <utility> |
| #include <vector> |
| |
| #include <geode/internal/functional.hpp> |
| |
| #include "EventId.hpp" |
| #include "EventSource.hpp" |
| |
| namespace apache { |
| namespace geode { |
| namespace client { |
| |
| class EventSequence; |
| class EventIdMap; |
| |
| typedef std::pair<std::shared_ptr<EventSource>, std::shared_ptr<EventSequence>> |
| EventIdMapEntry; |
| typedef std::vector<EventIdMapEntry> EventIdMapEntryList; |
| |
| /** @class EventIdMap EventIdMap.hpp |
| * |
| * This is the class that encapsulates a HashMap and |
| * provides the operations for duplicate checking and |
| * expiry of idle event IDs from notifications. |
| */ |
| class APACHE_GEODE_EXPORT EventIdMap { |
| private: |
| typedef std::unordered_map<std::shared_ptr<EventSource>, |
| std::shared_ptr<EventSequence>, |
| dereference_hash<std::shared_ptr<EventSource>>, |
| dereference_equal_to<std::shared_ptr<EventSource>>> |
| map_type; |
| |
| std::chrono::milliseconds m_expiry; |
| map_type m_map; |
| std::recursive_mutex m_lock; |
| |
| // hidden |
| EventIdMap(const EventIdMap &); |
| EventIdMap &operator=(const EventIdMap &); |
| |
| public: |
| EventIdMap() : m_expiry(0){}; |
| |
| void clear(); |
| |
| /** Initialize with preset expiration time in seconds */ |
| void init(std::chrono::milliseconds expirySecs); |
| |
| ~EventIdMap(); |
| |
| /** Find out if entry is duplicate |
| * @return true if the entry exists else false |
| */ |
| bool isDuplicate(std::shared_ptr<EventSource> key, |
| std::shared_ptr<EventSequence> value); |
| |
| /** Construct an EventIdMapEntry from an std::shared_ptr<EventId> */ |
| static EventIdMapEntry make(std::shared_ptr<EventId> eventid); |
| |
| /** Put an item and return true if it is new or false if it existed and was |
| * updated |
| * @param onlynew Only put if the sequence id does not exist or is higher |
| * @return true if the entry was updated or inserted otherwise false |
| */ |
| bool put(std::shared_ptr<EventSource> key, |
| std::shared_ptr<EventSequence> value, bool onlynew = false); |
| |
| /** Update the deadline for the entry |
| * @return true if the entry exists else false |
| */ |
| bool touch(std::shared_ptr<EventSource> key); |
| |
| /** Remove an item from the map |
| * @return true if the entry was found and removed else return false |
| */ |
| bool remove(std::shared_ptr<EventSource> key); |
| |
| /** Collect all map entries who acked flag is false and set their acked flags |
| * to true */ |
| EventIdMapEntryList getUnAcked(); |
| |
| /** Clear all acked flags in the list and return the number of entries cleared |
| * @param entries List of entries whos flags are to be cleared |
| * @return The number of entries whos flags were cleared |
| */ |
| uint32_t clearAckedFlags(EventIdMapEntryList &entries); |
| |
| /** Remove entries whos deadlines have passed and return the number of entries |
| * removed |
| * @param onlyacked Either check only entries whos acked flag is true |
| * otherwise check all entries |
| * @return The number of entries removed |
| */ |
| uint32_t expire(bool onlyacked); |
| }; |
| |
| /** @class EventSequence |
| * |
| * EventSequence is the combination of SequenceNum from EventId, a timestamp and |
| * a flag indicating whether or not it is ACKed |
| */ |
| class APACHE_GEODE_EXPORT EventSequence { |
| public: |
| using clock = std::chrono::steady_clock; |
| using time_point = clock::time_point; |
| |
| private: |
| int64_t m_seqNum; |
| bool m_acked; |
| time_point m_deadline; // current time plus the expiration delay (age) |
| |
| void init(); |
| |
| public: |
| void clear(); |
| |
| EventSequence(); |
| explicit EventSequence(int64_t seqNum); |
| ~EventSequence(); |
| |
| // update deadline |
| void touch(std::chrono::milliseconds ageSecs); |
| // update deadline, clear acked flag and set seqNum |
| void touch(int64_t seqNum, std::chrono::milliseconds ageSecs); |
| |
| // Accessors: |
| |
| int64_t getSeqNum(); |
| void setSeqNum(int64_t seqNum); |
| |
| bool getAcked(); |
| void setAcked(bool acked); |
| |
| time_point getDeadline(); |
| void setDeadline(time_point deadline); |
| |
| bool operator<=(const EventSequence &rhs) const; |
| }; |
| } // namespace client |
| } // namespace geode |
| } // namespace apache |
| #endif // GEODE_EVENTIDMAP_H_ |