/*
* Copyright 2016-present Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License. You may obtain
* a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*/
package com.facebook.buck.event.listener;
import com.facebook.buck.rules.BuildRuleEvent;
import com.facebook.buck.test.TestRuleEvent;
import com.facebook.buck.util.environment.ExecutionEnvironment;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Preconditions;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
public class BuildRuleThreadTracker {
private final ConcurrentMap<Long, Optional<? extends BuildRuleEvent.BeginningBuildRuleEvent>>
threadsToRunningBuildRuleEvent;
private final ConcurrentMap<Long, Optional<? extends TestRuleEvent>>
threadsToRunningTestRuleEvent;
public BuildRuleThreadTracker(ExecutionEnvironment executionEnvironment) {
this.threadsToRunningBuildRuleEvent =
new ConcurrentHashMap<>(executionEnvironment.getAvailableCores());
this.threadsToRunningTestRuleEvent =
new ConcurrentHashMap<>(executionEnvironment.getAvailableCores());
}
@VisibleForTesting
BuildRuleThreadTracker(
Map<Long, Optional<? extends BuildRuleEvent.BeginningBuildRuleEvent>>
threadsToRunningBuildRuleEvent,
Map<Long, Optional<? extends TestRuleEvent>> threadsToRunningTestRuleEvent) {
this.threadsToRunningBuildRuleEvent = new ConcurrentHashMap<>();
this.threadsToRunningTestRuleEvent = new ConcurrentHashMap<>();
this.threadsToRunningBuildRuleEvent.putAll(threadsToRunningBuildRuleEvent);
this.threadsToRunningTestRuleEvent.putAll(threadsToRunningTestRuleEvent);
}
public ConcurrentMap<Long, Optional<? extends BuildRuleEvent.BeginningBuildRuleEvent>>
getBuildEventsByThread() {
return threadsToRunningBuildRuleEvent;
}
public ConcurrentMap<Long, Optional<? extends TestRuleEvent>> getTestEventsByThread() {
return threadsToRunningTestRuleEvent;
}
public void didStartBuildRule(BuildRuleEvent.Started started) {
handleBeginningEvent(started);
}
public void didResumeBuildRule(BuildRuleEvent.Resumed resumed) {
handleBeginningEvent(resumed);
}
public void didSuspendBuildRule(BuildRuleEvent.Suspended suspended) {
handleEndingEvent(suspended);
}
public void didFinishBuildRule(BuildRuleEvent.Finished finished) {
handleEndingEvent(finished);
}
public void didStartTestRule(TestRuleEvent.Started started) {
threadsToRunningTestRuleEvent.put(started.getThreadId(), Optional.of(started));
}
public void didFinishTestRule(TestRuleEvent.Finished finished) {
threadsToRunningTestRuleEvent.put(finished.getThreadId(), Optional.empty());
}
private void handleBeginningEvent(BuildRuleEvent.BeginningBuildRuleEvent beginning) {
threadsToRunningBuildRuleEvent.put(beginning.getThreadId(), Optional.of(beginning));
}
private void handleEndingEvent(BuildRuleEvent.EndingBuildRuleEvent ending) {
Optional<? extends BuildRuleEvent> beginning =
Preconditions.checkNotNull(
threadsToRunningBuildRuleEvent.put(ending.getThreadId(), Optional.empty()));
Preconditions.checkState(beginning.isPresent());
Preconditions.checkState(ending.getBuildRule().equals(beginning.get().getBuildRule()));
}
}