blob: 6ec3379b72b7945af7976ba9fe72e4b17ad252e1 [file] [log] [blame]
/*
* 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_