Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
G
googletest
Project
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Chen Yisong
googletest
Commits
1b61f16a
Commit
1b61f16a
authored
Jun 25, 2009
by
zhanyong.wan
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Makes list traversal O(N) instead of O(N^2) (by Zhanyong Wan).
parent
aaebfcdc
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
51 additions
and
12 deletions
+51
-12
gtest-internal-inl.h
src/gtest-internal-inl.h
+51
-12
No files found.
src/gtest-internal-inl.h
View file @
1b61f16a
...
...
@@ -257,7 +257,8 @@ class List {
public
:
// Creates an empty list.
List
()
:
head_
(
NULL
),
last_
(
NULL
),
size_
(
0
)
{}
List
()
:
head_
(
NULL
),
last_
(
NULL
),
size_
(
0
),
last_read_index_
(
-
1
),
last_read_
(
NULL
)
{}
// D'tor.
virtual
~
List
();
...
...
@@ -276,8 +277,9 @@ class List {
}
// 2. Resets the member variables.
head_
=
last_
=
NULL
;
last_read_
=
head_
=
last_
=
NULL
;
size_
=
0
;
last_read_index_
=
-
1
;
}
}
...
...
@@ -298,7 +300,8 @@ class List {
// Adds an element to the end of the list. A copy of the element is
// created using the copy constructor, and then stored in the list.
// Changes made to the element in the list doesn't affect the source
// object, and vice versa.
// object, and vice versa. This does not affect the "last read"
// index.
void
PushBack
(
const
E
&
element
)
{
ListNode
<
E
>
*
new_node
=
new
ListNode
<
E
>
(
element
);
...
...
@@ -312,7 +315,8 @@ class List {
}
}
// Adds an element to the beginning of this list.
// Adds an element to the beginning of this list. The "last read"
// index is adjusted accordingly.
void
PushFront
(
const
E
&
element
)
{
ListNode
<
E
>*
const
new_node
=
new
ListNode
<
E
>
(
element
);
...
...
@@ -324,12 +328,18 @@ class List {
head_
=
new_node
;
size_
++
;
}
if
(
last_read_index_
>=
0
)
{
// A new element at the head bumps up an existing index by 1.
last_read_index_
++
;
}
}
// Removes an element from the beginning of this list. If the
// result argument is not NULL, the removed element is stored in the
// memory it points to. Otherwise the element is thrown away.
// Returns true iff the list wasn't empty before the operation.
// Returns true iff the list wasn't empty before the operation. The
// "last read" index is adjusted accordingly.
bool
PopFront
(
E
*
result
)
{
if
(
size_
==
0
)
return
false
;
...
...
@@ -346,13 +356,21 @@ class List {
}
delete
old_head
;
if
(
last_read_index_
>
0
)
{
last_read_index_
--
;
}
else
if
(
last_read_index_
==
0
)
{
last_read_index_
=
-
1
;
last_read_
=
NULL
;
}
return
true
;
}
// Inserts an element after a given node in the list. It's the
// caller's responsibility to ensure that the given node is in the
// list. If the given node is NULL, inserts the element at the
// front of the list.
// front of the list. The "last read" index is adjusted
// accordingly.
ListNode
<
E
>*
InsertAfter
(
ListNode
<
E
>*
node
,
const
E
&
element
)
{
if
(
node
==
NULL
)
{
PushFront
(
element
);
...
...
@@ -367,6 +385,11 @@ class List {
last_
=
new_node
;
}
// We aren't sure whether this insertion will affect the last read
// index, so we invalidate it to be safe.
last_read_index_
=
-
1
;
last_read_
=
NULL
;
return
new_node
;
}
...
...
@@ -431,20 +454,27 @@ class List {
}
// Returns a pointer to the i-th element of the list, or NULL if i is not
// in range [0, size()).
// in range [0, size()).
The "last read" index is adjusted accordingly.
const
E
*
GetElement
(
int
i
)
const
{
if
(
i
<
0
||
i
>=
size
())
return
NULL
;
const
ListNode
<
E
>*
node
=
Head
();
for
(
int
index
=
0
;
index
<
i
&&
node
!=
NULL
;
++
index
,
node
=
node
->
next
())
continue
;
if
(
last_read_index_
<
0
||
last_read_index_
>
i
)
{
// We have to count from the start.
last_read_index_
=
0
;
last_read_
=
Head
();
}
return
node
?
&
(
node
->
element
())
:
NULL
;
while
(
last_read_index_
<
i
)
{
last_read_
=
last_read_
->
next
();
last_read_index_
++
;
}
return
&
(
last_read_
->
element
());
}
// Returns the i-th element of the list, or default_value if i is not
// in range [0, size()).
// in range [0, size()).
The "last read" index is adjusted accordingly.
E
GetElementOr
(
int
i
,
E
default_value
)
const
{
const
E
*
element
=
GetElement
(
i
);
return
element
?
*
element
:
default_value
;
...
...
@@ -455,6 +485,15 @@ class List {
ListNode
<
E
>*
last_
;
// The last node of the list.
int
size_
;
// The number of elements in the list.
// These fields point to the last element read via GetElement(i) or
// GetElementOr(i). They are used to speed up list traversal as
// often they allow us to find the wanted element by looking from
// the last visited one instead of the list head. This means a
// sequential traversal of the list can be done in O(N) time instead
// of O(N^2).
mutable
int
last_read_index_
;
mutable
const
ListNode
<
E
>*
last_read_
;
// We disallow copying List.
GTEST_DISALLOW_COPY_AND_ASSIGN_
(
List
);
};
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment