8#ifndef INCLUDED_BDLCC_TIMEQUEUE
9#define INCLUDED_BDLCC_TIMEQUEUE
645#include <bdlscm_version.h>
670#include <bsl_climits.h>
671#include <bsl_cstdint.h>
673#include <bsl_vector.h>
675#ifndef BDE_DONT_ALLOW_TRANSITIVE_INCLUDES
710 k_NUM_INDEX_BITS_MIN = 8,
711 k_NUM_INDEX_BITS_MAX = 24,
712 k_NUM_INDEX_BITS_DEFAULT = 17
740 explicit Key(
const void *key)
747 : d_key(reinterpret_cast<const void*>(static_cast<
bsl::intptr_t>(key)))
760 return d_key == rhs.d_key;
767 return d_key != rhs.d_key;
774 template <
class VECTOR>
784 unsigned int d_index;
826 const unsigned int d_indexMask;
827 const unsigned int d_indexIterationMask;
828 const unsigned int d_indexIterationInc;
853 void freeNode(Node *node);
868 template <
class VECTOR>
890 template <
class VECTOR>
901 void putFreeNode(Node *node);
909 void putFreeNodeList(Node *begin);
915 Node* getNodeFromHandle(
Handle handle, Key key)
const;
945 bool poolTimerMemory,
1020#ifdef BSLS_LIBRARYFEATURES_HAS_CPP17_PMR
1054#ifdef BSLS_LIBRARYFEATURES_HAS_CPP17_PMR
1134template <
class DATA>
1217 const DATA&
data()
const;
1238template <
class DATA>
1239template <
class VECTOR>
1240struct TimeQueue<DATA>::IsVector {
1243 typedef TimeQueueItem<DATA> Item;
1246 static const bool value =
1248#ifdef BSLS_LIBRARYFEATURES_HAS_CPP17_PMR
1263template <
class DATA>
1265void TimeQueue<DATA>::freeNode(Node *node)
1267 node->d_index = ((node->d_index + d_indexIterationInc) &
1268 d_indexIterationMask) | (node->d_index & d_indexMask);
1270 if (!(node->d_index & d_indexIterationMask)) {
1271 node->d_index += d_indexIterationInc;
1276template <
class DATA>
1277template <
class VECTOR>
1287 MapIter it = d_map.begin();
1290 while (d_map.end() != it && it->first <= time) {
1291 Node *
const first = it->second;
1292 Node *
const last = first->d_prev_p;
1297 buffer->push_back(TimeQueueItem<DATA>(it->first,
1298 node->d_data.object(),
1304 node = node->d_next_p;
1306 }
while (node != first);
1308 last->d_next_p =
begin;
1311 MapIter condemned = it;
1313 d_map.erase(condemned);
1317 *newLength = d_length;
1319 if (d_map.end() != it && newMinTime) {
1320 *newMinTime = it->first;
1323 lock.release()->unlock();
1324 putFreeNodeList(begin);
1327template <
class DATA>
1328template <
class VECTOR>
1341 MapIter it = d_map.begin();
1344 while (d_map.end() != it && it->first <= time && 0 < maxTimers) {
1345 Node *
const first = it->second;
1346 Node *
const last = first->d_prev_p;
1348 Node *prevNode = first->d_prev_p;
1352 buffer->push_back(TimeQueueItem<DATA>(
1354 node->d_data.object(),
1361 node = node->d_next_p;
1364 }
while (0 < maxTimers && node != first);
1366 prevNode->d_next_p =
begin;
1369 if (node == first) {
1370 MapIter condemned = it;
1372 d_map.erase(condemned);
1375 node->d_prev_p = last;
1376 last->d_next_p = node;
1383 *newLength = d_length;
1385 if (d_map.end() != it && newMinTime) {
1386 *newMinTime = it->first;
1389 lock.release()->unlock();
1390 putFreeNodeList(begin);
1393template <
class DATA>
1394void TimeQueue<DATA>::putFreeNode(Node *node)
1396 node->d_data.object().~DATA();
1398 Node *nextFreeNode = d_nextFreeNode_p;
1399 node->d_next_p = nextFreeNode;
1400 while (nextFreeNode != d_nextFreeNode_p.testAndSwap(nextFreeNode, node)) {
1401 nextFreeNode = d_nextFreeNode_p;
1402 node->d_next_p = nextFreeNode;
1406template <
class DATA>
1407void TimeQueue<DATA>::putFreeNodeList(Node *begin)
1410 begin->d_data.object().~DATA();
1413 while (
end->d_next_p) {
1415 end->d_data.object().~DATA();
1418 Node *nextFreeNode = d_nextFreeNode_p;
1419 end->d_next_p = nextFreeNode;
1421 while (nextFreeNode !=
1422 d_nextFreeNode_p.testAndSwap(nextFreeNode, begin)) {
1423 nextFreeNode = d_nextFreeNode_p;
1424 end->d_next_p = nextFreeNode;
1431template <
class DATA>
1432typename TimeQueue<DATA>::Node *TimeQueue<DATA>::getNodeFromHandle(
1436 unsigned int uhandle =
static_cast<unsigned int>(handle) & d_indexMask;
1437 if (0 == uhandle || uhandle > d_nodeArray.size()) {
1440 Node *node = d_nodeArray[uhandle - 1];
1441 if (node->d_index !=
static_cast<unsigned>(handle) || node->d_key != key ||
1442 0 == node->d_prev_p) {
1449template <
class DATA>
1451: d_indexMask((1U << k_NUM_INDEX_BITS_DEFAULT) - 1)
1452, d_indexIterationMask(~d_indexMask)
1453, d_indexIterationInc(d_indexMask + 1)
1454, d_nodeArray(basicAllocator)
1455, d_nextFreeNode_p(0)
1456, d_map(basicAllocator)
1458, d_allocator_p(
bslma::Default::allocator(basicAllocator))
1462template <
class DATA>
1465: d_indexMask((1U << k_NUM_INDEX_BITS_DEFAULT) - 1)
1466, d_indexIterationMask(~d_indexMask)
1467, d_indexIterationInc(d_indexMask + 1)
1468, d_nodeArray(basicAllocator)
1469, d_nextFreeNode_p(0)
1470, d_map(basicAllocator)
1472, d_allocator_p(
bslma::Default::allocator(basicAllocator))
1477 (void)poolTimerMemory;
1480template <
class DATA>
1482: d_indexMask((1 << numIndexBits) - 1)
1483, d_indexIterationMask(~d_indexMask)
1484, d_indexIterationInc(d_indexMask + 1)
1485, d_nodeArray(basicAllocator)
1486, d_nextFreeNode_p(0)
1487, d_map(basicAllocator)
1489, d_allocator_p(
bslma::Default::allocator(basicAllocator))
1492 && k_NUM_INDEX_BITS_MAX >= numIndexBits);
1495template <
class DATA>
1497 bool poolTimerMemory,
1499: d_indexMask((1 << numIndexBits) - 1)
1500, d_indexIterationMask(~d_indexMask)
1501, d_indexIterationInc(d_indexMask + 1)
1502, d_nodeArray(basicAllocator)
1503, d_nextFreeNode_p(0)
1504, d_map(basicAllocator)
1506, d_allocator_p(
bslma::Default::allocator(basicAllocator))
1509 && k_NUM_INDEX_BITS_MAX >= numIndexBits);
1514 (void)poolTimerMemory;
1518template <
class DATA>
1522 if (!d_nodeArray.empty()) {
1523 Node **data = &d_nodeArray.front();
1524 const int numNodes =
static_cast<int>(d_nodeArray.size());
1525 for (
int i = 0; i < numNodes; ++i) {
1526 d_allocator_p->deleteObjectRaw(data[i]);
1532template <
class DATA>
1540 return add(time, data,
Key(0), isNewTop, newLength);
1543template <
class DATA>
1555 if (d_nextFreeNode_p) {
1561 node = d_nextFreeNode_p;
1562 Node *next = node->d_next_p;
1563 while (node != d_nextFreeNode_p.testAndSwap(node, next)) {
1564 node = d_nextFreeNode_p;
1565 next = node->d_next_p;
1572 if (d_nodeArray.size() >= d_indexMask - 1) {
1576 node =
new (*d_allocator_p) Node;
1577 d_nodeArray.push_back(node);
1579 static_cast<int>(d_nodeArray.size()) | d_indexIterationInc;
1581 node->d_time = time;
1588 MapIter it = d_map.find(time);
1590 if (d_map.end() == it) {
1591 node->d_prev_p = node;
1592 node->d_next_p = node;
1596 node->d_prev_p = it->second->d_prev_p;
1597 it->second->d_prev_p->d_next_p = node;
1598 node->d_next_p = it->second;
1599 it->second->d_prev_p = node;
1605 *isNewTop = d_map.begin()->second == node && node->d_prev_p == node;
1609 *newLength = d_length;
1612 return node->d_index;
1615template <
class DATA>
1622 return add(item.
time(), item.
data(), item.
key(), isNewTop, newLength);
1625template <
class DATA>
1631 MapIter it = d_map.begin();
1633 if (d_map.end() == it) {
1636 Node *node = it->second;
1639 buffer->
time() = node->d_time;
1640 buffer->
data() = node->d_data.object();
1641 buffer->
handle() = node->d_index;
1642 buffer->
key() = node->d_key;
1644 if (node->d_next_p != node) {
1645 node->d_prev_p->d_next_p = node->d_next_p;
1646 node->d_next_p->d_prev_p = node->d_prev_p;
1647 if (it->second == node) {
1648 it->second = node->d_next_p;
1658 if (d_length && newMinTime && !d_map.empty()) {
1659 *newMinTime = d_map.begin()->first;
1663 *newLength = d_length;
1672template <
class DATA>
1679template <
class DATA>
1686 popLEImp(time, buffer, newLength, newMinTime);
1689template <
class DATA>
1696 popLEImp(time, buffer, newLength, newMinTime);
1699#ifdef BSLS_LIBRARYFEATURES_HAS_CPP17_PMR
1700template <
class DATA>
1707 popLEImp(time, buffer, newLength, newMinTime);
1711template <
class DATA>
1720template <
class DATA>
1728 popLEImp(time, maxTimers, buffer, newLength, newMinTime);
1731template <
class DATA>
1739 popLEImp(time, maxTimers, buffer, newLength, newMinTime);
1742#ifdef BSLS_LIBRARYFEATURES_HAS_CPP17_PMR
1743template <
class DATA>
1751 popLEImp(time, maxTimers, buffer, newLength, newMinTime);
1755template <
class DATA>
1760 TimeQueueItem<DATA> *item)
1762 return remove(handle, Key(0), newLength, newMinTime, item);
1765template <
class DATA>
1770 TimeQueueItem<DATA> *item)
1774 Node *node = getNodeFromHandle(handle, key);
1781 item->time() = node->d_time;
1782 item->data() = node->d_data.object();
1783 item->handle() = handle;
1784 item->key() = node->d_key;
1787 if (node->d_next_p != node) {
1788 node->d_prev_p->d_next_p = node->d_next_p;
1789 node->d_next_p->d_prev_p = node->d_prev_p;
1791 MapIter it = d_map.find(node->d_time);
1792 if (it->second == node) {
1793 it->second = node->d_next_p;
1797 d_map.erase(node->d_time);
1803 *newLength = d_length;
1806 if (d_length && newMinTime) {
1809 *newMinTime = d_map.begin()->first;
1812 lock.release()->unlock();
1818template <
class DATA>
1822 MapIter it = d_map.begin();
1825 while (d_map.end() != it) {
1826 Node *
const first = it->second;
1827 Node *
const last = first->d_prev_p;
1834 node->d_data.object(),
1840 node = node->d_next_p;
1842 }
while (node != first);
1844 last->d_next_p = begin;
1847 MapIter condemned = it;
1849 d_map.erase(condemned);
1853 putFreeNodeList(begin);
1856template <
class DATA>
1862 return update(handle, Key(0), newTime, isNewTop);
1865template <
class DATA>
1873 Node *node = getNodeFromHandle(handle, key);
1879 if (node->d_prev_p != node) {
1880 node->d_prev_p->d_next_p = node->d_next_p;
1881 node->d_next_p->d_prev_p = node->d_prev_p;
1883 MapIter it = d_map.find(node->d_time);
1884 if (it->second == node) {
1885 it->second = node->d_next_p;
1889 d_map.erase(node->d_time);
1891 node->d_time = newTime;
1893 MapIter it = d_map.find(newTime);
1895 if (d_map.end() == it) {
1896 node->d_prev_p = node;
1897 node->d_next_p = node;
1898 d_map[newTime] = node;
1901 node->d_prev_p = it->second->d_prev_p;
1902 it->second->d_prev_p->d_next_p = node;
1903 node->d_next_p = it->second;
1904 it->second->d_prev_p = node;
1908 *isNewTop = d_map.begin()->second == node && node->d_prev_p == node;
1914template <
class DATA>
1921template <
class DATA>
1926 return isRegisteredHandle(handle, Key(0));
1929template <
class DATA>
1933 const Key& key)
const
1937 Node *node = getNodeFromHandle(handle, key);
1942template <
class DATA>
1948 if (d_map.empty()) {
1952 *buffer = d_map.begin()->first;
1956template <
class DATA>
1964 for (MapCIter it = d_map.cbegin();
1965 it != d_map.cend() && it->first <= time;
1967 Node *first = it->second;
1971 BSLS_ASSERT(count < (1 << k_NUM_INDEX_BITS_MAX) - 1);
1977 node = node->d_next_p;
1978 }
while (node != first);
1989template <
class DATA>
1993 bslma::DestructionUtil::destroy(&d_data);
1997template <
class DATA>
2001: d_time(original.d_time)
2003, d_handle(original.d_handle)
2004, d_key(original.d_key)
2006 bslma::DestructionUtil::destroy(&d_data);
2012template <
class DATA>
2023 bslma::DestructionUtil::destroy(&d_data);
2029template <
class DATA>
2041 bslma::DestructionUtil::destroy(&d_data);
2048template <
class DATA>
2053 d_time = rhs.d_time;
2054 d_data = rhs.d_data;
2055 d_handle = rhs.d_handle;
2061template <
class DATA>
2068template <
class DATA>
2081template <
typename DATA>
2093template <
class DATA>
2102template <
class DATA>
2109template <
class DATA>
2122template <
typename DATA>
2134template <
class DATA>
Definition bdlcc_timequeue.h:1135
Handle & handle()
Return the modifiable handle value associated with this item.
Definition bdlcc_timequeue.h:1200
TimeQueue< DATA >::Handle Handle
Definition bdlcc_timequeue.h:1142
TimeQueueItem(bslma::Allocator *basicAllocator=0)
Definition bdlcc_timequeue.h:1990
BSLMF_NESTED_TRAIT_DECLARATION(TimeQueueItem, bslma::UsesBslmaAllocator)
Key & key()
Return the modifiable key value associated with this item.
Definition bdlcc_timequeue.h:2096
DATA & data()
Return the modifiable data instance associated with this item.
Definition bdlcc_timequeue.h:2070
TimeQueueItem & operator=(const TimeQueueItem< DATA > &rhs)
Set the value of this TimeQueueItem to that of rhs.
Definition bdlcc_timequeue.h:2050
Handle handle() const
Return the non-modifiable handle value associated with this item.
Definition bdlcc_timequeue.h:1220
TimeQueue< DATA >::Key Key
Definition bdlcc_timequeue.h:1143
bsls::TimeInterval & time()
Return the modifiable time value associated with this item.
Definition bdlcc_timequeue.h:2063
Definition bdlcc_timequeue.h:731
~Key()
Destroy this Key object.
Definition bdlcc_timequeue.h:751
Key(const void *key)
Create a Key object having the specified key value.
Definition bdlcc_timequeue.h:740
bool operator==(const Key &rhs) const
Definition bdlcc_timequeue.h:758
Key(int key)
Definition bdlcc_timequeue.h:746
bool operator!=(const Key &rhs) const
Definition bdlcc_timequeue.h:765
Definition bdlcc_timequeue.h:706
TimeQueue(int numIndexBits, bool poolTimerMemory, bslma::Allocator *basicAllocator=0)
Definition bdlcc_timequeue.h:1496
void popLE(const bsls::TimeInterval &time, std::vector< TimeQueueItem< DATA > > *buffer, int *newLength=0, bsls::TimeInterval *newMinTime=0)
Definition bdlcc_timequeue.h:1691
bool isRegisteredHandle(Handle handle) const
void popLE(const bsls::TimeInterval &time)
Definition bdlcc_timequeue.h:1674
int minTime(bsls::TimeInterval *buffer) const
Definition bdlcc_timequeue.h:1944
TimeQueue(bool poolTimerMemory, bslma::Allocator *basicAllocator=0)
Definition bdlcc_timequeue.h:1463
~TimeQueue()
Destroy this time queue.
Definition bdlcc_timequeue.h:1519
int Handle
Definition bdlcc_timequeue.h:725
int length() const
Definition bdlcc_timequeue.h:1916
TimeQueue(int numIndexBits, bslma::Allocator *basicAllocator=0)
Definition bdlcc_timequeue.h:1481
Handle add(const bsls::TimeInterval &time, const DATA &data, int *isNewTop=0, int *newLength=0)
Definition bdlcc_timequeue.h:1534
int countLE(const bsls::TimeInterval &time) const
Definition bdlcc_timequeue.h:1958
bool isRegisteredHandle(Handle handle, const Key &key) const
int update(Handle handle, const bsls::TimeInterval &newTime, int *isNewTop=0)
void popLE(const bsls::TimeInterval &time, bsl::vector< TimeQueueItem< DATA > > *buffer, int *newLength=0, bsls::TimeInterval *newMinTime=0)
Definition bdlcc_timequeue.h:1681
TimeQueue(bslma::Allocator *basicAllocator=0)
Definition bdlcc_timequeue.h:1450
void popLE(const bsls::TimeInterval &time, int maxTimers)
Definition bdlcc_timequeue.h:1713
void popLE(const bsls::TimeInterval &time, int maxTimers, std::vector< TimeQueueItem< DATA > > *buffer, int *newLength=0, bsls::TimeInterval *newMinTime=0)
Definition bdlcc_timequeue.h:1733
int popFront(TimeQueueItem< DATA > *buffer=0, int *newLength=0, bsls::TimeInterval *newMinTime=0)
Definition bdlcc_timequeue.h:1626
Handle add(const bsls::TimeInterval &time, const DATA &data, const Key &key, int *isNewTop=0, int *newLength=0)
Definition bdlcc_timequeue.h:1544
void removeAll(bsl::vector< TimeQueueItem< DATA > > *buffer=0)
Definition bdlcc_timequeue.h:1819
int remove(Handle handle, const Key &key, int *newLength=0, bsls::TimeInterval *newMinTime=0, TimeQueueItem< DATA > *item=0)
int remove(Handle handle, int *newLength=0, bsls::TimeInterval *newMinTime=0, TimeQueueItem< DATA > *item=0)
int update(Handle handle, const Key &key, const bsls::TimeInterval &newTime, int *isNewTop=0)
void popLE(const bsls::TimeInterval &time, int maxTimers, bsl::vector< TimeQueueItem< DATA > > *buffer, int *newLength=0, bsls::TimeInterval *newMinTime=0)
Definition bdlcc_timequeue.h:1722
Handle add(const TimeQueueItem< DATA > &item, int *isNewTop=0, int *newLength=0)
Definition bdlcc_timequeue.h:1617
Definition bslstl_map.h:619
BloombergLP::bslstl::TreeIterator< const value_type, Node, difference_type > const_iterator
Definition bslstl_map.h:724
BloombergLP::bslstl::TreeIterator< value_type, Node, difference_type > iterator
Definition bslstl_map.h:722
Definition bslstl_vector.h:1025
Definition bslma_allocator.h:457
Definition bslmt_lockguard.h:234
T * release()
Definition bslmt_lockguard.h:493
Definition bslmt_mutex.h:315
Definition bsls_atomic.h:743
Definition bsls_atomic.h:1349
Definition bsls_timeinterval.h:301
#define BSLMF_ASSERT(expr)
Definition bslmf_assert.h:229
#define BSLS_ASSERT(X)
Definition bsls_assert.h:1804
#define BSLS_IDENT(str)
Definition bsls_ident.h:195
#define BSLS_KEYWORD_DELETED
Definition bsls_keyword.h:609
Definition bdlcc_boundedqueue.h:270
Definition bdlb_printmethods.h:283
T::iterator begin(T &container)
Definition bslstl_iterator.h:1495
T::iterator end(T &container)
Definition bslstl_iterator.h:1523
Definition balxml_encoderoptions.h:68
Definition bslmf_issame.h:146
static void defaultConstruct(TARGET_TYPE *address, bslma::Allocator *allocator)
Definition bslalg_scalarprimitives.h:1559
static void copyConstruct(TARGET_TYPE *address, const TARGET_TYPE &original, bslma::Allocator *allocator)
Definition bslalg_scalarprimitives.h:1599
Definition bslma_usesbslmaallocator.h:343
Definition bsls_objectbuffer.h:276