Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(22)

Unified Diff: Source/core/html/track/TextTrackCueList.cpp

Issue 955443002: Replace open-coded binary search in TextTrackCueList::add with upper_bound (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « Source/core/html/track/TextTrackCueList.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: Source/core/html/track/TextTrackCueList.cpp
diff --git a/Source/core/html/track/TextTrackCueList.cpp b/Source/core/html/track/TextTrackCueList.cpp
index bb23faffddc60b7993baed665ab706571e53484d..a442ddad66f692506aa13b3fb9e4be18918a84d8 100644
--- a/Source/core/html/track/TextTrackCueList.cpp
+++ b/Source/core/html/track/TextTrackCueList.cpp
@@ -24,9 +24,10 @@
*/
#include "config.h"
-
#include "core/html/track/TextTrackCueList.h"
+#include "wtf/StdLibExtras.h"
+
namespace blink {
TextTrackCueList::TextTrackCueList()
@@ -80,31 +81,33 @@ bool TextTrackCueList::add(PassRefPtrWillBeRawPtr<TextTrackCue> cue)
ASSERT(cue->startTime() >= 0);
ASSERT(cue->endTime() >= 0);
- return add(cue, 0, m_list.size());
-}
-
-bool TextTrackCueList::add(PassRefPtrWillBeRawPtr<TextTrackCue> prpCue, size_t start, size_t end)
-{
- ASSERT_WITH_SECURITY_IMPLICATION(start <= m_list.size());
- ASSERT_WITH_SECURITY_IMPLICATION(end <= m_list.size());
-
// Maintain text track cue order:
// http://www.whatwg.org/specs/web-apps/current-work/#text-track-cue-order
philipj_slow 2015/02/25 02:28:40 https://html.spec.whatwg.org/#text-track-cue-order
fs 2015/02/25 16:39:49 Done.
- RefPtrWillBeRawPtr<TextTrackCue> cue = prpCue;
- if (start == end) {
- if (!m_list.isEmpty() && (start > 0) && (m_list[start - 1].get() == cue.get()))
- return false;
+ size_t index = findInsertionIndex(cue.get());
+
+ // FIXME: The cue should not exist in the list in the first place.
+ if (!m_list.isEmpty() && (index > 0) && (m_list[index - 1].get() == cue.get()))
+ return false;
+
+ m_list.insert(index, cue);
+ invalidateCueIndexes(index);
+ return true;
+}
- m_list.insert(start, cue);
- invalidateCueIndexes(start);
+static bool cueIsBefore(const TextTrackCue* cue, PassRefPtrWillBeRawPtr<TextTrackCue> otherCue)
+{
+ if (cue->startTime() < otherCue->startTime())
return true;
- }
- size_t index = (start + end) / 2;
- if (cue->startTime() < m_list[index]->startTime() || (cue->startTime() == m_list[index]->startTime() && cue->endTime() > m_list[index]->endTime()))
- return add(cue.release(), start, index);
+ return cue->startTime() == otherCue->startTime() && cue->endTime() > otherCue->endTime();
+}
- return add(cue.release(), index + 1, end);
+size_t TextTrackCueList::findInsertionIndex(const TextTrackCue* cueToInsert) const
+{
+ auto it = std::upper_bound(m_list.begin(), m_list.end(), cueToInsert, cueIsBefore);
+ size_t index = safeCast<size_t>(it - m_list.begin());
+ ASSERT_WITH_SECURITY_IMPLICATION(index <= m_list.size());
+ return index;
}
bool TextTrackCueList::remove(TextTrackCue* cue)
@@ -119,16 +122,27 @@ bool TextTrackCueList::remove(TextTrackCue* cue)
bool TextTrackCueList::updateCueIndex(TextTrackCue* cue)
philipj_slow 2015/02/25 02:28:40 Here or in another CL the return value can be drop
fs 2015/02/25 13:09:49 Yes, it's a bit strange both that it wasn't used..
philipj_slow 2015/02/25 15:38:54 Thanks, I think that may make things a bit clearer
fs 2015/02/25 16:39:49 Return-value dropped. "Avoiding" O(n) here can onl
philipj_slow 2015/02/26 01:54:34 OK, looks like I'm still confused. Specifically, w
fs 2015/02/26 09:37:57 It's more because I want to be able to use oldInde
fs 2015/02/26 09:43:36 Uploaded as PS3.
{
- size_t index = m_list.find(cue);
- if (index == kNotFound)
+ size_t oldIndex = m_list.find(cue);
+ if (oldIndex == kNotFound)
return false;
cue->setIsActive(false);
cue->removeDisplayTree();
- m_list.remove(index);
-
- return add(cue);
+ m_list.remove(oldIndex);
+ size_t newIndex = findInsertionIndex(cue);
+ m_list.insert(newIndex, cue);
+
+ bool indexChanged = newIndex != oldIndex;
philipj_slow 2015/02/25 02:28:40 I'm not sure what the benefit of this over add(cue
fs 2015/02/25 13:09:49 The main reason would be the comment below - i.e.
+ if (indexChanged) {
+ // FIXME: If moving from oldIndex to newIndex and newIndex > oldIndex,
philipj_slow 2015/02/25 02:28:40 TextTrackCueList::remove has the same problem, rig
fs 2015/02/25 13:09:49 In a sense, yes. Theoretically remove() does not i
philipj_slow 2015/02/25 15:38:54 Throw a FIXME in remove as well to make this class
fs 2015/02/25 16:39:49 Done.
+ // then what happens with the cached index on cues in the range
+ // [oldIndex, newIndex)? (Some of the indices will be "safe", but
+ // there'll be a risk that the lazy update via cueIndex() yields
+ // duplicates/incorrect order.)
+ invalidateCueIndexes(newIndex);
+ }
+ return indexChanged;
}
void TextTrackCueList::clear()
@@ -138,6 +152,7 @@ void TextTrackCueList::clear()
void TextTrackCueList::invalidateCueIndexes(size_t start)
{
+ // FIXME: When iterating cues we could as well update their cached indices too.
philipj_slow 2015/02/25 02:28:40 Heh, yeah :)
for (size_t i = start; i < m_list.size(); ++i)
m_list[i]->invalidateCueIndex();
}
« no previous file with comments | « Source/core/html/track/TextTrackCueList.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698