mirror of
https://github.com/zeek/zeek.git
synced 2025-10-02 14:48:21 +00:00
Add ability for List to be ordered/unordered
This fixes a "bug" with List where remove_nth() can be an O(n) operation when it doesn't need to be. remove_nth for lists that don't necessarily need to keep an order can be an O(1) operation instead.
This commit is contained in:
parent
0558a7bfed
commit
28e5100842
2 changed files with 38 additions and 12 deletions
14
src/List.cc
14
src/List.cc
|
@ -114,3 +114,17 @@ TEST_CASE("plists")
|
|||
delete v;
|
||||
list.clear();
|
||||
}
|
||||
|
||||
TEST_CASE("unordered list operation")
|
||||
{
|
||||
List<int, LIST_UNORDERED> list({1, 2, 3, 4});
|
||||
CHECK(list.size() == 4);
|
||||
|
||||
// An unordered list doesn't maintain the ordering of the elements when
|
||||
// one is removed. It just swaps the last element into the hole.
|
||||
list.remove(2);
|
||||
CHECK(list.size() == 3);
|
||||
CHECK(list[0] == 1);
|
||||
CHECK(list[1] == 4);
|
||||
CHECK(list[2] == 3);
|
||||
}
|
||||
|
|
28
src/List.h
28
src/List.h
|
@ -29,7 +29,9 @@
|
|||
// TODO: this can be removed in v3.1 when List::sort() is removed
|
||||
typedef int (*list_cmp_func)(const void* v1, const void* v2);
|
||||
|
||||
template<typename T>
|
||||
enum list_order { LIST_ORDERED, LIST_UNORDERED };
|
||||
|
||||
template<typename T, list_order Order = LIST_ORDERED>
|
||||
class List {
|
||||
public:
|
||||
|
||||
|
@ -195,14 +197,12 @@ public:
|
|||
|
||||
bool remove(const T& a) // delete entry from list
|
||||
{
|
||||
for ( int i = 0; i < num_entries; ++i )
|
||||
int pos = member_pos(a);
|
||||
if ( pos != -1 )
|
||||
{
|
||||
if ( a == entries[i] )
|
||||
{
|
||||
remove_nth(i);
|
||||
remove_nth(pos);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -212,10 +212,22 @@ public:
|
|||
assert(n >=0 && n < num_entries);
|
||||
|
||||
T old_ent = entries[n];
|
||||
|
||||
// For data where we don't care about ordering, we don't care about keeping
|
||||
// the list in the same order when removing an element. Just swap the last
|
||||
// element with the element being removed.
|
||||
if ( Order == LIST_ORDERED )
|
||||
{
|
||||
--num_entries;
|
||||
|
||||
for ( ; n < num_entries; ++n )
|
||||
entries[n] = entries[n+1];
|
||||
}
|
||||
else
|
||||
{
|
||||
entries[n] = entries[num_entries - 1];
|
||||
--num_entries;
|
||||
}
|
||||
|
||||
return old_ent;
|
||||
}
|
||||
|
@ -332,8 +344,8 @@ protected:
|
|||
|
||||
|
||||
// Specialization of the List class to store pointers of a type.
|
||||
template<typename T>
|
||||
using PList = List<T*>;
|
||||
template<typename T, list_order Order = LIST_ORDERED>
|
||||
using PList = List<T*, Order>;
|
||||
|
||||
// Popular type of list: list of strings.
|
||||
typedef PList<char> name_list;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue