From be84897ed608eca79b421e56523fdd9dfae56abf Mon Sep 17 00:00:00 2001 From: Pavel Kirienko Date: Wed, 14 Oct 2015 08:29:50 +0300 Subject: [PATCH] First stab at global refactoring of memory management - the library builds, but unit tests are failing horribly --- libuavcan/include/uavcan/build_config.hpp | 18 -- .../uavcan/node/generic_subscriber.hpp | 13 +- libuavcan/include/uavcan/node/node.hpp | 23 +- .../include/uavcan/node/service_client.hpp | 72 +++-- .../include/uavcan/node/service_server.hpp | 23 +- libuavcan/include/uavcan/node/sub_node.hpp | 6 +- libuavcan/include/uavcan/node/subscriber.hpp | 23 +- .../distributed/raft_core.hpp | 4 +- .../node_discoverer.hpp | 6 +- .../protocol/global_time_sync_slave.hpp | 3 +- .../uavcan/protocol/node_info_retriever.hpp | 5 +- .../uavcan/protocol/node_status_monitor.hpp | 2 +- .../can_acceptance_filter_configurator.hpp | 2 +- .../transport/outgoing_transfer_registry.hpp | 22 +- .../uavcan/transport/transfer_buffer.hpp | 47 +--- .../uavcan/transport/transfer_listener.hpp | 28 +- libuavcan/include/uavcan/util/map.hpp | 254 ++---------------- libuavcan/include/uavcan/util/multiset.hpp | 94 ++----- .../src/transport/uc_transfer_buffer.cpp | 147 +--------- libuavcan/test/node/test_node.hpp | 2 +- .../distributed/server.cpp | 3 +- .../node_discoverer.cpp | 4 +- libuavcan/test/transport/dispatcher.cpp | 10 +- .../test/transport/incoming_transfer.cpp | 2 +- .../transport/outgoing_transfer_registry.cpp | 2 +- libuavcan/test/transport/transfer_buffer.cpp | 32 +-- .../test/transport/transfer_listener.cpp | 12 +- .../test/transport/transfer_receiver.cpp | 2 +- libuavcan/test/transport/transfer_sender.cpp | 12 +- .../test/transport/transfer_test_helpers.cpp | 2 +- .../test/transport/transfer_test_helpers.hpp | 6 +- libuavcan/test/util/map.cpp | 44 ++- libuavcan/test/util/multiset.cpp | 34 +-- 33 files changed, 203 insertions(+), 756 deletions(-) diff --git a/libuavcan/include/uavcan/build_config.hpp b/libuavcan/include/uavcan/build_config.hpp index 89688a3056..fedea852b7 100644 --- a/libuavcan/include/uavcan/build_config.hpp +++ b/libuavcan/include/uavcan/build_config.hpp @@ -239,24 +239,6 @@ static const unsigned MaxCanAcceptanceFilters = UAVCAN_MAX_CAN_ACCEPTANCE_FILTER static const unsigned MaxCanAcceptanceFilters = 32; #endif -/** - * This constant defines how many receiver objects will be statically pre-allocated by classes that listen to messages - * of type uavcan.protocol.NodeStatus from other nodes. If the number of publishers exceeds this value, extra - * listeners will be allocated in the dynamic memory (one block per listener). - * - * The default value is safe to use in any application (since extra memory can always be retrieved from the pool). - * Applications that are extremely memory sensitive and are not expected to operate in large networks can override - * the default with a lower value. - * - * Note that nodes that aren't using classes that monitor the network (e.g. NodeStatusMonitor, dynamic node ID - * allocation servers) do not depend on this configuration parameter in any way. - */ -#ifdef UAVCAN_MAX_NETWORK_SIZE_HINT -static const unsigned MaxNetworkSizeHint = UAVCAN_MAX_NETWORK_SIZE_HINT; -#else -static const unsigned MaxNetworkSizeHint = 64; ///< Rest will go into the dynamic memory -#endif - } #endif // UAVCAN_BUILD_CONFIG_HPP_INCLUDED diff --git a/libuavcan/include/uavcan/node/generic_subscriber.hpp b/libuavcan/include/uavcan/node/generic_subscriber.hpp index bb203788c6..eca19c829f 100644 --- a/libuavcan/include/uavcan/node/generic_subscriber.hpp +++ b/libuavcan/include/uavcan/node/generic_subscriber.hpp @@ -119,25 +119,16 @@ public: * This helper class does some compile-time magic on the transport layer machinery. For authorized personnel only. */ template class TransferListenerTemplate = TransferListener + template class TransferListenerTemplate = TransferListener > class UAVCAN_EXPORT TransferListenerInstantiationHelper { enum { DataTypeMaxByteLen = BitLenToByteLen::Result }; enum { NeedsBuffer = int(DataTypeMaxByteLen) > int(GuaranteedPayloadLenPerFrame) }; enum { BufferSize = NeedsBuffer ? DataTypeMaxByteLen : 0 }; -#if UAVCAN_TINY - enum { NumStaticBufs = 0 }; - enum { NumStaticReceivers = 0 }; -#else - enum { NumStaticBufs = NeedsBuffer ? NumStaticBufs_: 0 }; - enum { NumStaticReceivers = NumStaticReceivers_ }; -#endif public: - typedef TransferListenerTemplate Type; + typedef TransferListenerTemplate Type; }; /** diff --git a/libuavcan/include/uavcan/node/node.hpp b/libuavcan/include/uavcan/node/node.hpp index 6ea59a2244..d9b6502736 100644 --- a/libuavcan/include/uavcan/node/node.hpp +++ b/libuavcan/include/uavcan/node/node.hpp @@ -35,22 +35,8 @@ namespace uavcan * For simple nodes this number can be reduced. * For high-traffic nodes the recommended minimum is * like 16K * (number of CAN ifaces + 1). - * - * @tparam OutgoingTransferRegistryStaticEntries Number of statically allocated objects - * to track Transfer ID for outgoing transfers. - * Normally it should be equal to expected number of - * publishers and service callers, but it's not necessary. - * Additional objects for Transfer ID tracking will - * be allocated in the memory pool if needed. - * Default value is acceptable for any use case. */ -template +template class UAVCAN_EXPORT Node : public INode { enum @@ -61,7 +47,7 @@ class UAVCAN_EXPORT Node : public INode typedef PoolAllocator Allocator; Allocator pool_allocator_; - OutgoingTransferRegistry outgoing_trans_reg_; + OutgoingTransferRegistry outgoing_trans_reg_; Scheduler scheduler_; NodeStatusProvider proto_nsp_; @@ -260,9 +246,8 @@ public: // ---------------------------------------------------------------------------- -template -int Node::start( - const TransferPriority priority) +template +int Node::start(const TransferPriority priority) { if (started_) { diff --git a/libuavcan/include/uavcan/node/service_client.hpp b/libuavcan/include/uavcan/node/service_client.hpp index daea7ac7cf..a7cce0dd4e 100644 --- a/libuavcan/include/uavcan/node/service_client.hpp +++ b/libuavcan/include/uavcan/node/service_client.hpp @@ -21,13 +21,11 @@ namespace uavcan { -template +template class UAVCAN_EXPORT ServiceResponseTransferListenerInstantiationHelper { -public: // so much templating it hurts +public: typedef typename TransferListenerInstantiationHelper::Type Type; }; @@ -217,24 +215,18 @@ public: * In C++11 mode this type defaults to std::function<>. * In C++03 mode this type defaults to a plain function pointer; use binder to * call member functions as callbacks. - * - * @tparam NumStaticCalls_ Number of concurrent calls that the class will be able to handle without using the - * memory pool. Note that this is NOT the maximum possible number of concurrent calls, - * there's no such limit. Defaults to one. */ template = UAVCAN_CPP11 - typename Callback_ = std::function&)>, + typename Callback_ = std::function&)> #else - typename Callback_ = void (*)(const ServiceCallResult&), + typename Callback_ = void (*)(const ServiceCallResult&) #endif - unsigned NumStaticCalls_ = 1 > class UAVCAN_EXPORT ServiceClient : public GenericSubscriber::Type> + typename ServiceResponseTransferListenerInstantiationHelper::Type> , public ServiceClientBase { public: @@ -244,16 +236,13 @@ public: typedef ServiceCallResult ServiceCallResultType; typedef Callback_ Callback; - enum { NumStaticCalls = NumStaticCalls_ }; - private: typedef ServiceClient SelfType; typedef GenericPublisher PublisherType; - typedef typename ServiceResponseTransferListenerInstantiationHelper::Type - TransferListenerType; + typedef typename ServiceResponseTransferListenerInstantiationHelper::Type TransferListenerType; typedef GenericSubscriber SubscriberType; - typedef Multiset CallRegistry; + typedef Multiset CallRegistry; struct TimeoutCallbackCaller { @@ -424,8 +413,8 @@ public: // ---------------------------------------------------------------------------- -template -void ServiceClient::invokeCallback(ServiceCallResultType& result) +template +void ServiceClient::invokeCallback(ServiceCallResultType& result) { if (coerceOrFallback(callback_, true)) { @@ -437,8 +426,8 @@ void ServiceClient::invokeCallback(Servic } } -template -bool ServiceClient::shouldAcceptFrame(const RxFrame& frame) const +template +bool ServiceClient::shouldAcceptFrame(const RxFrame& frame) const { UAVCAN_ASSERT(frame.getTransferType() == TransferTypeServiceResponse); // Other types filtered out by dispatcher @@ -447,9 +436,8 @@ bool ServiceClient::shouldAcceptFrame(con } -template -void ServiceClient:: -handleReceivedDataStruct(ReceivedDataStructure& response) +template +void ServiceClient::handleReceivedDataStruct(ReceivedDataStructure& response) { UAVCAN_ASSERT(response.getTransferType() == TransferTypeServiceResponse); @@ -460,8 +448,8 @@ handleReceivedDataStruct(ReceivedDataStructure& response) } -template -void ServiceClient::handleDeadline(MonotonicTime) +template +void ServiceClient::handleDeadline(MonotonicTime) { UAVCAN_TRACE("ServiceClient", "Shared deadline event received"); /* @@ -484,8 +472,8 @@ void ServiceClient::handleDeadline(Monoto } } -template -int ServiceClient::addCallState(ServiceCallID call_id) +template +int ServiceClient::addCallState(ServiceCallID call_id) { if (call_registry_.isEmpty()) { @@ -507,16 +495,16 @@ int ServiceClient::addCallState(ServiceCa return 0; } -template -int ServiceClient::call(NodeID server_node_id, const RequestType& request) +template +int ServiceClient::call(NodeID server_node_id, const RequestType& request) { ServiceCallID dummy; return call(server_node_id, request, dummy); } -template -int ServiceClient::call(NodeID server_node_id, const RequestType& request, - ServiceCallID& out_call_id) +template +int ServiceClient::call(NodeID server_node_id, const RequestType& request, + ServiceCallID& out_call_id) { if (!coerceOrFallback(callback_, true)) { @@ -573,8 +561,8 @@ int ServiceClient::call(NodeID server_nod return publisher_res; } -template -void ServiceClient::cancelCall(ServiceCallID call_id) +template +void ServiceClient::cancelCall(ServiceCallID call_id) { call_registry_.removeFirstWhere(CallStateMatchingPredicate(call_id)); if (call_registry_.isEmpty()) @@ -583,21 +571,21 @@ void ServiceClient::cancelCall(ServiceCal } } -template -void ServiceClient::cancelAllCalls() +template +void ServiceClient::cancelAllCalls() { call_registry_.clear(); SubscriberType::stop(); } -template -bool ServiceClient::hasPendingCallToServer(NodeID server_node_id) const +template +bool ServiceClient::hasPendingCallToServer(NodeID server_node_id) const { return NULL != call_registry_.find(ServerSearchPredicate(server_node_id)); } -template -ServiceCallID ServiceClient::getCallIDByIndex(unsigned index) const +template +ServiceCallID ServiceClient::getCallIDByIndex(unsigned index) const { const CallState* const id = call_registry_.getByIndex(index); return (id == NULL) ? ServiceCallID() : id->getCallID(); diff --git a/libuavcan/include/uavcan/node/service_server.hpp b/libuavcan/include/uavcan/node/service_server.hpp index d635d9579d..d362502800 100644 --- a/libuavcan/include/uavcan/node/service_server.hpp +++ b/libuavcan/include/uavcan/node/service_server.hpp @@ -77,33 +77,19 @@ public: * In C++11 mode this type defaults to std::function<>. * In C++03 mode this type defaults to a plain function pointer; use binder to * call member functions as callbacks. - * - * @tparam NumStaticReceivers Number of statically allocated receiver objects. If there's more service - * clients for this service, extra receivers will be allocated in the memory pool. - * - * @tparam NumStaticBufs Number of statically allocated receiver buffers. If there's more concurrent - * incoming transfers, extra buffers will be allocated in the memory pool. */ template = UAVCAN_CPP11 typename Callback_ = std::function&, - ServiceResponseDataStructure&)>, + ServiceResponseDataStructure&)> #else typename Callback_ = void (*)(const ReceivedDataStructure&, - ServiceResponseDataStructure&), -#endif -#if UAVCAN_TINY - unsigned NumStaticReceivers = 0, - unsigned NumStaticBufs = 0 -#else - unsigned NumStaticReceivers = 2, - unsigned NumStaticBufs = 1 + ServiceResponseDataStructure&) #endif > class UAVCAN_EXPORT ServiceServer : public GenericSubscriber::Type> + typename TransferListenerInstantiationHelper::Type> { public: typedef DataType_ DataType; @@ -112,8 +98,7 @@ public: typedef Callback_ Callback; private: - typedef typename TransferListenerInstantiationHelper::Type - TransferListenerType; + typedef typename TransferListenerInstantiationHelper::Type TransferListenerType; typedef GenericSubscriber SubscriberType; typedef GenericPublisher PublisherType; diff --git a/libuavcan/include/uavcan/node/sub_node.hpp b/libuavcan/include/uavcan/node/sub_node.hpp index ec5484365d..2a7de956ef 100644 --- a/libuavcan/include/uavcan/node/sub_node.hpp +++ b/libuavcan/include/uavcan/node/sub_node.hpp @@ -20,9 +20,7 @@ namespace uavcan * Please refer to the @ref Node<> for documentation concerning the template arguments; refer to the tutorials * to lean how to use libuavcan in multiprocess applications. */ -template +template class UAVCAN_EXPORT SubNode : public INode { enum @@ -33,7 +31,7 @@ class UAVCAN_EXPORT SubNode : public INode typedef PoolAllocator Allocator; Allocator pool_allocator_; - OutgoingTransferRegistry outgoing_trans_reg_; + OutgoingTransferRegistry outgoing_trans_reg_; Scheduler scheduler_; uint64_t internal_failure_cnt_; diff --git a/libuavcan/include/uavcan/node/subscriber.hpp b/libuavcan/include/uavcan/node/subscriber.hpp index ac094e5c32..b82233dddd 100644 --- a/libuavcan/include/uavcan/node/subscriber.hpp +++ b/libuavcan/include/uavcan/node/subscriber.hpp @@ -34,38 +34,23 @@ namespace uavcan * In C++11 mode this type defaults to std::function<>. * In C++03 mode this type defaults to a plain function pointer; use binder to * call member functions as callbacks. - * - * @tparam NumStaticReceivers Number of statically allocated receiver objects. If there's more publishers - * of this message, extra receivers will be allocated in the memory pool. - * - * @tparam NumStaticBufs Number of statically allocated receiver buffers. If there's more concurrent - * incoming transfers, extra buffers will be allocated in the memory pool. */ template = UAVCAN_CPP11 - typename Callback_ = std::function&)>, + typename Callback_ = std::function&)> #else - typename Callback_ = void (*)(const ReceivedDataStructure&), -#endif -#if UAVCAN_TINY - unsigned NumStaticReceivers = 0, - unsigned NumStaticBufs = 0 -#else - unsigned NumStaticReceivers = 2, - unsigned NumStaticBufs = 1 + typename Callback_ = void (*)(const ReceivedDataStructure&) #endif > class UAVCAN_EXPORT Subscriber : public GenericSubscriber::Type> + typename TransferListenerInstantiationHelper::Type> { public: typedef Callback_ Callback; private: - typedef typename TransferListenerInstantiationHelper::Type - TransferListenerType; + typedef typename TransferListenerInstantiationHelper::Type TransferListenerType; typedef GenericSubscriber BaseType; Callback callback_; diff --git a/libuavcan/include/uavcan/protocol/dynamic_node_id_server/distributed/raft_core.hpp b/libuavcan/include/uavcan/protocol/dynamic_node_id_server/distributed/raft_core.hpp index 7e8a0eafa7..4080d8bbae 100644 --- a/libuavcan/include/uavcan/protocol/dynamic_node_id_server/distributed/raft_core.hpp +++ b/libuavcan/include/uavcan/protocol/dynamic_node_id_server/distributed/raft_core.hpp @@ -126,8 +126,8 @@ private: */ ServiceServer append_entries_srv_; ServiceClient append_entries_client_; - ServiceServer request_vote_srv_; - ServiceClient request_vote_client_; + ServiceServer request_vote_srv_; + ServiceClient request_vote_client_; /* * Methods diff --git a/libuavcan/include/uavcan/protocol/dynamic_node_id_server/node_discoverer.hpp b/libuavcan/include/uavcan/protocol/dynamic_node_id_server/node_discoverer.hpp index 2e4a015c63..4f856e7090 100644 --- a/libuavcan/include/uavcan/protocol/dynamic_node_id_server/node_discoverer.hpp +++ b/libuavcan/include/uavcan/protocol/dynamic_node_id_server/node_discoverer.hpp @@ -84,7 +84,7 @@ class NodeDiscoverer : TimerBase { } }; - typedef Map NodeMap; + typedef Map NodeMap; /** * When this number of attempts has been made, the discoverer will give up and assume that the node @@ -101,10 +101,10 @@ class NodeDiscoverer : TimerBase IEventTracer& tracer_; BitSet committed_node_mask_; ///< Nodes that are marked will not be queried - NodeMap node_map_; ///< Will not work in UAVCAN_TINY + NodeMap node_map_; ServiceClient get_node_info_client_; - Subscriber node_status_sub_; + Subscriber node_status_sub_; /* * Methods diff --git a/libuavcan/include/uavcan/protocol/global_time_sync_slave.hpp b/libuavcan/include/uavcan/protocol/global_time_sync_slave.hpp index 2d9336ffb5..770cd721ad 100644 --- a/libuavcan/include/uavcan/protocol/global_time_sync_slave.hpp +++ b/libuavcan/include/uavcan/protocol/global_time_sync_slave.hpp @@ -31,8 +31,7 @@ class UAVCAN_EXPORT GlobalTimeSyncSlave : Noncopyable void (GlobalTimeSyncSlave::*)(const ReceivedDataStructure&)> GlobalTimeSyncCallback; - // Static buffers are explicitly disabled because time should never be unicasted. - Subscriber sub_; + Subscriber sub_; UtcTime prev_ts_utc_; MonotonicTime prev_ts_mono_; diff --git a/libuavcan/include/uavcan/protocol/node_info_retriever.hpp b/libuavcan/include/uavcan/protocol/node_info_retriever.hpp index 3089150f2f..9ff2bcc79b 100644 --- a/libuavcan/include/uavcan/protocol/node_info_retriever.hpp +++ b/libuavcan/include/uavcan/protocol/node_info_retriever.hpp @@ -156,7 +156,6 @@ private: } }; - enum { NumStaticCalls = 2 }; enum { DefaultNumRequestAttempts = 16 }; enum { DefaultTimerIntervalMSec = 40 }; ///< Read explanation in the class documentation @@ -165,9 +164,9 @@ private: */ Entry entries_[NodeID::Max]; // [1, NodeID::Max] - Multiset listeners_; + Multiset listeners_; - ServiceClient get_node_info_client_; + ServiceClient get_node_info_client_; MonotonicDuration request_interval_; diff --git a/libuavcan/include/uavcan/protocol/node_status_monitor.hpp b/libuavcan/include/uavcan/protocol/node_status_monitor.hpp index 2c3c1256fa..c915ec6d10 100644 --- a/libuavcan/include/uavcan/protocol/node_status_monitor.hpp +++ b/libuavcan/include/uavcan/protocol/node_status_monitor.hpp @@ -75,7 +75,7 @@ private: typedef MethodBinder TimerCallback; - Subscriber sub_; + Subscriber sub_; TimerEventForwarder timer_; diff --git a/libuavcan/include/uavcan/transport/can_acceptance_filter_configurator.hpp b/libuavcan/include/uavcan/transport/can_acceptance_filter_configurator.hpp index 8b9a716343..e7c7d6e7a1 100644 --- a/libuavcan/include/uavcan/transport/can_acceptance_filter_configurator.hpp +++ b/libuavcan/include/uavcan/transport/can_acceptance_filter_configurator.hpp @@ -65,7 +65,7 @@ private: static const unsigned DefaultAnonMsgMask = 0xFF; static const unsigned DefaultAnonMsgID = 0x0; - typedef uavcan::Multiset MultisetConfigContainer; + typedef uavcan::Multiset MultisetConfigContainer; static CanFilterConfig mergeFilters(CanFilterConfig &a_, CanFilterConfig &b_); static uint8_t countBits(uint32_t n_); diff --git a/libuavcan/include/uavcan/transport/outgoing_transfer_registry.hpp b/libuavcan/include/uavcan/transport/outgoing_transfer_registry.hpp index 4a93fd2be7..c6d2c0c412 100644 --- a/libuavcan/include/uavcan/transport/outgoing_transfer_registry.hpp +++ b/libuavcan/include/uavcan/transport/outgoing_transfer_registry.hpp @@ -60,6 +60,8 @@ public: * Outgoing transfer registry keeps track of Transfer ID values for all currently existing local transfer senders. * If a local transfer sender was inactive for a sufficiently long time, the outgoing transfer registry will * remove the respective Transfer ID tracking object. + * + * TODO: Deinterface this. */ class UAVCAN_EXPORT IOutgoingTransferRegistry { @@ -74,7 +76,6 @@ public: }; -template class UAVCAN_EXPORT OutgoingTransferRegistry : public IOutgoingTransferRegistry, Noncopyable { struct Value @@ -123,7 +124,7 @@ class UAVCAN_EXPORT OutgoingTransferRegistry : public IOutgoingTransferRegistry, } }; - Map map_; + Map map_; public: explicit OutgoingTransferRegistry(IPoolAllocator& allocator) @@ -140,11 +141,12 @@ public: // ---------------------------------------------------------------------------- /* - * OutgoingTransferRegistry<> + * OutgoingTransferRegistry + * TODO: deinterface and move to .cpp */ -template -TransferID* OutgoingTransferRegistry::accessOrCreate(const OutgoingTransferRegistryKey& key, - MonotonicTime new_deadline) +inline +TransferID* OutgoingTransferRegistry::accessOrCreate(const OutgoingTransferRegistryKey& key, + MonotonicTime new_deadline) { UAVCAN_ASSERT(!new_deadline.isZero()); Value* p = map_.access(key); @@ -161,14 +163,14 @@ TransferID* OutgoingTransferRegistry::accessOrCreate(const Out return &p->tid; } -template -bool OutgoingTransferRegistry::exists(DataTypeID dtid, TransferType tt) const +inline +bool OutgoingTransferRegistry::exists(DataTypeID dtid, TransferType tt) const { return NULL != map_.find(ExistenceCheckingPredicate(dtid, tt)); } -template -void OutgoingTransferRegistry::cleanup(MonotonicTime ts) +inline +void OutgoingTransferRegistry::cleanup(MonotonicTime ts) { map_.removeAllWhere(DeadlineExpiredPredicate(ts)); } diff --git a/libuavcan/include/uavcan/transport/transfer_buffer.hpp b/libuavcan/include/uavcan/transport/transfer_buffer.hpp index 977bd3e368..7ea35145be 100644 --- a/libuavcan/include/uavcan/transport/transfer_buffer.hpp +++ b/libuavcan/include/uavcan/transport/transfer_buffer.hpp @@ -194,8 +194,6 @@ public: virtual int read(unsigned offset, uint8_t* data, unsigned len) const; virtual int write(unsigned offset, const uint8_t* data, unsigned len); - - bool migrateFrom(const TransferBufferManagerEntry* tbme); }; template @@ -250,11 +248,7 @@ class TransferBufferManagerImpl : public ITransferBufferManager, Noncopyable IPoolAllocator& allocator_; const uint16_t max_buf_size_; - virtual StaticTransferBufferManagerEntryImpl* getStaticByIndex(uint16_t index) const = 0; - - StaticTransferBufferManagerEntryImpl* findFirstStatic(const TransferBufferManagerKey& key); DynamicTransferBufferManagerEntry* findFirstDynamic(const TransferBufferManagerKey& key); - void optimizeStorage(); public: TransferBufferManagerImpl(uint16_t max_buf_size, IPoolAllocator& allocator) @@ -269,49 +263,20 @@ public: virtual void remove(const TransferBufferManagerKey& key); virtual bool isEmpty() const; - unsigned getNumDynamicBuffers() const; - unsigned getNumStaticBuffers() const; -}; - -template -class UAVCAN_EXPORT TransferBufferManager : public TransferBufferManagerImpl -{ - mutable StaticTransferBufferManagerEntry static_buffers_[NumStaticBufs]; - - virtual StaticTransferBufferManagerEntry* getStaticByIndex(uint16_t index) const - { - return (index < NumStaticBufs) ? &static_buffers_[index] : NULL; - } - -public: - explicit TransferBufferManager(IPoolAllocator& allocator) - : TransferBufferManagerImpl(MaxBufSize, allocator) - { -#if UAVCAN_TINY - StaticAssert<(NumStaticBufs == 0)>::check(); // Static buffers in UAVCAN_TINY mode are not allowed -#endif - StaticAssert<(MaxBufSize > 0)>::check(); - } + unsigned getNumBuffers() const; }; template -class UAVCAN_EXPORT TransferBufferManager : public TransferBufferManagerImpl +class UAVCAN_EXPORT TransferBufferManager : public TransferBufferManagerImpl { - virtual StaticTransferBufferManagerEntry* getStaticByIndex(uint16_t) const - { - return NULL; - } - public: - explicit TransferBufferManager(IPoolAllocator& allocator) - : TransferBufferManagerImpl(MaxBufSize, allocator) - { - StaticAssert<(MaxBufSize > 0)>::check(); - } + explicit TransferBufferManager(IPoolAllocator& allocator) : + TransferBufferManagerImpl(MaxBufSize, allocator) + { } }; template <> -class UAVCAN_EXPORT TransferBufferManager<0, 0> : public ITransferBufferManager +class UAVCAN_EXPORT TransferBufferManager<0> : public ITransferBufferManager { public: TransferBufferManager() { } diff --git a/libuavcan/include/uavcan/transport/transfer_listener.hpp b/libuavcan/include/uavcan/transport/transfer_listener.hpp index 66bfe9f6f7..181a2e36b1 100644 --- a/libuavcan/include/uavcan/transport/transfer_listener.hpp +++ b/libuavcan/include/uavcan/transport/transfer_listener.hpp @@ -99,7 +99,7 @@ public: class UAVCAN_EXPORT TransferListenerBase : public LinkedListNode, Noncopyable { const DataTypeDescriptor& data_type_; - MapBase& receivers_; + Map& receivers_; ITransferBufferManager& bufmgr_; TransferPerfCounter& perf_; const TransferCRC crc_base_; ///< Pre-initialized with data type hash, thus constant @@ -123,7 +123,7 @@ class UAVCAN_EXPORT TransferListenerBase : public LinkedListNode& receivers, + Map& receivers, ITransferBufferManager& bufmgr) : data_type_(data_type) , receivers_(receivers) @@ -157,24 +157,18 @@ public: /** * This class should be derived by transfer receivers (subscribers, servers). */ -template +template class UAVCAN_EXPORT TransferListener : public TransferListenerBase { - TransferBufferManager bufmgr_; - Map receivers_; + TransferBufferManager bufmgr_; + Map receivers_; public: TransferListener(TransferPerfCounter& perf, const DataTypeDescriptor& data_type, IPoolAllocator& allocator) : TransferListenerBase(perf, data_type, receivers_, bufmgr_) , bufmgr_(allocator) , receivers_(allocator) - { -#if UAVCAN_TINY - StaticAssert::check(); - StaticAssert::check(); -#endif - StaticAssert<(NumStaticReceivers >= NumStaticBufs)>::check(); // Otherwise it would be meaningless - } + { } virtual ~TransferListener() { @@ -200,15 +194,15 @@ public: /** * This class should be derived by callers. */ -template -class UAVCAN_EXPORT TransferListenerWithFilter : public TransferListener +template +class UAVCAN_EXPORT TransferListenerWithFilter : public TransferListener { const ITransferAcceptanceFilter* filter_; virtual void handleFrame(const RxFrame& frame); public: - typedef TransferListener BaseType; + typedef TransferListener BaseType; TransferListenerWithFilter(TransferPerfCounter& perf, const DataTypeDescriptor& data_type, IPoolAllocator& allocator) @@ -227,8 +221,8 @@ public: /* * TransferListenerWithFilter<> */ -template -void TransferListenerWithFilter::handleFrame(const RxFrame& frame) +template +void TransferListenerWithFilter::handleFrame(const RxFrame& frame) { if (filter_ != NULL) { diff --git a/libuavcan/include/uavcan/util/map.hpp b/libuavcan/include/uavcan/util/map.hpp index 9c43394ba3..d7c2b29625 100644 --- a/libuavcan/include/uavcan/util/map.hpp +++ b/libuavcan/include/uavcan/util/map.hpp @@ -18,9 +18,7 @@ namespace uavcan /** * Slow but memory efficient KV container. * - * KV pairs can be allocated in a static buffer or in the node's memory pool if the static buffer is exhausted. - * When a KV pair is deleted from the static buffer, one pair from the memory pool will be moved in the free - * slot of the static buffer, so the use of the memory pool is minimized. + * KV pairs will be allocated in the node's memory pool. * * Please be aware that this container does not perform any speed optimizations to minimize memory footprint, * so the complexity of most operations is O(N). @@ -32,10 +30,8 @@ namespace uavcan * Size of Key + Value + padding must not exceed MemPoolBlockSize. */ template -class UAVCAN_EXPORT MapBase : Noncopyable +class UAVCAN_EXPORT Map : Noncopyable { - template friend class Map; - public: struct KVPair { @@ -102,16 +98,9 @@ private: LinkedListRoot list_; IPoolAllocator& allocator_; -#if !UAVCAN_TINY - KVPair* const static_; - const unsigned num_static_entries_; -#endif KVPair* findKey(const Key& key); -#if !UAVCAN_TINY - void optimizeStorage(); -#endif void compact(); struct YesPredicate @@ -119,30 +108,18 @@ private: bool operator()(const Key&, const Value&) const { return true; } }; -protected: -#if UAVCAN_TINY - MapBase(IPoolAllocator& allocator) - : allocator_(allocator) - { - UAVCAN_ASSERT(Key() == Key()); - } -#else - MapBase(KVPair* static_buf, unsigned num_static_entries, IPoolAllocator& allocator) - : allocator_(allocator) - , static_(static_buf) - , num_static_entries_(num_static_entries) - { - UAVCAN_ASSERT(Key() == Key()); - } -#endif - - /// Derived class destructor must call clear(); - ~MapBase() - { - UAVCAN_ASSERT(getSize() == 0); - } - public: + Map(IPoolAllocator& allocator) : + allocator_(allocator) + { + UAVCAN_ASSERT(Key() == Key()); + } + + ~Map() + { + clear(); + } + /** * Returns null pointer if there's no such entry. */ @@ -192,69 +169,20 @@ public: */ bool isEmpty() const { return find(YesPredicate()) == NULL; } - unsigned getSize() const; - /** - * For testing, do not use directly. + * Complexity is O(N). */ - unsigned getNumStaticPairs() const; - unsigned getNumDynamicPairs() const; -}; - - -template -class UAVCAN_EXPORT Map : public MapBase -{ - typename MapBase::KVPair static_[NumStaticEntries]; - -public: - -#if !UAVCAN_TINY - - // This instantiation will not be valid in UAVCAN_TINY mode - explicit Map(IPoolAllocator& allocator) - : MapBase(static_, NumStaticEntries, allocator) - { } - - ~Map() { this->clear(); } - -#endif // !UAVCAN_TINY -}; - - -template -class UAVCAN_EXPORT Map : public MapBase -{ -public: - explicit Map(IPoolAllocator& allocator) -#if UAVCAN_TINY - : MapBase(allocator) -#else - : MapBase(NULL, 0, allocator) -#endif - { } - - ~Map() { this->clear(); } + unsigned getSize() const; }; // ---------------------------------------------------------------------------- /* - * MapBase<> + * Map<> */ template -typename MapBase::KVPair* MapBase::findKey(const Key& key) +typename Map::KVPair* Map::findKey(const Key& key) { -#if !UAVCAN_TINY - for (unsigned i = 0; i < num_static_entries_; i++) - { - if (static_[i].match(key)) - { - return static_ + i; - } - } -#endif - KVGroup* p = list_.get(); while (p) { @@ -268,64 +196,8 @@ typename MapBase::KVPair* MapBase::findKey(const Key& ke return NULL; } -#if !UAVCAN_TINY - template -void MapBase::optimizeStorage() -{ - while (true) - { - // Looking for first EMPTY static entry - KVPair* stat = NULL; - for (unsigned i = 0; i < num_static_entries_; i++) - { - if (static_[i].match(Key())) - { - stat = static_ + i; - break; - } - } - if (stat == NULL) - { - break; - } - - // Looking for the first NON-EMPTY dynamic entry, erasing immediately - KVGroup* p = list_.get(); - KVPair dyn; - while (p) - { - bool stop = false; - for (int i = 0; i < KVGroup::NumKV; i++) - { - if (!p->kvs[i].match(Key())) // Non empty - { - dyn = p->kvs[i]; // Copy by value - p->kvs[i] = KVPair(); // Erase immediately - stop = true; - break; - } - } - if (stop) - { - break; - } - p = p->getNextListNode(); - } - if (dyn.match(Key())) - { - break; - } - - // Migrating - *stat = dyn; - } -} - -#endif // !UAVCAN_TINY - -template -void MapBase::compact() +void Map::compact() { KVGroup* p = list_.get(); while (p) @@ -350,7 +222,7 @@ void MapBase::compact() } template -Value* MapBase::access(const Key& key) +Value* Map::access(const Key& key) { UAVCAN_ASSERT(!(key == Key())); KVPair* const kv = findKey(key); @@ -358,7 +230,7 @@ Value* MapBase::access(const Key& key) } template -Value* MapBase::insert(const Key& key, const Value& value) +Value* Map::insert(const Key& key, const Value& value) { UAVCAN_ASSERT(!(key == Key())); remove(key); @@ -381,40 +253,23 @@ Value* MapBase::insert(const Key& key, const Value& value) } template -void MapBase::remove(const Key& key) +void Map::remove(const Key& key) { UAVCAN_ASSERT(!(key == Key())); KVPair* const kv = findKey(key); if (kv) { *kv = KVPair(); -#if !UAVCAN_TINY - optimizeStorage(); -#endif compact(); } } template template -void MapBase::removeAllWhere(Predicate predicate) +void Map::removeAllWhere(Predicate predicate) { unsigned num_removed = 0; -#if !UAVCAN_TINY - for (unsigned i = 0; i < num_static_entries_; i++) - { - if (!static_[i].match(Key())) - { - if (predicate(static_[i].key, static_[i].value)) - { - num_removed++; - static_[i] = KVPair(); - } - } - } -#endif - KVGroup* p = list_.get(); while (p != NULL) { @@ -438,30 +293,14 @@ void MapBase::removeAllWhere(Predicate predicate) if (num_removed > 0) { -#if !UAVCAN_TINY - optimizeStorage(); -#endif compact(); } } template template -const Key* MapBase::find(Predicate predicate) const +const Key* Map::find(Predicate predicate) const { -#if !UAVCAN_TINY - for (unsigned i = 0; i < num_static_entries_; i++) - { - if (!static_[i].match(Key())) - { - if (predicate(static_[i].key, static_[i].value)) - { - return &static_[i].key; - } - } - } -#endif - KVGroup* p = list_.get(); while (p != NULL) { @@ -485,29 +324,14 @@ const Key* MapBase::find(Predicate predicate) const } template -void MapBase::clear() +void Map::clear() { removeAllWhere(YesPredicate()); } template -typename MapBase::KVPair* MapBase::getByIndex(unsigned index) +typename Map::KVPair* Map::getByIndex(unsigned index) { -#if !UAVCAN_TINY - // Checking the static storage - for (unsigned i = 0; i < num_static_entries_; i++) - { - if (!static_[i].match(Key())) - { - if (index == 0) - { - return static_ + i; - } - index--; - } - } -#endif - // Slowly crawling through the dynamic storage KVGroup* p = list_.get(); while (p != NULL) @@ -534,35 +358,13 @@ typename MapBase::KVPair* MapBase::getByIndex(unsigned i } template -const typename MapBase::KVPair* MapBase::getByIndex(unsigned index) const +const typename Map::KVPair* Map::getByIndex(unsigned index) const { - return const_cast*>(this)->getByIndex(index); + return const_cast*>(this)->getByIndex(index); } template -unsigned MapBase::getSize() const -{ - return getNumStaticPairs() + getNumDynamicPairs(); -} - -template -unsigned MapBase::getNumStaticPairs() const -{ - unsigned num = 0; -#if !UAVCAN_TINY - for (unsigned i = 0; i < num_static_entries_; i++) - { - if (!static_[i].match(Key())) - { - num++; - } - } -#endif - return num; -} - -template -unsigned MapBase::getNumDynamicPairs() const +unsigned Map::getSize() const { unsigned num = 0; KVGroup* p = list_.get(); diff --git a/libuavcan/include/uavcan/util/multiset.hpp b/libuavcan/include/uavcan/util/multiset.hpp index c1a99d31ea..ae04dfd4e0 100644 --- a/libuavcan/include/uavcan/util/multiset.hpp +++ b/libuavcan/include/uavcan/util/multiset.hpp @@ -23,11 +23,9 @@ namespace uavcan * Slow but memory efficient unordered multiset. Unlike Map<>, this container does not move objects, so * they don't have to be copyable. * - * Items can be allocated in a static buffer or in the node's memory pool if the static buffer is exhausted. - * - * Number of static entries must not be less than 1. + * Items will be allocated in the node's memory pool. */ -template +template class UAVCAN_EXPORT Multiset : Noncopyable { struct Item : ::uavcan::Noncopyable @@ -122,7 +120,6 @@ private: */ LinkedListRoot list_; IPoolAllocator& allocator_; - Item static_[NumStaticEntries]; /* * Methods @@ -333,13 +330,7 @@ public: * Counts number of items stored. * Best case complexity is O(N). */ - unsigned getSize() const { return getNumStaticItems() + getNumDynamicItems(); } - - /** - * For testing, do not use directly. - */ - unsigned getNumStaticItems() const; - unsigned getNumDynamicItems() const; + unsigned getSize() const; }; // ---------------------------------------------------------------------------- @@ -347,21 +338,10 @@ public: /* * Multiset<> */ -template -typename Multiset::Item* Multiset::findOrCreateFreeSlot() +template +typename Multiset::Item* Multiset::findOrCreateFreeSlot() { -#if !UAVCAN_TINY - // Search in static pool - for (unsigned i = 0; i < NumStaticEntries; i++) - { - if (!static_[i].isConstructed()) - { - return &static_[i]; - } - } -#endif - - // Search in dynamic pool + // Search { Chunk* p = list_.get(); while (p) @@ -375,7 +355,7 @@ typename Multiset::Item* Multiset::fin } } - // Create new dynamic chunk + // Create new chunk Chunk* const chunk = Chunk::instantiate(allocator_); if (chunk == NULL) { @@ -385,8 +365,8 @@ typename Multiset::Item* Multiset::fin return &chunk->items[0]; } -template -void Multiset::compact() +template +void Multiset::compact() { Chunk* p = list_.get(); while (p) @@ -410,30 +390,12 @@ void Multiset::compact() } } -template +template template -void Multiset::removeWhere(Predicate predicate, const RemoveStrategy strategy) +void Multiset::removeWhere(Predicate predicate, const RemoveStrategy strategy) { unsigned num_removed = 0; -#if !UAVCAN_TINY - for (unsigned i = 0; i < NumStaticEntries; i++) - { - if (static_[i].isConstructed()) - { - if (predicate(*static_[i].ptr)) - { - num_removed++; - static_[i].destroy(); - if (strategy == RemoveOne) - { - break; - } - } - } - } -#endif - Chunk* p = list_.get(); while (p != NULL) { @@ -470,23 +432,10 @@ void Multiset::removeWhere(Predicate predicate, const Remov } } -template +template template -T* Multiset::find(Predicate predicate) +T* Multiset::find(Predicate predicate) { -#if !UAVCAN_TINY - for (unsigned i = 0; i < NumStaticEntries; i++) - { - if (static_[i].isConstructed()) - { - if (predicate(*static_[i].ptr)) - { - return static_[i].ptr; - } - } - } -#endif - Chunk* p = list_.get(); while (p != NULL) { @@ -508,21 +457,8 @@ T* Multiset::find(Predicate predicate) return NULL; } -template -unsigned Multiset::getNumStaticItems() const -{ - unsigned num = 0; -#if !UAVCAN_TINY - for (unsigned i = 0; i < NumStaticEntries; i++) - { - num += static_[i].isConstructed() ? 1U : 0U; - } -#endif - return num; -} - -template -unsigned Multiset::getNumDynamicItems() const +template +unsigned Multiset::getSize() const { unsigned num = 0; Chunk* p = list_.get(); diff --git a/libuavcan/src/transport/uc_transfer_buffer.cpp b/libuavcan/src/transport/uc_transfer_buffer.cpp index fb3774c7d9..f684d8ecd7 100644 --- a/libuavcan/src/transport/uc_transfer_buffer.cpp +++ b/libuavcan/src/transport/uc_transfer_buffer.cpp @@ -291,58 +291,9 @@ int StaticTransferBufferManagerEntryImpl::write(unsigned offset, const uint8_t* return buf_.write(offset, data, len); } -bool StaticTransferBufferManagerEntryImpl::migrateFrom(const TransferBufferManagerEntry* tbme) -{ - if (tbme == NULL || tbme->isEmpty()) - { - UAVCAN_ASSERT(0); - return false; - } - - // Resetting self and moving all data from the source - TransferBufferManagerEntry::reset(tbme->getKey()); - const int res = tbme->read(0, buf_.getRawPtr(), buf_.getSize()); - if (res < 0) - { - TransferBufferManagerEntry::reset(); - return false; - } - buf_.setMaxWritePos(uint16_t(res)); - if (res < int(buf_.getSize())) - { - return true; - } - - // Now we need to make sure that all data can fit the storage - uint8_t dummy = 0; - if (tbme->read(buf_.getSize(), &dummy, 1) > 0) - { - TransferBufferManagerEntry::reset(); // Damn, the buffer was too large - return false; - } - return true; -} - /* * TransferBufferManagerImpl */ -StaticTransferBufferManagerEntryImpl* TransferBufferManagerImpl::findFirstStatic(const TransferBufferManagerKey& key) -{ - for (unsigned i = 0; true; i++) - { - StaticTransferBufferManagerEntryImpl* const sb = getStaticByIndex(uint16_t(i)); - if (sb == NULL) - { - break; - } - if (sb->getKey() == key) - { - return sb; - } - } - return NULL; -} - DynamicTransferBufferManagerEntry* TransferBufferManagerImpl::findFirstDynamic(const TransferBufferManagerKey& key) { DynamicTransferBufferManagerEntry* dyn = dynamic_buffers_.get(); @@ -358,40 +309,6 @@ DynamicTransferBufferManagerEntry* TransferBufferManagerImpl::findFirstDynamic(c return NULL; } -void TransferBufferManagerImpl::optimizeStorage() -{ - while (!dynamic_buffers_.isEmpty()) - { - StaticTransferBufferManagerEntryImpl* const sb = findFirstStatic(TransferBufferManagerKey()); - if (sb == NULL) - { - break; - } - DynamicTransferBufferManagerEntry* dyn = dynamic_buffers_.get(); - UAVCAN_ASSERT(dyn); - UAVCAN_ASSERT(!dyn->isEmpty()); - if (sb->migrateFrom(dyn)) - { - UAVCAN_ASSERT(!dyn->isEmpty()); - UAVCAN_TRACE("TransferBufferManager", "Storage optimization: Migrated %s", - dyn->getKey().toString().c_str()); - dynamic_buffers_.remove(dyn); - DynamicTransferBufferManagerEntry::destroy(dyn, allocator_); - } - else - { - /* Migration can fail if a dynamic buffer contains more data than a static buffer can accomodate. - * This should never happen during normal operation because dynamic buffers are limited in growth. - */ - UAVCAN_TRACE("TransferBufferManager", "Storage optimization: MIGRATION FAILURE %s MAXSIZE %u", - dyn->getKey().toString().c_str(), max_buf_size_); - UAVCAN_ASSERT(0); - sb->reset(); - break; - } - } -} - TransferBufferManagerImpl::~TransferBufferManagerImpl() { DynamicTransferBufferManagerEntry* dyn = dynamic_buffers_.get(); @@ -411,11 +328,6 @@ ITransferBuffer* TransferBufferManagerImpl::access(const TransferBufferManagerKe UAVCAN_ASSERT(0); return NULL; } - TransferBufferManagerEntry* tbme = findFirstStatic(key); - if (tbme) - { - return tbme; - } return findFirstDynamic(key); } @@ -428,27 +340,17 @@ ITransferBuffer* TransferBufferManagerImpl::create(const TransferBufferManagerKe } remove(key); - TransferBufferManagerEntry* tbme = findFirstStatic(TransferBufferManagerKey()); + DynamicTransferBufferManagerEntry* tbme = DynamicTransferBufferManagerEntry::instantiate(allocator_, max_buf_size_); if (tbme == NULL) { - DynamicTransferBufferManagerEntry* dyn = - DynamicTransferBufferManagerEntry::instantiate(allocator_, max_buf_size_); - tbme = dyn; - if (dyn == NULL) - { - return NULL; // Epic fail. - } - dynamic_buffers_.insert(dyn); - UAVCAN_TRACE("TransferBufferManager", "Dynamic buffer created [st=%u, dyn=%u], %s", - getNumStaticBuffers(), getNumDynamicBuffers(), key.toString().c_str()); - } - else - { - UAVCAN_TRACE("TransferBufferManager", "Static buffer created [st=%u, dyn=%u], %s", - getNumStaticBuffers(), getNumDynamicBuffers(), key.toString().c_str()); + return NULL; // Epic fail. } - if (tbme) + dynamic_buffers_.insert(tbme); + + UAVCAN_TRACE("TransferBufferManager", "Buffer created [num=%u], %s", getNumBuffers(), key.toString().c_str()); + + if (tbme != NULL) { UAVCAN_ASSERT(tbme->isEmpty()); tbme->reset(key); @@ -460,19 +362,10 @@ void TransferBufferManagerImpl::remove(const TransferBufferManagerKey& key) { UAVCAN_ASSERT(!key.isEmpty()); - TransferBufferManagerEntry* const tbme = findFirstStatic(key); - if (tbme) - { - UAVCAN_TRACE("TransferBufferManager", "Static buffer deleted, %s", key.toString().c_str()); - tbme->reset(); - optimizeStorage(); - return; - } - DynamicTransferBufferManagerEntry* dyn = findFirstDynamic(key); - if (dyn) + if (dyn != NULL) { - UAVCAN_TRACE("TransferBufferManager", "Dynamic buffer deleted, %s", key.toString().c_str()); + UAVCAN_TRACE("TransferBufferManager", "Buffer deleted, %s", key.toString().c_str()); dynamic_buffers_.remove(dyn); DynamicTransferBufferManagerEntry::destroy(dyn, allocator_); } @@ -480,30 +373,12 @@ void TransferBufferManagerImpl::remove(const TransferBufferManagerKey& key) bool TransferBufferManagerImpl::isEmpty() const { - return (getNumStaticBuffers() == 0) && (getNumDynamicBuffers() == 0); + return getNumBuffers() == 0; } -unsigned TransferBufferManagerImpl::getNumDynamicBuffers() const +unsigned TransferBufferManagerImpl::getNumBuffers() const { return dynamic_buffers_.getLength(); } -unsigned TransferBufferManagerImpl::getNumStaticBuffers() const -{ - unsigned res = 0; - for (unsigned i = 0; true; i++) - { - StaticTransferBufferManagerEntryImpl* const sb = getStaticByIndex(uint16_t(i)); - if (sb == NULL) - { - break; - } - if (!sb->isEmpty()) - { - res++; - } - } - return res; -} - } diff --git a/libuavcan/test/node/test_node.hpp b/libuavcan/test/node/test_node.hpp index f02ab6b552..1549f5bb45 100644 --- a/libuavcan/test/node/test_node.hpp +++ b/libuavcan/test/node/test_node.hpp @@ -20,7 +20,7 @@ struct TestNode : public uavcan::INode { uavcan::PoolAllocator pool; - uavcan::OutgoingTransferRegistry<8> otr; + uavcan::OutgoingTransferRegistry otr; uavcan::Scheduler scheduler; uint64_t internal_failure_count; diff --git a/libuavcan/test/protocol/dynamic_node_id_server/distributed/server.cpp b/libuavcan/test/protocol/dynamic_node_id_server/distributed/server.cpp index d5cbb4b626..7d7d9a3913 100644 --- a/libuavcan/test/protocol/dynamic_node_id_server/distributed/server.cpp +++ b/libuavcan/test/protocol/dynamic_node_id_server/distributed/server.cpp @@ -190,6 +190,5 @@ TEST(dynamic_node_id_server, ObjectSizes) std::cout << "ServiceServer: " << sizeof(ServiceServer) << std::endl; std::cout << "ServiceClient: " << sizeof(ServiceClient) << std::endl; std::cout << "ServiceServer: " << sizeof(ServiceServer) << std::endl; - std::cout << "ServiceClient:" - << sizeof(ServiceClient&), 5>) << std::endl; + std::cout << "ServiceClient: " << sizeof(ServiceClient) << std::endl; } diff --git a/libuavcan/test/protocol/dynamic_node_id_server/node_discoverer.cpp b/libuavcan/test/protocol/dynamic_node_id_server/node_discoverer.cpp index 288d299b6d..eb3fe234b4 100644 --- a/libuavcan/test/protocol/dynamic_node_id_server/node_discoverer.cpp +++ b/libuavcan/test/protocol/dynamic_node_id_server/node_discoverer.cpp @@ -281,7 +281,5 @@ TEST(dynamic_node_id_server_NodeDiscoverer, Sizes) std::cout << "BitSet: " << sizeof(BitSet) << std::endl; std::cout << "ServiceClient: " << sizeof(ServiceClient) << std::endl; std::cout << "protocol::GetNodeInfo::Response: " << sizeof(protocol::GetNodeInfo::Response) << std::endl; - std::cout << "Subscriber: " - << sizeof(Subscriber&), 64, 0>) << std::endl; + std::cout << "Subscriber: " << sizeof(Subscriber) << std::endl; } diff --git a/libuavcan/test/transport/dispatcher.cpp b/libuavcan/test/transport/dispatcher.cpp index d9e2d937d4..e2daa02f63 100644 --- a/libuavcan/test/transport/dispatcher.cpp +++ b/libuavcan/test/transport/dispatcher.cpp @@ -57,7 +57,7 @@ TEST(Dispatcher, Reception) SystemClockMock clockmock(100); CanDriverMock driver(2, clockmock); - uavcan::OutgoingTransferRegistry<8> out_trans_reg(pool); + uavcan::OutgoingTransferRegistry out_trans_reg(pool); uavcan::Dispatcher dispatcher(driver, pool, clockmock, out_trans_reg); ASSERT_TRUE(dispatcher.setNodeID(SELF_NODE_ID)); // Can be set only once @@ -86,7 +86,7 @@ TEST(Dispatcher, Reception) makeDataType(uavcan::DataTypeKindService, 1) }; - typedef TestListener<512, 2, 2> Subscriber; + typedef TestListener<512> Subscriber; typedef std::auto_ptr SubscriberPtr; static const int NUM_SUBSCRIBERS = 6; SubscriberPtr subscribers[NUM_SUBSCRIBERS] = @@ -255,7 +255,7 @@ TEST(Dispatcher, Transmission) SystemClockMock clockmock(100); CanDriverMock driver(2, clockmock); - uavcan::OutgoingTransferRegistry<8> out_trans_reg(pool); + uavcan::OutgoingTransferRegistry out_trans_reg(pool); uavcan::Dispatcher dispatcher(driver, pool, clockmock, out_trans_reg); ASSERT_TRUE(dispatcher.setNodeID(SELF_NODE_ID)); // Can be set only once @@ -319,7 +319,7 @@ TEST(Dispatcher, Spin) SystemClockMock clockmock(100); CanDriverMock driver(2, clockmock); - uavcan::OutgoingTransferRegistry<8> out_trans_reg(poolmgr); + uavcan::OutgoingTransferRegistry out_trans_reg(poolmgr); uavcan::Dispatcher dispatcher(driver, poolmgr, clockmock, out_trans_reg); ASSERT_TRUE(dispatcher.setNodeID(SELF_NODE_ID)); // Can be set only once @@ -365,7 +365,7 @@ TEST(Dispatcher, Loopback) SystemClockMock clockmock(100); CanDriverMock driver(2, clockmock); - uavcan::OutgoingTransferRegistry<8> out_trans_reg(poolmgr); + uavcan::OutgoingTransferRegistry out_trans_reg(poolmgr); uavcan::Dispatcher dispatcher(driver, poolmgr, clockmock, out_trans_reg); ASSERT_TRUE(dispatcher.setNodeID(SELF_NODE_ID)); diff --git a/libuavcan/test/transport/incoming_transfer.cpp b/libuavcan/test/transport/incoming_transfer.cpp index 2264d848fc..8c52dab8d8 100644 --- a/libuavcan/test/transport/incoming_transfer.cpp +++ b/libuavcan/test/transport/incoming_transfer.cpp @@ -73,7 +73,7 @@ TEST(MultiFrameIncomingTransfer, Basic) using uavcan::MultiFrameIncomingTransfer; NullAllocator poolmgr; // We don't need dynamic memory - uavcan::TransferBufferManager<256, 1> bufmgr(poolmgr); + uavcan::TransferBufferManager<256> bufmgr(poolmgr); const RxFrame frame = makeFrame(); uavcan::TransferBufferManagerKey bufmgr_key(frame.getSrcNodeID(), frame.getTransferType()); diff --git a/libuavcan/test/transport/outgoing_transfer_registry.cpp b/libuavcan/test/transport/outgoing_transfer_registry.cpp index aaffb357a0..9ad8b334d1 100644 --- a/libuavcan/test/transport/outgoing_transfer_registry.cpp +++ b/libuavcan/test/transport/outgoing_transfer_registry.cpp @@ -13,7 +13,7 @@ TEST(OutgoingTransferRegistry, Basic) { using uavcan::OutgoingTransferRegistryKey; NullAllocator poolmgr; // Empty - uavcan::OutgoingTransferRegistry<4> otr(poolmgr); + uavcan::OutgoingTransferRegistry otr(poolmgr); otr.cleanup(tsMono(1000)); diff --git a/libuavcan/test/transport/transfer_buffer.cpp b/libuavcan/test/transport/transfer_buffer.cpp index 719bf5d08c..96c9fe77c5 100644 --- a/libuavcan/test/transport/transfer_buffer.cpp +++ b/libuavcan/test/transport/transfer_buffer.cpp @@ -229,10 +229,10 @@ TEST(TransferBufferManager, Basic) using uavcan::TransferBufferManagerKey; using uavcan::ITransferBuffer; - static const int POOL_BLOCKS = 6; + static const int POOL_BLOCKS = 8; uavcan::PoolAllocator pool; - typedef TransferBufferManager TransferBufferManagerType; + typedef TransferBufferManager TransferBufferManagerType; std::auto_ptr mgr(new TransferBufferManagerType(pool)); // Empty @@ -250,40 +250,32 @@ TEST(TransferBufferManager, Basic) TransferBufferManagerKey(64, uavcan::TransferTypeMessageBroadcast) }; - // Static 0 ASSERT_TRUE((tbb = mgr->create(keys[0]))); ASSERT_EQ(MGR_MAX_BUFFER_SIZE, fillTestData(MGR_TEST_DATA[0], tbb)); - ASSERT_EQ(1, mgr->getNumStaticBuffers()); + ASSERT_EQ(1, mgr->getNumBuffers()); - // Static 1 ASSERT_TRUE((tbb = mgr->create(keys[1]))); ASSERT_EQ(MGR_MAX_BUFFER_SIZE, fillTestData(MGR_TEST_DATA[1], tbb)); - ASSERT_EQ(2, mgr->getNumStaticBuffers()); - ASSERT_EQ(0, mgr->getNumDynamicBuffers()); + ASSERT_EQ(0, mgr->getNumBuffers()); ASSERT_EQ(0, pool.getNumUsedBlocks()); - // Dynamic 0 ASSERT_TRUE((tbb = mgr->create(keys[2]))); ASSERT_EQ(1, pool.getNumUsedBlocks()); // Empty dynamic buffer occupies one block ASSERT_EQ(MGR_MAX_BUFFER_SIZE, fillTestData(MGR_TEST_DATA[2], tbb)); - ASSERT_EQ(2, mgr->getNumStaticBuffers()); - ASSERT_EQ(1, mgr->getNumDynamicBuffers()); + ASSERT_EQ(1, mgr->getNumBuffers()); ASSERT_LT(1, pool.getNumUsedBlocks()); std::cout << "TransferBufferManager - Basic: Pool usage: " << pool.getNumUsedBlocks() << std::endl; - // Dynamic 2 ASSERT_TRUE((tbb = mgr->create(keys[3]))); ASSERT_LT(0, pool.getNumUsedBlocks()); ASSERT_LT(0, fillTestData(MGR_TEST_DATA[3], tbb)); - ASSERT_EQ(2, mgr->getNumStaticBuffers()); - ASSERT_EQ(2, mgr->getNumDynamicBuffers()); + ASSERT_EQ(2, mgr->getNumBuffers()); // Dynamic 3 - will fail due to OOM ASSERT_FALSE((tbb = mgr->create(keys[4]))); - ASSERT_EQ(2, mgr->getNumStaticBuffers()); - ASSERT_EQ(2, mgr->getNumDynamicBuffers()); + ASSERT_EQ(2, mgr->getNumBuffers()); // Making sure all buffers contain proper data ASSERT_TRUE((tbb = mgr->access(keys[0]))); @@ -298,18 +290,14 @@ TEST(TransferBufferManager, Basic) ASSERT_TRUE((tbb = mgr->access(keys[3]))); ASSERT_TRUE(matchAgainst(MGR_TEST_DATA[3], *tbb)); - // Freeing one static buffer; one dynamic must migrate mgr->remove(keys[1]); ASSERT_FALSE(mgr->access(keys[1])); - ASSERT_EQ(2, mgr->getNumStaticBuffers()); - ASSERT_EQ(1, mgr->getNumDynamicBuffers()); // One migrated to the static + ASSERT_EQ(1, mgr->getNumBuffers()); ASSERT_LT(0, pool.getNumFreeBlocks()); - // Removing NodeID 0; one dynamic must migrate mgr->remove(keys[0]); ASSERT_FALSE(mgr->access(keys[0])); - ASSERT_EQ(2, mgr->getNumStaticBuffers()); - ASSERT_EQ(0, mgr->getNumDynamicBuffers()); + ASSERT_EQ(0, mgr->getNumBuffers()); // At this time we have the following NodeID: 2, 127 ASSERT_TRUE((tbb = mgr->access(keys[2]))); @@ -336,7 +324,7 @@ TEST(TransferBufferManager, Basic) TEST(TransferBufferManager, EmptySpecialization) { - uavcan::TransferBufferManager<0, 0> mgr; + uavcan::TransferBufferManager<0> mgr; (void)mgr; ASSERT_GE(sizeof(void*), sizeof(mgr)); } diff --git a/libuavcan/test/transport/transfer_listener.cpp b/libuavcan/test/transport/transfer_listener.cpp index 5a6f2726ae..d5e07596e0 100644 --- a/libuavcan/test/transport/transfer_listener.cpp +++ b/libuavcan/test/transport/transfer_listener.cpp @@ -38,7 +38,7 @@ TEST(TransferListener, BasicMFT) uavcan::PoolAllocator pool; uavcan::TransferPerfCounter perf; - TestListener<256, 1, 1> subscriber(perf, type, pool); + TestListener<256> subscriber(perf, type, pool); /* * Test data @@ -95,7 +95,7 @@ TEST(TransferListener, CrcFailure) NullAllocator poolmgr; // No dynamic memory uavcan::TransferPerfCounter perf; - TestListener<256, 2, 2> subscriber(perf, type, poolmgr); // Static buffer only, 2 entries + TestListener<256> subscriber(perf, type, poolmgr); // Static buffer only, 2 entries /* * Generating transfers with damaged payload (CRC is not valid) @@ -138,7 +138,7 @@ TEST(TransferListener, BasicSFT) NullAllocator poolmgr; // No dynamic memory. At all. uavcan::TransferPerfCounter perf; - TestListener<0, 0, 5> subscriber(perf, type, poolmgr); // Max buf size is 0, i.e. SFT-only + TestListener<0> subscriber(perf, type, poolmgr); // Max buf size is 0, i.e. SFT-only TransferListenerEmulator emulator(subscriber, type); const Transfer transfers[] = @@ -174,7 +174,7 @@ TEST(TransferListener, Cleanup) NullAllocator poolmgr; // No dynamic memory uavcan::TransferPerfCounter perf; - TestListener<256, 1, 2> subscriber(perf, type, poolmgr); // Static buffer only, 1 entry + TestListener<256> subscriber(perf, type, poolmgr); // Static buffer only, 1 entry /* * Generating transfers @@ -229,7 +229,7 @@ TEST(TransferListener, AnonymousTransfers) NullAllocator poolmgr; uavcan::TransferPerfCounter perf; - TestListener<0, 0, 0> subscriber(perf, type, poolmgr); + TestListener<0> subscriber(perf, type, poolmgr); TransferListenerEmulator emulator(subscriber, type); const Transfer transfers[] = @@ -261,5 +261,5 @@ TEST(TransferListener, Sizes) { using namespace uavcan; - std::cout << "sizeof(TransferListener<64, 1, 2>): " << sizeof(TransferListener<64, 1, 2>) << std::endl; + std::cout << "sizeof(TransferListener<64>): " << sizeof(TransferListener<64>) << std::endl; } diff --git a/libuavcan/test/transport/transfer_receiver.cpp b/libuavcan/test/transport/transfer_receiver.cpp index fad00f45b4..f58f21a3d6 100644 --- a/libuavcan/test/transport/transfer_receiver.cpp +++ b/libuavcan/test/transport/transfer_receiver.cpp @@ -76,7 +76,7 @@ struct Context { NullAllocator pool; // We don't need dynamic memory for this test uavcan::TransferReceiver receiver; // Must be default constructible and copyable - uavcan::TransferBufferManager bufmgr; + uavcan::TransferBufferManager bufmgr; Context() : bufmgr(pool) diff --git a/libuavcan/test/transport/transfer_sender.cpp b/libuavcan/test/transport/transfer_sender.cpp index 36a40b6b2b..62205c68c1 100644 --- a/libuavcan/test/transport/transfer_sender.cpp +++ b/libuavcan/test/transport/transfer_sender.cpp @@ -34,7 +34,7 @@ TEST(TransferSender, Basic) SystemClockMock clockmock(100); CanDriverMock driver(2, clockmock); - uavcan::OutgoingTransferRegistry<8> out_trans_reg(poolmgr); + uavcan::OutgoingTransferRegistry out_trans_reg(poolmgr); static const uavcan::NodeID TX_NODE_ID(64); static const uavcan::NodeID RX_NODE_ID(65); @@ -123,9 +123,9 @@ TEST(TransferSender, Basic) } } - TestListener<512, 2, 2> sub_msg(dispatcher_rx.getTransferPerfCounter(), TYPES[0], poolmgr); - TestListener<512, 2, 2> sub_srv_req(dispatcher_rx.getTransferPerfCounter(), TYPES[1], poolmgr); - TestListener<512, 2, 2> sub_srv_resp(dispatcher_rx.getTransferPerfCounter(), TYPES[1], poolmgr); + TestListener<512> sub_msg(dispatcher_rx.getTransferPerfCounter(), TYPES[0], poolmgr); + TestListener<512> sub_srv_req(dispatcher_rx.getTransferPerfCounter(), TYPES[1], poolmgr); + TestListener<512> sub_srv_resp(dispatcher_rx.getTransferPerfCounter(), TYPES[1], poolmgr); dispatcher_rx.registerMessageListener(&sub_msg); dispatcher_rx.registerServiceRequestListener(&sub_srv_req); @@ -195,7 +195,7 @@ TEST(TransferSender, Loopback) SystemClockMock clockmock(100); CanDriverMock driver(2, clockmock); - uavcan::OutgoingTransferRegistry<8> out_trans_reg(poolmgr); + uavcan::OutgoingTransferRegistry out_trans_reg(poolmgr); static const uavcan::NodeID TX_NODE_ID(64); uavcan::Dispatcher dispatcher(driver, poolmgr, clockmock, out_trans_reg); @@ -236,7 +236,7 @@ TEST(TransferSender, PassiveMode) SystemClockMock clockmock(100); CanDriverMock driver(2, clockmock); - uavcan::OutgoingTransferRegistry<8> out_trans_reg(poolmgr); + uavcan::OutgoingTransferRegistry out_trans_reg(poolmgr); uavcan::Dispatcher dispatcher(driver, poolmgr, clockmock, out_trans_reg); diff --git a/libuavcan/test/transport/transfer_test_helpers.cpp b/libuavcan/test/transport/transfer_test_helpers.cpp index c4dc7d7606..f7de3410f1 100644 --- a/libuavcan/test/transport/transfer_test_helpers.cpp +++ b/libuavcan/test/transport/transfer_test_helpers.cpp @@ -11,7 +11,7 @@ TEST(TransferTestHelpers, Transfer) { uavcan::PoolAllocator pool; - uavcan::TransferBufferManager<128, 1> mgr(pool); + uavcan::TransferBufferManager<128> mgr(pool); uavcan::TransferBufferAccessor tba(mgr, uavcan::TransferBufferManagerKey(0, uavcan::TransferTypeMessageBroadcast)); uavcan::RxFrame frame(uavcan::Frame(123, uavcan::TransferTypeMessageBroadcast, 1, 0, 0), diff --git a/libuavcan/test/transport/transfer_test_helpers.hpp b/libuavcan/test/transport/transfer_test_helpers.hpp index d423f142e8..d1b4f76375 100644 --- a/libuavcan/test/transport/transfer_test_helpers.hpp +++ b/libuavcan/test/transport/transfer_test_helpers.hpp @@ -117,10 +117,10 @@ struct Transfer * In reality, uavcan::TransferListener should accept only specific transfer types * which are dispatched/filtered by uavcan::Dispatcher. */ -template -class TestListener : public uavcan::TransferListener +template +class TestListener : public uavcan::TransferListener { - typedef uavcan::TransferListener Base; + typedef uavcan::TransferListener Base; std::queue transfers_; diff --git a/libuavcan/test/util/map.cpp b/libuavcan/test/util/map.cpp index 60386058ec..947bb52010 100644 --- a/libuavcan/test/util/map.cpp +++ b/libuavcan/test/util/map.cpp @@ -2,6 +2,11 @@ * Copyright (C) 2014 Pavel Kirienko */ +#if __GNUC__ +// We need auto_ptr for compatibility reasons +# pragma GCC diagnostic ignored "-Wdeprecated-declarations" +#endif + #include #include #include @@ -46,7 +51,7 @@ TEST(Map, Basic) static const int POOL_BLOCKS = 3; uavcan::PoolAllocator pool; - typedef Map MapType; + typedef Map MapType; std::auto_ptr map(new MapType(pool)); // Empty @@ -57,25 +62,23 @@ TEST(Map, Basic) ASSERT_FALSE(map->getByIndex(1)); ASSERT_FALSE(map->getByIndex(10000)); - // Static insertion + // Insertion ASSERT_EQ("a", *map->insert("1", "a")); ASSERT_EQ("b", *map->insert("2", "b")); - ASSERT_EQ(0, pool.getNumUsedBlocks()); - ASSERT_EQ(2, map->getNumStaticPairs()); - ASSERT_EQ(0, map->getNumDynamicPairs()); + ASSERT_EQ(1, pool.getNumUsedBlocks()); + ASSERT_EQ(2, map->getSize()); // Ordering ASSERT_TRUE(map->getByIndex(0)->match("1")); ASSERT_TRUE(map->getByIndex(1)->match("2")); - // Dynamic insertion + // Insertion ASSERT_EQ("c", *map->insert("3", "c")); ASSERT_EQ(1, pool.getNumUsedBlocks()); ASSERT_EQ("d", *map->insert("4", "d")); - ASSERT_EQ(1, pool.getNumUsedBlocks()); // Assuming that at least 2 items fit one block - ASSERT_EQ(2, map->getNumStaticPairs()); - ASSERT_EQ(2, map->getNumDynamicPairs()); + ASSERT_EQ(2, pool.getNumUsedBlocks()); // Assuming that at least 2 items fit one block + ASSERT_EQ(4, map->getSize()); // Making sure everything is here ASSERT_EQ("a", *map->access("1")); @@ -116,12 +119,11 @@ TEST(Map, Basic) ASSERT_EQ("4", *map->find(ValueFindPredicate("D"))); ASSERT_FALSE(map->find(KeyFindPredicate("nonexistent_value"))); - // Removing one static + // Removing one map->remove("1"); // One of dynamics now migrates to the static storage map->remove("foo"); // There's no such thing anyway - ASSERT_EQ(1, pool.getNumUsedBlocks()); - ASSERT_EQ(2, map->getNumStaticPairs()); - ASSERT_EQ(1, map->getNumDynamicPairs()); + ASSERT_EQ(2, pool.getNumUsedBlocks()); + ASSERT_EQ(3, map->getSize()); ASSERT_FALSE(map->access("1")); ASSERT_EQ("B", *map->access("2")); @@ -135,9 +137,8 @@ TEST(Map, Basic) // Removing another static map->remove("2"); - ASSERT_EQ(2, map->getNumStaticPairs()); - ASSERT_EQ(0, map->getNumDynamicPairs()); - ASSERT_EQ(0, pool.getNumUsedBlocks()); // No dynamic entries left + ASSERT_EQ(1, map->getSize()); + ASSERT_EQ(1, pool.getNumUsedBlocks()); // No dynamic entries left ASSERT_FALSE(map->access("1")); ASSERT_FALSE(map->access("2")); @@ -172,13 +173,7 @@ TEST(Map, Basic) ASSERT_FALSE(map->access("value")); // Removing odd values - nearly half of them - ASSERT_EQ(2, map->getNumStaticPairs()); - const unsigned num_dynamics_old = map->getNumDynamicPairs(); map->removeAllWhere(oddValuePredicate); - ASSERT_EQ(2, map->getNumStaticPairs()); - const unsigned num_dynamics_new = map->getNumDynamicPairs(); - std::cout << "Num of dynamic pairs reduced from " << num_dynamics_old << " to " << num_dynamics_new << std::endl; - ASSERT_LT(num_dynamics_new, num_dynamics_old); // Making sure there's no odd values left for (unsigned kv_int = 0; kv_int <= max_key_integer; kv_int++) @@ -220,8 +215,7 @@ TEST(Map, NoStatic) ASSERT_EQ("a", *map->insert("1", "a")); ASSERT_EQ("b", *map->insert("2", "b")); ASSERT_EQ(1, pool.getNumUsedBlocks()); - ASSERT_EQ(0, map->getNumStaticPairs()); - ASSERT_EQ(2, map->getNumDynamicPairs()); + ASSERT_EQ(2, map->getSize()); // Ordering ASSERT_TRUE(map->getByIndex(0)->match("1")); @@ -238,7 +232,7 @@ TEST(Map, PrimitiveKey) static const int POOL_BLOCKS = 3; uavcan::PoolAllocator pool; - typedef Map MapType; + typedef Map MapType; std::auto_ptr map(new MapType(pool)); // Empty diff --git a/libuavcan/test/util/multiset.cpp b/libuavcan/test/util/multiset.cpp index 505deb8ddc..bfd6384049 100644 --- a/libuavcan/test/util/multiset.cpp +++ b/libuavcan/test/util/multiset.cpp @@ -71,7 +71,7 @@ TEST(Multiset, Basic) static const int POOL_BLOCKS = 3; uavcan::PoolAllocator pool; - typedef Multiset MultisetType; + typedef Multiset MultisetType; std::auto_ptr mset(new MultisetType(pool)); typedef SummationOperator StringConcatenationOperator; @@ -86,9 +86,8 @@ TEST(Multiset, Basic) // Static addion ASSERT_EQ("1", *mset->emplace("1")); ASSERT_EQ("2", *mset->emplace("2")); - ASSERT_EQ(0, pool.getNumUsedBlocks()); - ASSERT_EQ(2, mset->getNumStaticItems()); - ASSERT_EQ(0, mset->getNumDynamicItems()); + ASSERT_LE(1, pool.getNumUsedBlocks()); // One or more + ASSERT_EQ(2, mset->getSize()); // Ordering ASSERT_TRUE(*mset->getByIndex(0) == "1"); @@ -103,12 +102,11 @@ TEST(Multiset, Basic) // Dynamic addition ASSERT_EQ("3", *mset->emplace("3")); ASSERT_EQ("3", *mset->getByIndex(2)); - ASSERT_EQ(1, pool.getNumUsedBlocks()); + ASSERT_LE(1, pool.getNumUsedBlocks()); // One or more ASSERT_EQ("4", *mset->emplace("4")); ASSERT_LE(1, pool.getNumUsedBlocks()); // One or more - ASSERT_EQ(2, mset->getNumStaticItems()); - ASSERT_EQ(2, mset->getNumDynamicItems()); + ASSERT_EQ(4, mset->getSize()); // Making sure everything is here ASSERT_EQ("1", *mset->getByIndex(0)); @@ -117,9 +115,6 @@ TEST(Multiset, Basic) ASSERT_FALSE(mset->getByIndex(100)); ASSERT_FALSE(mset->getByIndex(4)); - const std::string data_at_pos2 = *mset->getByIndex(2); - const std::string data_at_pos3 = *mset->getByIndex(3); - // Finding some items ASSERT_EQ("1", *mset->find(FindPredicate("1"))); ASSERT_EQ("2", *mset->find(FindPredicate("2"))); @@ -134,23 +129,10 @@ TEST(Multiset, Basic) ASSERT_EQ(4, op.accumulator.size()); } - // Removing one static; ordering will be preserved + // Removing some mset->removeFirst("1"); mset->removeFirst("foo"); // There's no such thing anyway - ASSERT_LE(1, pool.getNumUsedBlocks()); - ASSERT_EQ(1, mset->getNumStaticItems()); - ASSERT_EQ(2, mset->getNumDynamicItems()); // This container does not move items - - // Ordering has not changed - ASSERT_EQ("2", *mset->getByIndex(0)); // Entry "1" was here - ASSERT_EQ(data_at_pos2, *mset->getByIndex(1)); - ASSERT_EQ(data_at_pos3, *mset->getByIndex(2)); - - // Removing another static mset->removeFirst("2"); - ASSERT_EQ(0, mset->getNumStaticItems()); - ASSERT_EQ(2, mset->getNumDynamicItems()); - ASSERT_LE(1, pool.getNumUsedBlocks()); // Adding some new items unsigned max_value_integer = 0; @@ -219,7 +201,7 @@ TEST(Multiset, PrimitiveKey) static const int POOL_BLOCKS = 3; uavcan::PoolAllocator pool; - typedef Multiset MultisetType; + typedef Multiset MultisetType; std::auto_ptr mset(new MultisetType(pool)); // Empty @@ -269,7 +251,7 @@ TEST(Multiset, NoncopyableWithCounter) static const int POOL_BLOCKS = 3; uavcan::PoolAllocator pool; - typedef Multiset MultisetType; + typedef Multiset MultisetType; std::auto_ptr mset(new MultisetType(pool)); ASSERT_EQ(0, NoncopyableWithCounter::num_objects);