Skip to content

Commit

Permalink
Adds a new data structure for maintaining the registry of eevent ids:…
Browse files Browse the repository at this point in the history
… a sorted list-based map.

This structure shows bad insertion characteristics, but is a lot more memory efficient than a RB tree while using the same cost for lookups.

The insertion cost is offset a bit by lazy sorting.
  • Loading branch information
balazsracz committed Aug 31, 2015
1 parent c209cc5 commit c774724
Show file tree
Hide file tree
Showing 3 changed files with 153 additions and 2 deletions.
20 changes: 20 additions & 0 deletions event_handler_performance.txt
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ processing events with zero match in the registry:

AFTER FIRST ROUND OF OPTIMIZATION
=================================
(eliminate eventhandlercall)


processing events with 8 match in the registry: (0100)
Expand All @@ -54,6 +55,7 @@ processing events with zero match in the registry:

AFTER SECOND ROUND OF OPTIMIZATION
=================================
(add new version of barriernotify)

processing events with 8 match in the registry: (0100)
8-17 msec
Expand All @@ -66,6 +68,18 @@ processing events with zero match in the registry:



AFTER MEMORY OPTIMIZATION
=================================
(with new tree event handler implementation)

processing events with 8 match in the registry: (0100)
12-18 msec

processing events with one match in the registry:
7-16 msec for 100 events.

processing events with zero match in the registry:
2-10 msec for 100 events.



Expand All @@ -84,3 +98,9 @@ delta:
per consumer size: 144 bytes.


AFTER MEMORY OPTIMIZATION
0x612c (appl_main: 53a0 pool: 376)

adding four consumers:
0x622c (appl_main 54a0 pool: 376)
per consumer size: 64
5 changes: 3 additions & 2 deletions src/nmranet/EventHandlerContainer.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@

#include "utils/Atomic.hxx"
#include "utils/logging.h"
#include "utils/SortedListMap.hxx"
#include "nmranet/EventHandler.hxx"
#include "nmranet/EventHandlerTemplates.hxx"

Expand Down Expand Up @@ -133,7 +134,7 @@ class VectorEventHandlers : public EventRegistry {
HandlersList handlers_;
};

/// EventRegistry implementation that keeps event handlers in a red-black tree
/// EventRegistry implementation that keeps event handlers in a SortedListMap
/// and filters the event handler calls based on the registered event handler
/// arguments (id/mask).
class TreeEventHandlers : public EventRegistry, private Atomic {
Expand All @@ -148,7 +149,7 @@ private:
class Iterator;
friend class Iterator;

typedef std::multimap<uint64_t, EventHandler*> OneMaskMap;
typedef SortedListMap<uint64_t, EventHandler*> OneMaskMap;
typedef std::map<uint8_t, OneMaskMap> MaskLookupMap;
/** The registered handlers. The offset in the first map tell us how many
* bits wide the registration is (it is the mask value in the register
Expand Down
130 changes: 130 additions & 0 deletions src/utils/SortedListMap.hxx
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
/** \copyright
* Copyright (c) 2015, Balazs Racz
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* \file SortedListMap.hxx
* Template class for maintaining a mapping by using a sorted list.
*
* @author Balazs Racz
* @date 30 August 2015
*/

#ifndef _UTILS_SORTEDLISTMAP_HXX_
#define _UTILS_SORTEDLISTMAP_HXX_

#include <vector>
#include <algorithm>

template <class K, class V> class SortedListMap
{
public:
typedef K key_type;
typedef V value_type;
typedef std::pair<key_type, value_type> data_type;

private:
typedef std::vector<data_type> container_type;

public:
typedef typename container_type::iterator iterator;
typedef typename container_type::const_iterator const_iterator;

SortedListMap()
{
}

iterator begin()
{
lazy_init();
return container_.begin();
}

iterator end()
{
return container_.begin() + sortedCount_;
}

struct cmpop
{
bool operator()(const data_type &d, const key_type &k)
{
return d.first < k;
}
bool operator()(const key_type &k, const data_type &d)
{
return k < d.first;
}
};

iterator lower_bound(key_type key)
{
lazy_init();
return std::lower_bound(container_.begin(), container_.end(), key,
cmpop());
}

iterator upper_bound(key_type key)
{
lazy_init();
return std::upper_bound(container_.begin(), container_.end(), key,
cmpop());
}

pair<iterator, iterator> equal_range(key_type key)
{
lazy_init();
return std::equal_range(container_.begin(), container_.end(), key,
cmpop());
}

void insert(data_type &&d)
{
container_.push_back(d);
}

void erase(const iterator &it)
{
container_.erase(it);
}

private:
/// Reestablishes sorted order in case anything was inserted or removed.
void lazy_init()
{
if (sortedCount_ != container_.size())
{
sort(container_.begin(), container_.end());
sortedCount_ = container_.size();
}
}

/// Holds the actual data elements.
container_type container_;

/// The first this many elements in the container are already sorted.
size_t sortedCount_;
};

#endif // _UTILS_SORTEDLISTMAP_HXX_

0 comments on commit c774724

Please sign in to comment.