Repository: reef Updated Branches: refs/heads/master f5fd01fc7 -> 3818bf454
[REEF-1168] Support TaskStart and TaskStop JIRA: [REEF-1168](https://issues.apache.org/jira/browse/REEF-1168) This closes #841 Project: http://git-wip-us.apache.org/repos/asf/reef/repo Commit: http://git-wip-us.apache.org/repos/asf/reef/commit/3818bf45 Tree: http://git-wip-us.apache.org/repos/asf/reef/tree/3818bf45 Diff: http://git-wip-us.apache.org/repos/asf/reef/diff/3818bf45 Branch: refs/heads/master Commit: 3818bf454ab1f9eb8b35bbcb2457d7726bc5f540 Parents: f5fd01f Author: Andrew Chung <[email protected]> Authored: Fri Feb 12 10:49:39 2016 -0800 Committer: Julia Wang <[email protected]> Committed: Wed Feb 17 12:54:44 2016 -0800 ---------------------------------------------------------------------- .../Runtime/Evaluator/Task/TaskLifeCycle.cs | 73 ++++++--- .../Runtime/Evaluator/Task/TaskStartImpl.cs | 6 +- .../Runtime/Evaluator/Task/TaskStatus.cs | 6 +- .../Runtime/Evaluator/Task/TaskStopImpl.cs | 6 +- .../Tasks/Events/ITaskStart.cs | 4 + .../Tasks/Events/ITaskStop.cs | 4 + .../TaskRuntimeTests.cs | 159 ++++++++++++++++++- .../Collections/ReadOnlySet.cs | 137 ++++++++++++++++ .../Org.Apache.Reef.Utilities.csproj | 1 + 9 files changed, 363 insertions(+), 33 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/reef/blob/3818bf45/lang/cs/Org.Apache.REEF.Common/Runtime/Evaluator/Task/TaskLifeCycle.cs ---------------------------------------------------------------------- diff --git a/lang/cs/Org.Apache.REEF.Common/Runtime/Evaluator/Task/TaskLifeCycle.cs b/lang/cs/Org.Apache.REEF.Common/Runtime/Evaluator/Task/TaskLifeCycle.cs index bdff836..369fbf0 100644 --- a/lang/cs/Org.Apache.REEF.Common/Runtime/Evaluator/Task/TaskLifeCycle.cs +++ b/lang/cs/Org.Apache.REEF.Common/Runtime/Evaluator/Task/TaskLifeCycle.cs @@ -17,49 +17,78 @@ using System; using System.Collections.Generic; +using Org.Apache.REEF.Common.Tasks; using Org.Apache.REEF.Common.Tasks.Events; +using Org.Apache.REEF.Tang.Annotations; +using Org.Apache.REEF.Utilities; +using Org.Apache.REEF.Utilities.Collections; namespace Org.Apache.REEF.Common.Runtime.Evaluator.Task { internal sealed class TaskLifeCycle { - private readonly HashSet<IObserver<ITaskStop>> _taskStopHandlers; - private readonly HashSet<IObserver<ITaskStart>> _taskStartHandlers; - private readonly ITaskStart _taskStart; - private readonly ITaskStop _taskStop; + private readonly IReadOnlyCollection<IObserver<ITaskStop>> _taskStopHandlers; + private readonly IReadOnlyCollection<IObserver<ITaskStart>> _taskStartHandlers; + private readonly Optional<ITaskStart> _taskStart; + private readonly Optional<ITaskStop> _taskStop; - // INJECT - public TaskLifeCycle( - HashSet<IObserver<ITaskStop>> taskStopHandlers, - HashSet<IObserver<ITaskStart>> taskStartHandlers, - TaskStartImpl taskStart, - TaskStopImpl taskStop) + /// <summary> + /// TODO[JIRA REEF-1167]: Remove constructor. + /// </summary> + [Obsolete("Deprecated in 0.14. Will be removed.")] + [Inject] + private TaskLifeCycle( + [Parameter(typeof(TaskConfigurationOptions.StartHandlers))] ISet<IObserver<ITaskStart>> taskStartHandlers, + [Parameter(typeof(TaskConfigurationOptions.StopHandlers))] ISet<IObserver<ITaskStop>> taskStopHandlers) + : this(taskStartHandlers, taskStopHandlers, Optional<ITaskStart>.Empty(), Optional<ITaskStop>.Empty()) { - _taskStartHandlers = taskStartHandlers; - _taskStopHandlers = taskStopHandlers; - _taskStart = taskStart; - _taskStop = taskStop; } - public TaskLifeCycle() + [Inject] + private TaskLifeCycle( + [Parameter(typeof(TaskConfigurationOptions.StartHandlers))] ISet<IObserver<ITaskStart>> taskStartHandlers, + [Parameter(typeof(TaskConfigurationOptions.StopHandlers))] ISet<IObserver<ITaskStop>> taskStopHandlers, + ITaskStart taskStart, + ITaskStop taskStop) + : this(taskStartHandlers, taskStopHandlers, Optional<ITaskStart>.Of(taskStart), Optional<ITaskStop>.Of(taskStop)) { - _taskStartHandlers = new HashSet<IObserver<ITaskStart>>(); - _taskStopHandlers = new HashSet<IObserver<ITaskStop>>(); } - + + private TaskLifeCycle( + IEnumerable<IObserver<ITaskStart>> taskStartHandlers, + IEnumerable<IObserver<ITaskStop>> taskStopHandlers, + Optional<ITaskStart> taskStart, + Optional<ITaskStop> taskStop) + { + _taskStartHandlers = new ReadOnlySet<IObserver<ITaskStart>>(taskStartHandlers); + _taskStopHandlers = new ReadOnlySet<IObserver<ITaskStop>>(taskStopHandlers); + _taskStart = taskStart; + _taskStop = taskStop; + } + public void Start() { - foreach (IObserver<ITaskStart> startHandler in _taskStartHandlers) + if (!_taskStart.IsPresent()) + { + return; + } + + foreach (var startHandler in _taskStartHandlers) { - startHandler.OnNext(_taskStart); + startHandler.OnNext(_taskStart.Value); } } public void Stop() { - foreach (IObserver<ITaskStop> stopHandler in _taskStopHandlers) + if (!_taskStop.IsPresent()) + { + return; + } + + foreach (var stopHandler in _taskStopHandlers) { - stopHandler.OnNext(_taskStop); + stopHandler.OnNext(_taskStop.Value); } } } http://git-wip-us.apache.org/repos/asf/reef/blob/3818bf45/lang/cs/Org.Apache.REEF.Common/Runtime/Evaluator/Task/TaskStartImpl.cs ---------------------------------------------------------------------- diff --git a/lang/cs/Org.Apache.REEF.Common/Runtime/Evaluator/Task/TaskStartImpl.cs b/lang/cs/Org.Apache.REEF.Common/Runtime/Evaluator/Task/TaskStartImpl.cs index 0571719..f35ab82 100644 --- a/lang/cs/Org.Apache.REEF.Common/Runtime/Evaluator/Task/TaskStartImpl.cs +++ b/lang/cs/Org.Apache.REEF.Common/Runtime/Evaluator/Task/TaskStartImpl.cs @@ -15,14 +15,16 @@ // specific language governing permissions and limitations // under the License. +using Org.Apache.REEF.Common.Tasks; using Org.Apache.REEF.Common.Tasks.Events; +using Org.Apache.REEF.Tang.Annotations; namespace Org.Apache.REEF.Common.Runtime.Evaluator.Task { internal sealed class TaskStartImpl : ITaskStart { - // INJECT - public TaskStartImpl(string id) + [Inject] + private TaskStartImpl([Parameter(typeof(TaskConfigurationOptions.Identifier))] string id) { Id = id; } http://git-wip-us.apache.org/repos/asf/reef/blob/3818bf45/lang/cs/Org.Apache.REEF.Common/Runtime/Evaluator/Task/TaskStatus.cs ---------------------------------------------------------------------- diff --git a/lang/cs/Org.Apache.REEF.Common/Runtime/Evaluator/Task/TaskStatus.cs b/lang/cs/Org.Apache.REEF.Common/Runtime/Evaluator/Task/TaskStatus.cs index 31ce771..ab10c63 100644 --- a/lang/cs/Org.Apache.REEF.Common/Runtime/Evaluator/Task/TaskStatus.cs +++ b/lang/cs/Org.Apache.REEF.Common/Runtime/Evaluator/Task/TaskStatus.cs @@ -22,6 +22,7 @@ using Org.Apache.REEF.Common.Context; using Org.Apache.REEF.Common.Protobuf.ReefProtocol; using Org.Apache.REEF.Common.Tasks; using Org.Apache.REEF.Tang.Annotations; +using Org.Apache.REEF.Tang.Implementations.Tang; using Org.Apache.REEF.Utilities; using Org.Apache.REEF.Utilities.Logging; @@ -47,10 +48,11 @@ namespace Org.Apache.REEF.Common.Runtime.Evaluator.Task [Parameter(typeof(ContextConfigurationOptions.ContextIdentifier))] string contextId, [Parameter(typeof(TaskConfigurationOptions.Identifier))] string taskId, [Parameter(typeof(TaskConfigurationOptions.TaskMessageSources))] ISet<ITaskMessageSource> taskMessageSources, + TaskLifeCycle taskLifeCycle, IHeartBeatManager heartBeatManager) { _heartBeatManager = heartBeatManager; - _taskLifeCycle = new TaskLifeCycle(); + _taskLifeCycle = taskLifeCycle; _evaluatorMessageSources = Optional<ISet<ITaskMessageSource>>.OfNullable(taskMessageSources); State = TaskState.Init; _taskId = taskId; @@ -64,7 +66,7 @@ namespace Org.Apache.REEF.Common.Runtime.Evaluator.Task public TaskStatus(IHeartBeatManager heartBeatManager, string contextId, string taskId, Optional<ISet<ITaskMessageSource>> evaluatorMessageSources) { _heartBeatManager = heartBeatManager; - _taskLifeCycle = new TaskLifeCycle(); + _taskLifeCycle = TangFactory.GetTang().NewInjector().GetInstance<TaskLifeCycle>(); _evaluatorMessageSources = evaluatorMessageSources; State = TaskState.Init; _taskId = taskId; http://git-wip-us.apache.org/repos/asf/reef/blob/3818bf45/lang/cs/Org.Apache.REEF.Common/Runtime/Evaluator/Task/TaskStopImpl.cs ---------------------------------------------------------------------- diff --git a/lang/cs/Org.Apache.REEF.Common/Runtime/Evaluator/Task/TaskStopImpl.cs b/lang/cs/Org.Apache.REEF.Common/Runtime/Evaluator/Task/TaskStopImpl.cs index b2830e5..07739b9 100644 --- a/lang/cs/Org.Apache.REEF.Common/Runtime/Evaluator/Task/TaskStopImpl.cs +++ b/lang/cs/Org.Apache.REEF.Common/Runtime/Evaluator/Task/TaskStopImpl.cs @@ -15,14 +15,16 @@ // specific language governing permissions and limitations // under the License. +using Org.Apache.REEF.Common.Tasks; using Org.Apache.REEF.Common.Tasks.Events; +using Org.Apache.REEF.Tang.Annotations; namespace Org.Apache.REEF.Common.Runtime.Evaluator.Task { internal sealed class TaskStopImpl : ITaskStop { - // INJECT - public TaskStopImpl(string id) + [Inject] + private TaskStopImpl([Parameter(typeof(TaskConfigurationOptions.Identifier))] string id) { Id = id; } http://git-wip-us.apache.org/repos/asf/reef/blob/3818bf45/lang/cs/Org.Apache.REEF.Common/Tasks/Events/ITaskStart.cs ---------------------------------------------------------------------- diff --git a/lang/cs/Org.Apache.REEF.Common/Tasks/Events/ITaskStart.cs b/lang/cs/Org.Apache.REEF.Common/Tasks/Events/ITaskStart.cs index 7cf5b75..24b495b 100644 --- a/lang/cs/Org.Apache.REEF.Common/Tasks/Events/ITaskStart.cs +++ b/lang/cs/Org.Apache.REEF.Common/Tasks/Events/ITaskStart.cs @@ -15,8 +15,12 @@ // specific language governing permissions and limitations // under the License. +using Org.Apache.REEF.Common.Runtime.Evaluator.Task; +using Org.Apache.REEF.Tang.Annotations; + namespace Org.Apache.REEF.Common.Tasks.Events { + [DefaultImplementation(typeof(TaskStartImpl))] public interface ITaskStart { string Id { get; set; } http://git-wip-us.apache.org/repos/asf/reef/blob/3818bf45/lang/cs/Org.Apache.REEF.Common/Tasks/Events/ITaskStop.cs ---------------------------------------------------------------------- diff --git a/lang/cs/Org.Apache.REEF.Common/Tasks/Events/ITaskStop.cs b/lang/cs/Org.Apache.REEF.Common/Tasks/Events/ITaskStop.cs index 24fa016..4d4850f 100644 --- a/lang/cs/Org.Apache.REEF.Common/Tasks/Events/ITaskStop.cs +++ b/lang/cs/Org.Apache.REEF.Common/Tasks/Events/ITaskStop.cs @@ -15,8 +15,12 @@ // specific language governing permissions and limitations // under the License. +using Org.Apache.REEF.Common.Runtime.Evaluator.Task; +using Org.Apache.REEF.Tang.Annotations; + namespace Org.Apache.REEF.Common.Tasks.Events { + [DefaultImplementation(typeof(TaskStopImpl))] public interface ITaskStop { string Id { get; } http://git-wip-us.apache.org/repos/asf/reef/blob/3818bf45/lang/cs/Org.Apache.REEF.Evaluator.Tests/TaskRuntimeTests.cs ---------------------------------------------------------------------- diff --git a/lang/cs/Org.Apache.REEF.Evaluator.Tests/TaskRuntimeTests.cs b/lang/cs/Org.Apache.REEF.Evaluator.Tests/TaskRuntimeTests.cs index 44d691f..0435357 100644 --- a/lang/cs/Org.Apache.REEF.Evaluator.Tests/TaskRuntimeTests.cs +++ b/lang/cs/Org.Apache.REEF.Evaluator.Tests/TaskRuntimeTests.cs @@ -16,6 +16,8 @@ // under the License. using System; +using System.Collections.Generic; +using System.Linq; using System.Threading; using NSubstitute; using Org.Apache.REEF.Common.Context; @@ -23,16 +25,24 @@ using Org.Apache.REEF.Common.Protobuf.ReefProtocol; using Org.Apache.REEF.Common.Runtime.Evaluator; using Org.Apache.REEF.Common.Runtime.Evaluator.Task; using Org.Apache.REEF.Common.Tasks; +using Org.Apache.REEF.Common.Tasks.Events; using Org.Apache.REEF.Tang.Annotations; using Org.Apache.REEF.Tang.Implementations.Tang; using Org.Apache.REEF.Tang.Interface; using Org.Apache.REEF.Tang.Util; +using Org.Apache.REEF.Utilities; using Xunit; namespace Org.Apache.REEF.Evaluator.Tests { + /// <summary> + /// Tests for TaskRuntime and Task events. + /// </summary> public sealed class TaskRuntimeTests { + /// <summary> + /// Tests that Task ID and Context ID are properly passed to TaskRuntime. + /// </summary> [Fact] public void TestTaskRuntimeFields() { @@ -44,6 +54,9 @@ namespace Org.Apache.REEF.Evaluator.Tests Assert.Equal(taskRuntime.ContextId, contextId); } + /// <summary> + /// Tests that TaskRuntime has proper state at initialization. + /// </summary> [Fact] public void TestTaskRuntimeInitialization() { @@ -53,6 +66,10 @@ namespace Org.Apache.REEF.Evaluator.Tests Assert.False(taskRuntime.HasEnded()); } + /// <summary> + /// Tests a simple Task on TaskRuntime and tests that the Task is + /// properly disposed. + /// </summary> [Fact] public void TestTaskRuntimeRunsAndDisposesTask() { @@ -66,6 +83,9 @@ namespace Org.Apache.REEF.Evaluator.Tests Assert.True(taskRuntime.HasEnded()); } + /// <summary> + /// Tests the correctness of TaskRuntime state on Task failure. + /// </summary> [Fact] public void TestTaskRuntimeFailure() { @@ -78,6 +98,10 @@ namespace Org.Apache.REEF.Evaluator.Tests Assert.True(taskRuntime.HasEnded()); } + /// <summary> + /// Tests the correctness of TaskRuntime state throughout the lifecycle + /// of a Task. Also tests that the Task runs properly. + /// </summary> [Fact] public void TestTaskLifeCycle() { @@ -107,6 +131,89 @@ namespace Org.Apache.REEF.Evaluator.Tests Assert.Equal(taskRuntime.GetTaskState(), TaskState.Done); } + /// <summary> + /// Tests whether task start and stop handlers are properly instantiated and invoked + /// in the happy path. + /// </summary> + [Fact] + public void TestTaskEvents() + { + var contextId = Guid.NewGuid().ToString(); + var taskId = Guid.NewGuid().ToString(); + + var injector = GetInjector(typeof(CountDownAction), contextId, taskId); + var taskRuntime = injector.GetInstance<TaskRuntime>(); + var startHandlers = injector.GetNamedInstance<TaskConfigurationOptions.StartHandlers, ISet<IObserver<ITaskStart>>>(); + + Assert.Equal(startHandlers.Count, 1); + + var testTaskEventStartHandler = startHandlers.Single() as TestTaskEventHandler; + Assert.NotNull(testTaskEventStartHandler); + if (testTaskEventStartHandler == null) + { + throw new Exception("Event handler is not expected to be null."); + } + + taskRuntime.RunTask(); + + Assert.True(testTaskEventStartHandler.StartInvoked.IsPresent()); + Assert.Equal(testTaskEventStartHandler.StartInvoked.Value, taskId); + Assert.False(testTaskEventStartHandler.StopInvoked.IsPresent()); + + var countDownAction = injector.GetInstance<CountDownAction>(); + countDownAction.CountdownEvent.Signal(); + + var task = injector.GetInstance<TestTask>(); + task.FinishCountdownEvent.Wait(); + task.DisposeCountdownEvent.Wait(); + + var stopHandlers = injector.GetNamedInstance<TaskConfigurationOptions.StopHandlers, ISet<IObserver<ITaskStop>>>(); + + Assert.Equal(stopHandlers.Count, 1); + + var testTaskEventStopHandler = stopHandlers.Single() as TestTaskEventHandler; + Assert.NotNull(testTaskEventStopHandler); + if (testTaskEventStopHandler == null) + { + throw new Exception("Event handler is not expected to be null."); + } + + Assert.True(ReferenceEquals(testTaskEventStartHandler, testTaskEventStopHandler)); + Assert.True(testTaskEventStopHandler.StopInvoked.IsPresent()); + Assert.Equal(testTaskEventStopHandler.StopInvoked.Value, taskId); + } + + /// <summary> + /// Tests whether task start and stop handlers are properly instantiated and invoked + /// on the failure of a task. + /// </summary> + [Fact] + public void TestTaskEventsOnFailure() + { + var contextId = Guid.NewGuid().ToString(); + var taskId = Guid.NewGuid().ToString(); + + var injector = GetInjector(typeof(ExceptionAction), contextId, taskId); + var taskRuntime = injector.GetInstance<TaskRuntime>(); + + taskRuntime.RunTask(); + + var task = injector.GetInstance<TestTask>(); + task.FinishCountdownEvent.Wait(); + task.DisposeCountdownEvent.Wait(); + + var stopHandlers = injector.GetNamedInstance<TaskConfigurationOptions.StopHandlers, ISet<IObserver<ITaskStop>>>(); + var testTaskEventStopHandler = stopHandlers.Single() as TestTaskEventHandler; + Assert.NotNull(testTaskEventStopHandler); + if (testTaskEventStopHandler == null) + { + throw new Exception("Event handler is not expected to be null."); + } + + Assert.True(testTaskEventStopHandler.StopInvoked.IsPresent()); + Assert.Equal(testTaskEventStopHandler.StopInvoked.Value, taskId); + } + private static IInjector GetInjector(string contextId = "contextId", string taskId = "taskId") { return GetInjector(typeof(DefaultAction), contextId, taskId); @@ -117,19 +224,61 @@ namespace Org.Apache.REEF.Evaluator.Tests var confBuilder = TangFactory.GetTang().NewConfigurationBuilder(); var heartbeatManager = Substitute.For<IHeartBeatManager>(); - var evaluatorConfig = confBuilder - .BindNamedParameter(typeof(ContextConfigurationOptions.ContextIdentifier), contextId) - .BindNamedParameter(typeof(TaskConfigurationOptions.Identifier), taskId) - .BindImplementation(typeof(ITask), typeof(TestTask)) + var contextConfig = ContextConfiguration.ConfigurationModule + .Set(ContextConfiguration.Identifier, contextId) + .Build(); + + var taskConfig = TaskConfiguration.ConfigurationModule + .Set(TaskConfiguration.Identifier, taskId) + .Set(TaskConfiguration.OnTaskStart, GenericType<TestTaskEventHandler>.Class) + .Set(TaskConfiguration.OnTaskStop, GenericType<TestTaskEventHandler>.Class) + .Set(TaskConfiguration.Task, GenericType<TestTask>.Class) + .Build(); + + var actionConfig = confBuilder .BindImplementation(typeof(IAction), actionType) .Build(); - var injector = TangFactory.GetTang().NewInjector(evaluatorConfig); + var injector = TangFactory.GetTang().NewInjector(contextConfig, taskConfig, actionConfig); injector.BindVolatileInstance(GenericType<IHeartBeatManager>.Class, heartbeatManager); return injector; } + private sealed class TestTaskEventHandler : IObserver<ITaskStart>, IObserver<ITaskStop> + { + [Inject] + private TestTaskEventHandler() + { + StartInvoked = Optional<string>.Empty(); + StopInvoked = Optional<string>.Empty(); + } + + public Optional<string> StartInvoked { get; private set; } + + public Optional<string> StopInvoked { get; private set; } + + public void OnNext(ITaskStart value) + { + StartInvoked = Optional<string>.Of(value.Id); + } + + public void OnNext(ITaskStop value) + { + StopInvoked = Optional<string>.Of(value.Id); + } + + public void OnError(Exception error) + { + throw new NotImplementedException(); + } + + public void OnCompleted() + { + throw new NotImplementedException(); + } + } + private sealed class TestTask : ITask { private readonly IAction _action; http://git-wip-us.apache.org/repos/asf/reef/blob/3818bf45/lang/cs/Org.Apache.REEF.Utilities/Collections/ReadOnlySet.cs ---------------------------------------------------------------------- diff --git a/lang/cs/Org.Apache.REEF.Utilities/Collections/ReadOnlySet.cs b/lang/cs/Org.Apache.REEF.Utilities/Collections/ReadOnlySet.cs new file mode 100644 index 0000000..d7f4414 --- /dev/null +++ b/lang/cs/Org.Apache.REEF.Utilities/Collections/ReadOnlySet.cs @@ -0,0 +1,137 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you 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. + +using System; +using System.Collections; +using System.Collections.Generic; + +namespace Org.Apache.REEF.Utilities.Collections +{ + /// <summary> + /// An implementation of a set that is read only. + /// Backed by a HashSet. + /// </summary> + public sealed class ReadOnlySet<T> : IReadOnlyCollection<T>, ISet<T> + { + private readonly ISet<T> _backingSet; + + public ReadOnlySet(IEnumerable<T> enumerable) + { + _backingSet = new HashSet<T>(enumerable); + } + + public IEnumerator<T> GetEnumerator() + { + return _backingSet.GetEnumerator(); + } + + IEnumerator IEnumerable.GetEnumerator() + { + return GetEnumerator(); + } + + void ICollection<T>.Add(T item) + { + throw new NotSupportedException("ReadOnlySet does not support Add."); + } + + public bool Add(T item) + { + throw new NotSupportedException("ReadOnlySet does not support Add."); + } + + public void UnionWith(IEnumerable<T> other) + { + throw new NotSupportedException("ReadOnlySet does not support UnionWith."); + } + + public void IntersectWith(IEnumerable<T> other) + { + throw new NotSupportedException("ReadOnlySet does not support IntersectWith."); + } + + public void ExceptWith(IEnumerable<T> other) + { + throw new NotSupportedException("ReadOnlySet does not support ExceptWith."); + } + + public void SymmetricExceptWith(IEnumerable<T> other) + { + throw new NotSupportedException("ReadOnlySet does not support SymmetricExceptWith."); + } + + public bool IsSubsetOf(IEnumerable<T> other) + { + return _backingSet.IsSubsetOf(other); + } + + public bool IsSupersetOf(IEnumerable<T> other) + { + return _backingSet.IsSupersetOf(other); + } + + public bool IsProperSupersetOf(IEnumerable<T> other) + { + return _backingSet.IsProperSupersetOf(other); + } + + public bool IsProperSubsetOf(IEnumerable<T> other) + { + return _backingSet.IsProperSubsetOf(other); + } + + public bool Overlaps(IEnumerable<T> other) + { + return _backingSet.Overlaps(other); + } + + public bool SetEquals(IEnumerable<T> other) + { + return _backingSet.SetEquals(other); + } + + public void Clear() + { + throw new NotSupportedException("ReadOnlySet does not support Clear."); + } + + public bool Contains(T item) + { + return _backingSet.Contains(item); + } + + public void CopyTo(T[] array, int arrayIndex) + { + _backingSet.CopyTo(array, arrayIndex); + } + + public bool Remove(T item) + { + throw new NotSupportedException("ReadOnlySet does not support Remove."); + } + + public int Count + { + get { return _backingSet.Count; } + } + + public bool IsReadOnly + { + get { return true; } + } + } +} http://git-wip-us.apache.org/repos/asf/reef/blob/3818bf45/lang/cs/Org.Apache.REEF.Utilities/Org.Apache.Reef.Utilities.csproj ---------------------------------------------------------------------- diff --git a/lang/cs/Org.Apache.REEF.Utilities/Org.Apache.Reef.Utilities.csproj b/lang/cs/Org.Apache.REEF.Utilities/Org.Apache.Reef.Utilities.csproj index 5d5129c..7baf88f 100644 --- a/lang/cs/Org.Apache.REEF.Utilities/Org.Apache.Reef.Utilities.csproj +++ b/lang/cs/Org.Apache.REEF.Utilities/Org.Apache.Reef.Utilities.csproj @@ -50,6 +50,7 @@ under the License. <Compile Include="AvroUtils.cs" /> <Compile Include="ByteUtilities.cs" /> <Compile Include="Collections\PriorityQueue.cs" /> + <Compile Include="Collections\ReadOnlySet.cs" /> <Compile Include="Diagnostics\DiagnosticsMessages.cs" /> <Compile Include="Diagnostics\Exceptions.cs" /> <Compile Include="IIdentifiable.cs" />
