# HG changeset patch # User wenzelm # Date 1709992348 -3600 # Node ID 5969ead9f9007782683b923e3b5225d6bd2856e2 # Parent e38f5f81592dc6d2e7db083633e07bf7fe78402e clarified data representation: more uniform treatment of State.Pending vs. State.Running; diff -r e38f5f81592d -r 5969ead9f900 src/Pure/Build/build_process.scala --- a/src/Pure/Build/build_process.scala Sat Mar 09 13:06:13 2024 +0100 +++ b/src/Pure/Build/build_process.scala Sat Mar 09 14:52:28 2024 +0100 @@ -44,10 +44,10 @@ name: String, deps: List[String], build_uuid: String - ) { + ) extends Library.Named { def is_ready: Boolean = deps.isEmpty - def resolve(dep: String): Task = - if (deps.contains(dep)) copy(deps = deps.filterNot(_ == dep)) else this + def resolve(dep: String): Option[Task] = + if (deps.contains(dep)) Some(copy(deps = deps.filterNot(_ == dep))) else None } sealed case class Job( @@ -198,7 +198,7 @@ results: State.Results) // finished results object State { - type Pending = List[Task] + type Pending = Map[String, Task] type Running = Map[String, Job] type Results = Map[String, Result] } @@ -207,7 +207,7 @@ serial: Long = 0, numa_nodes: List[Int] = Nil, sessions: Sessions = Sessions.empty, - pending: State.Pending = Nil, + pending: State.Pending = Map.empty, running: State.Running = Map.empty, results: State.Results = Map.empty ) { @@ -217,12 +217,21 @@ copy(serial = serial + 1) } - def ready: State.Pending = pending.filter(_.is_ready) - def next_ready: State.Pending = ready.filter(entry => !is_running(entry.name)) + def ready: List[Task] = pending.valuesIterator.filter(_.is_ready).toList.sortBy(_.name) + def next_ready: List[Task] = ready.filter(entry => !is_running(entry.name)) - def remove_pending(name: String): State = - copy(pending = pending.flatMap( - entry => if (entry.name == name) None else Some(entry.resolve(name)))) + def remove_pending(a: String): State = + copy(pending = + pending.foldLeft(pending) { + case (map, (b, task)) => + if (a == b) map - a + else { + task.resolve(a) match { + case None => map + case Some(task1) => map + (b -> task1) + } + } + }) def is_running(name: String): Boolean = running.isDefinedAt(name) @@ -565,15 +574,15 @@ val table = make_table(List(name, deps, build_uuid), name = "pending") } - def read_pending(db: SQL.Database): List[Task] = + def read_pending(db: SQL.Database): State.Pending = db.execute_query_statement( - Pending.table.select(sql = SQL.order_by(List(Pending.name))), - List.from[Task], + Pending.table.select(), + Map.from[String, Task], { res => val name = res.string(Pending.name) val deps = res.string(Pending.deps) val build_uuid = res.string(Pending.build_uuid) - Task(name, split_lines(deps), build_uuid) + name -> Task(name, split_lines(deps), build_uuid) }) def update_pending( @@ -581,7 +590,9 @@ pending: State.Pending, old_pending: State.Pending ): Boolean = { - val (delete, insert) = Library.symmetric_difference(old_pending, pending) + val pending0 = old_pending.valuesIterator.toList + val pending1 = pending.valuesIterator.toList + val (delete, insert) = Library.symmetric_difference(pending0, pending1) if (delete.nonEmpty) { db.execute_statement( @@ -788,7 +799,7 @@ stamp_worker(db, worker_uuid, serial) val sessions = state.sessions.pull(read_sessions_domain(db), read_sessions(db, _)) - val pending = read_pending(db) + val pending = pull0(read_pending(db), state.pending) val running = pull0(read_running(db), state.running) val results = pull1(read_results_domain(db), read_results(db, _), state.results) @@ -966,14 +977,12 @@ protected def init_state(state: Build_Process.State): Build_Process.State = { val sessions1 = state.sessions.init(build_context, _database_server, progress = build_progress) - - val old_pending = state.pending.iterator.map(_.name).toSet - val new_pending = - List.from( - for (session <- sessions1.iterator if !old_pending(session.name)) - yield Build_Process.Task(session.name, session.deps, build_uuid)) - val pending1 = new_pending ::: state.pending - + val pending1 = + sessions1.iterator.foldLeft(state.pending) { + case (map, session) => + if (map.isDefinedAt(session.name)) map + else map + (session.name -> Build_Process.Task(session.name, session.deps, build_uuid)) + } state.copy(sessions = sessions1, pending = pending1) } diff -r e38f5f81592d -r 5969ead9f900 src/Pure/Build/build_schedule.scala --- a/src/Pure/Build/build_schedule.scala Sat Mar 09 13:06:13 2024 +0100 +++ b/src/Pure/Build/build_schedule.scala Sat Mar 09 14:52:28 2024 +0100 @@ -503,7 +503,6 @@ def update(state: Build_Process.State): Schedule = { val start1 = Date.now() - val pending = state.pending.map(_.name).toSet def shift_elapsed(graph: Schedule.Graph, name: String): Schedule.Graph = graph.map_node(name, { node => @@ -517,7 +516,8 @@ node.copy(start = starts.max(Date.Ordering)) }) - val graph0 = state.running.keys.foldLeft(graph.restrict(pending.contains))(shift_elapsed) + val graph0 = + state.running.keys.foldLeft(graph.restrict(state.pending.isDefinedAt))(shift_elapsed) val graph1 = graph0.topological_order.foldLeft(graph0)(shift_starts) copy(start = start1, graph = graph1) @@ -1333,7 +1333,8 @@ Build_Process.Task(session.name, session.deps, build_context.build_uuid) val build_state = - Build_Process.State(sessions = sessions, pending = sessions.iterator.map(task).toList) + Build_Process.State(sessions = sessions, + pending = sessions.iterator.map(session => (session.name -> task(session))).toMap) val scheduler = Build_Engine.scheduler(timing_data, build_context) def schedule_msg(res: Exn.Result[Schedule]): String =