| /*========================================================================= |
| * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved. |
| * This product is protected by U.S. and international copyright |
| * and intellectual property laws. Pivotal products are covered by |
| * one or more patents listed at http://www.pivotal.io/patents. |
| *========================================================================= |
| */ |
| #include "EventIdMap.hpp" |
| |
| using namespace gemfire; |
| |
| EventIdMap::~EventIdMap() |
| { |
| clear(); |
| } |
| |
| void EventIdMap::init( int32_t expirySecs ) |
| { |
| m_expiry = expirySecs; |
| } |
| |
| void EventIdMap::clear() |
| { |
| GUARD_MAP; |
| m_map.clear(); |
| } |
| |
| EventIdMapEntry EventIdMap::make(EventIdPtr eventid) |
| { |
| EventSourcePtr sid(new EventSource(eventid->getMemId(), |
| eventid->getMemIdLen(), eventid->getThrId())); |
| EventSequencePtr seq(new EventSequence(eventid->getSeqNum())); |
| return std::make_pair(sid, seq); |
| } |
| |
| bool EventIdMap::isDuplicate(EventSourcePtr key, EventSequencePtr value) |
| { |
| GUARD_MAP; |
| EventIdMapType::Iterator entry = m_map.find(key); |
| |
| if (entry != m_map.end() && ( (*value.ptr()) <= (*entry.second().ptr()) )) |
| { |
| return true; |
| } |
| return false; |
| } |
| |
| bool EventIdMap::put(EventSourcePtr key, EventSequencePtr value, bool onlynew) |
| { |
| GUARD_MAP; |
| |
| value->touch(m_expiry); |
| |
| EventIdMapType::Iterator entry = m_map.find(key); |
| |
| if (entry != m_map.end()) |
| { |
| if (onlynew && ((*value.ptr()) <= (*entry.second().ptr()))) |
| { |
| return false; |
| } |
| else |
| { |
| m_map.update(key, value); |
| return true; |
| } |
| } |
| else |
| { |
| m_map.insert(key, value); |
| return true; |
| } |
| } |
| |
| bool EventIdMap::touch(EventSourcePtr key) |
| { |
| GUARD_MAP; |
| |
| EventIdMapType::Iterator entry = m_map.find(key); |
| |
| if (entry != m_map.end()) |
| { |
| entry.second()->touch(m_expiry); |
| return true; |
| } |
| else |
| { |
| return false; |
| } |
| } |
| |
| bool EventIdMap::remove(EventSourcePtr key) |
| { |
| GUARD_MAP; |
| |
| EventIdMapType::Iterator entry = m_map.find(key); |
| |
| if (entry != m_map.end()) |
| { |
| m_map.erase(key); |
| return true; |
| } |
| else |
| { |
| return false; |
| } |
| } |
| |
| // side-effect: sets acked flags to true |
| EventIdMapEntryList EventIdMap::getUnAcked() |
| { |
| GUARD_MAP; |
| |
| EventIdMapEntryList entries; |
| |
| for (EventIdMapType::Iterator entry = m_map.begin(); entry != m_map.end(); entry++) |
| { |
| if (entry.second()->getAcked()) |
| { |
| continue; |
| } |
| |
| entry.second()->setAcked(true); |
| entries.push_back(std::make_pair(entry.first(), entry.second())); |
| } |
| |
| return entries; |
| } |
| |
| uint32_t EventIdMap::clearAckedFlags(EventIdMapEntryList & entries) |
| { |
| GUARD_MAP; |
| |
| uint32_t cleared = 0; |
| |
| for (EventIdMapEntryList::iterator item = entries.begin(); item != entries.end(); item++) |
| { |
| EventIdMapType::Iterator entry = m_map.find((*item).first); |
| |
| if (entry != m_map.end()) |
| { |
| entry.second()->setAcked(false); |
| cleared++; |
| } |
| } |
| |
| return cleared; |
| } |
| |
| uint32_t EventIdMap::expire(bool onlyacked) |
| { |
| GUARD_MAP; |
| |
| uint32_t expired = 0; |
| |
| EventIdMapEntryList entries; |
| |
| ACE_Time_Value current = ACE_OS::gettimeofday(); |
| |
| for (EventIdMapType::Iterator entry = m_map.begin(); entry != m_map.end(); entry++) |
| { |
| if (onlyacked && ! entry.second()->getAcked()) |
| { |
| continue; |
| } |
| |
| if (entry.second()->getDeadline() < current) |
| { |
| entries.push_back(std::make_pair(entry.first(), entry.second())); |
| } |
| } |
| |
| for (EventIdMapEntryList::iterator expiry = entries.begin(); expiry != entries.end(); expiry++) |
| { |
| m_map.erase((*expiry).first); |
| expired++; |
| } |
| |
| return expired; |
| } |
| |
| EventSource::EventSource(const char* memId, int32_t memIdLen, int64_t thrId) |
| { |
| init(); |
| |
| if (memId == NULL || memIdLen <= 0) |
| { |
| return; |
| } |
| |
| m_thrId = thrId; |
| |
| m_srcIdLen = memIdLen + sizeof(thrId); //8; // sizeof(thrId or int64_t); |
| m_srcId = new char[m_srcIdLen]; |
| memcpy(m_srcId, memId, memIdLen); |
| |
| // convert the int64 thrId to a byte-array and place at the end of m_srcId |
| memcpy(m_srcId+memIdLen, &thrId, sizeof(thrId)); |
| } |
| |
| EventSource::~EventSource() |
| { |
| clear(); |
| } |
| |
| void EventSource::init() |
| { |
| m_srcId = NULL; |
| m_srcIdLen = 0; |
| m_hash = 0; |
| m_thrId = -1; |
| } |
| |
| void EventSource::clear() |
| { |
| delete [] m_srcId; |
| init(); |
| } |
| |
| char * EventSource::getSrcId() |
| { |
| return m_srcId; |
| } |
| |
| int32_t EventSource::getSrcIdLen() |
| { |
| return m_srcIdLen; |
| } |
| |
| char * EventSource::getMemId() |
| { |
| return m_srcId; |
| } |
| |
| int32_t EventSource::getMemIdLen() |
| { |
| return m_srcIdLen - sizeof(m_thrId); |
| } |
| |
| int64_t EventSource::getThrId() |
| { |
| return m_thrId; |
| } |
| |
| uint32_t EventSource::hashcode() |
| { |
| if (m_srcId == NULL || m_srcIdLen <= 0) |
| { |
| return 0; |
| } |
| |
| if (m_hash == 0) |
| { |
| m_hash = ACE::hash_pjw(m_srcId, m_srcIdLen); |
| } |
| |
| return m_hash; |
| } |
| |
| bool EventSource::operator == (const EventSource & rhs) const |
| { |
| if (this->m_srcId == NULL || (&rhs)->m_srcId == NULL || this->m_srcIdLen != (&rhs)->m_srcIdLen) |
| { |
| return false; |
| } |
| |
| return memcmp(this->m_srcId, (&rhs)->m_srcId, this->m_srcIdLen) == 0; |
| } |
| |
| void EventSequence::init() |
| { |
| m_seqNum = -1; |
| m_acked = false; |
| m_deadline = ACE_OS::gettimeofday(); |
| } |
| |
| void EventSequence::clear() |
| { |
| init(); |
| } |
| |
| EventSequence::EventSequence() |
| { |
| init(); |
| } |
| |
| EventSequence::EventSequence(int64_t seqNum) |
| { |
| init(); |
| m_seqNum = seqNum; |
| } |
| |
| EventSequence::~EventSequence() |
| { |
| clear(); |
| } |
| |
| void EventSequence::touch(int32_t ageSecs) |
| { |
| m_deadline = ACE_OS::gettimeofday(); |
| m_deadline += ageSecs; |
| } |
| |
| void EventSequence::touch(int64_t seqNum, int32_t ageSecs) |
| { |
| touch(ageSecs); |
| m_seqNum = seqNum; |
| m_acked = false; |
| } |
| |
| int64_t EventSequence::getSeqNum() |
| { |
| return m_seqNum; |
| } |
| |
| void EventSequence::setSeqNum(int64_t seqNum) |
| { |
| m_seqNum = seqNum; |
| } |
| |
| bool EventSequence::getAcked() |
| { |
| return m_acked; |
| } |
| |
| void EventSequence::setAcked(bool acked) |
| { |
| m_acked = acked; |
| } |
| |
| ACE_Time_Value EventSequence::getDeadline() |
| { |
| return m_deadline; |
| } |
| |
| void EventSequence::setDeadline(ACE_Time_Value deadline) |
| { |
| m_deadline = deadline; |
| } |
| |
| bool EventSequence::operator <= (const EventSequence & rhs) const |
| { |
| return this->m_seqNum <= (&rhs)->m_seqNum; |
| } |
| |