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;
|
delete v;
|
||||||
list.clear();
|
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
|
// TODO: this can be removed in v3.1 when List::sort() is removed
|
||||||
typedef int (*list_cmp_func)(const void* v1, const void* v2);
|
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 {
|
class List {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
@ -195,14 +197,12 @@ public:
|
||||||
|
|
||||||
bool remove(const T& a) // delete entry from list
|
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(pos);
|
||||||
{
|
|
||||||
remove_nth(i);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -212,10 +212,22 @@ public:
|
||||||
assert(n >=0 && n < num_entries);
|
assert(n >=0 && n < num_entries);
|
||||||
|
|
||||||
T old_ent = entries[n];
|
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;
|
--num_entries;
|
||||||
|
|
||||||
for ( ; n < num_entries; ++n )
|
for ( ; n < num_entries; ++n )
|
||||||
entries[n] = entries[n+1];
|
entries[n] = entries[n+1];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
entries[n] = entries[num_entries - 1];
|
||||||
|
--num_entries;
|
||||||
|
}
|
||||||
|
|
||||||
return old_ent;
|
return old_ent;
|
||||||
}
|
}
|
||||||
|
@ -332,8 +344,8 @@ protected:
|
||||||
|
|
||||||
|
|
||||||
// Specialization of the List class to store pointers of a type.
|
// Specialization of the List class to store pointers of a type.
|
||||||
template<typename T>
|
template<typename T, list_order Order = LIST_ORDERED>
|
||||||
using PList = List<T*>;
|
using PList = List<T*, Order>;
|
||||||
|
|
||||||
// Popular type of list: list of strings.
|
// Popular type of list: list of strings.
|
||||||
typedef PList<char> name_list;
|
typedef PList<char> name_list;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue