diff --git a/Cargo.lock b/Cargo.lock index 065e1669a4b..ea1217e4826 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -452,6 +452,7 @@ dependencies = [ "gfx 0.0.1", "gfx_traits 0.0.1", "ipc-channel 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", + "itertools 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)", "layout_traits 0.0.1", "log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", "msg 0.0.1", @@ -688,6 +689,11 @@ dependencies = [ "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "either" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "embedding" version = "0.0.1" @@ -1289,6 +1295,14 @@ dependencies = [ "uuid 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "itertools" +version = "0.5.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "either 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "itoa" version = "0.3.1" @@ -3345,6 +3359,7 @@ dependencies = [ "checksum dtoa 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "80c8b71fd71146990a9742fc06dcbbde19161a267e0ad4e572c35162f4578c90" "checksum dwmapi-sys 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "07c4c7cc7b396419bc0a4d90371d0cee16cb5053b53647d287c0b728000c41fe" "checksum dwrote 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "74114b6b49d6731835da7a28a3642651451e315f7f9b9d04e907e65a45681796" +"checksum either 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "63f94a35a9ca0d4178e85f0250373f2cea55c5d603e6993778d68a99b3d8071c" "checksum encoding 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)" = "6b0d943856b990d12d3b55b359144ff341533e516d94098b1d3fc1ac666d36ec" "checksum encoding-index-japanese 1.20141219.5 (registry+https://github.com/rust-lang/crates.io-index)" = "04e8b2ff42e9a05335dbf8b5c6f7567e5591d0d916ccef4e0b1710d32a0d0c91" "checksum encoding-index-korean 1.20141219.5 (registry+https://github.com/rust-lang/crates.io-index)" = "4dc33fb8e6bcba213fe2f14275f0963fd16f0a02c878e3095ecfdf5bee529d81" @@ -3396,6 +3411,7 @@ dependencies = [ "checksum io-surface 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c35a3278fa52fb070fdc874dfd057163e6c21e0a9295f87f54daee9dd5530b43" "checksum iovec 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "29d062ee61fccdf25be172e70f34c9f6efc597e1fb8f6526e8437b2046ab26be" "checksum ipc-channel 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f1e8d7f511a1e2dae4e26efac30a85d2376b67d7c6f2c691ea95ebd850b017da" +"checksum itertools 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4833d6978da405305126af4ac88569b5d71ff758581ce5a987dbfa3755f694fc" "checksum itoa 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "eb2f404fbc66fd9aac13e998248505e7ecb2ad8e44ab6388684c5fb11c6c251c" "checksum jpeg-decoder 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "5c4ff3d14e7ef3522471ab712832c3dd50001f7fb7aa4cdc48af811d63b531e9" "checksum js 0.1.4 (git+https://github.com/servo/rust-mozjs)" = "" diff --git a/components/constellation/Cargo.toml b/components/constellation/Cargo.toml index de1e5df08f1..564fbf61815 100644 --- a/components/constellation/Cargo.toml +++ b/components/constellation/Cargo.toml @@ -21,6 +21,7 @@ euclid = "0.11" gfx = {path = "../gfx"} gfx_traits = {path = "../gfx_traits"} ipc-channel = "0.7" +itertools = "0.5" layout_traits = {path = "../layout_traits"} log = "0.3.5" msg = {path = "../msg"} diff --git a/components/constellation/constellation.rs b/components/constellation/constellation.rs index 30f36cbaa02..2fbcd6feefb 100644 --- a/components/constellation/constellation.rs +++ b/components/constellation/constellation.rs @@ -81,6 +81,7 @@ use gfx_traits::Epoch; use ipc_channel::{Error as IpcError}; use ipc_channel::ipc::{self, IpcSender, IpcReceiver}; use ipc_channel::router::ROUTER; +use itertools::Itertools; use layout_traits::LayoutThreadFactory; use log::{Log, LogLevel, LogLevelFilter, LogMetadata, LogRecord}; use msg::constellation_msg::{FrameId, FrameType, PipelineId}; @@ -109,6 +110,7 @@ use servo_rand::{Rng, SeedableRng, ServoRng, random}; use servo_remutex::ReentrantMutex; use servo_url::{Host, ImmutableOrigin, ServoUrl}; use std::borrow::ToOwned; +use std::cmp::Ordering; use std::collections::{HashMap, VecDeque}; use std::iter::once; use std::marker::PhantomData; @@ -117,7 +119,6 @@ use std::rc::{Rc, Weak}; use std::sync::Arc; use std::sync::mpsc::{Receiver, Sender, channel}; use std::thread; -use std::time::Instant; use style_traits::CSSPixel; use style_traits::cursor::Cursor; use style_traits::viewport::ViewportConstraints; @@ -703,15 +704,10 @@ impl Constellation /// The joint session future is the merge of the session future of every /// frame in the frame tree, sorted chronologically. - fn joint_session_future<'a>(&'a self, frame_id_root: FrameId) -> impl Iterator { - let mut future: Vec = self.full_frame_tree_iter(frame_id_root) - .flat_map(|frame| frame.next.iter().cloned()) - .collect(); - - // Sort the joint session future by the timestamp that the pipeline was navigated to - // in chronological order - future.sort_by(|a, b| a.instant.cmp(&b.instant)); - future.into_iter() + fn joint_session_future<'a>(&'a self, frame_id_root: FrameId) -> impl Iterator + 'a { + self.full_frame_tree_iter(frame_id_root) + .map(|frame| frame.next.iter().rev()) + .kmerge_by(|a, b| a.instant.cmp(&b.instant) == Ordering::Less) } /// Is the joint session future empty? @@ -722,19 +718,15 @@ impl Constellation /// The joint session past is the merge of the session past of every /// frame in the frame tree, sorted reverse chronologically. - fn joint_session_past<'a>(&self, frame_id_root: FrameId) -> impl Iterator { - let mut past: Vec<(Instant, FrameState)> = self.full_frame_tree_iter(frame_id_root) - .flat_map(|frame| frame.prev.iter().rev().scan(frame.instant, |prev_instant, entry| { + fn joint_session_past<'a>(&'a self, frame_id_root: FrameId) -> impl Iterator + 'a { + self.full_frame_tree_iter(frame_id_root) + .map(|frame| frame.prev.iter().rev().scan(frame.instant, |prev_instant, entry| { let instant = *prev_instant; *prev_instant = entry.instant; - Some((instant, entry.clone())) + Some((instant, entry)) })) - .collect(); - - // Sort the joint session past by the timestamp that the pipeline was navigated from - // in reverse chronological order - past.sort_by(|a, b| b.0.cmp(&a.0)); - past.into_iter().map(|(_, entry)| entry) + .kmerge_by(|a, b| a.0.cmp(&b.0) == Ordering::Greater) + .map(|(_, entry)| entry) } /// Is the joint session past empty? @@ -1714,7 +1706,7 @@ impl Constellation TraversalDirection::Forward(delta) => { for entry in self.joint_session_future(top_level_frame_id).take(delta) { size = size + 1; - table.insert(entry.frame_id, entry); + table.insert(entry.frame_id, entry.clone()); } if size < delta { return debug!("Traversing forward too much."); @@ -1723,7 +1715,7 @@ impl Constellation TraversalDirection::Back(delta) => { for entry in self.joint_session_past(top_level_frame_id).take(delta) { size = size + 1; - table.insert(entry.frame_id, entry); + table.insert(entry.frame_id, entry.clone()); } if size < delta { return debug!("Traversing back too much."); diff --git a/components/constellation/lib.rs b/components/constellation/lib.rs index 5a9a616bbdf..536775de0ef 100644 --- a/components/constellation/lib.rs +++ b/components/constellation/lib.rs @@ -20,6 +20,7 @@ extern crate gaol; extern crate gfx; extern crate gfx_traits; extern crate ipc_channel; +extern crate itertools; extern crate layout_traits; #[macro_use] extern crate log;