You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucenenet.apache.org by ni...@apache.org on 2017/03/24 02:02:39 UTC
[07/15] lucenenet git commit: Lucene.Net.Core.Util.SetOnce: Changed
back to original implementation that uses AtomicBoolean rather than
Interlocked. Also added a class generic constraint to revert back to using
the volatile keyword and fixed the test to
Lucene.Net.Core.Util.SetOnce: Changed back to original implementation that uses AtomicBoolean rather than Interlocked. Also added a class generic constraint to revert back to using the volatile keyword and fixed the test to use a reference type for testing.
Project: http://git-wip-us.apache.org/repos/asf/lucenenet/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucenenet/commit/50bbf51b
Tree: http://git-wip-us.apache.org/repos/asf/lucenenet/tree/50bbf51b
Diff: http://git-wip-us.apache.org/repos/asf/lucenenet/diff/50bbf51b
Branch: refs/heads/api-work
Commit: 50bbf51be1674906a4457cf155d86284a79feb73
Parents: d9f979c
Author: Shad Storhaug <sh...@shadstorhaug.com>
Authored: Thu Mar 23 23:18:44 2017 +0700
Committer: Shad Storhaug <sh...@shadstorhaug.com>
Committed: Thu Mar 23 23:35:01 2017 +0700
----------------------------------------------------------------------
src/Lucene.Net.Core/Util/SetOnce.cs | 33 +++++++++----------
src/Lucene.Net.Tests/Util/TestSetOnce.cs | 47 +++++++++++++++++----------
2 files changed, 45 insertions(+), 35 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/50bbf51b/src/Lucene.Net.Core/Util/SetOnce.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Core/Util/SetOnce.cs b/src/Lucene.Net.Core/Util/SetOnce.cs
index 2710842..2ac06fe 100644
--- a/src/Lucene.Net.Core/Util/SetOnce.cs
+++ b/src/Lucene.Net.Core/Util/SetOnce.cs
@@ -1,5 +1,5 @@
+using Lucene.Net.Support;
using System;
-using System.Threading;
namespace Lucene.Net.Util
{
@@ -23,16 +23,16 @@ namespace Lucene.Net.Util
/// <summary>
/// A convenient class which offers a semi-immutable object wrapper
/// implementation which allows one to set the value of an object exactly once,
- /// and retrieve it many times. If <seealso cref="#set(Object)"/> is called more than once,
- /// <seealso cref="AlreadySetException"/> is thrown and the operation
+ /// and retrieve it many times. If <see cref="Set(T)"/> is called more than once,
+ /// <see cref="AlreadySetException"/> is thrown and the operation
/// will fail.
- ///
+ /// <para/>
/// @lucene.experimental
/// </summary>
- public sealed class SetOnce<T>
+ public sealed class SetOnce<T> where T : class // LUCENENET specific - added class constraint so we don't accept value types (which cannot be volatile)
{
/// <summary>
- /// Thrown when <seealso cref="SetOnce#set(Object)"/> is called more than once. </summary>
+ /// Thrown when <see cref="SetOnce.Set(T)"/> is called more than once. </summary>
// LUCENENET: All exeption classes should be marked serializable
#if FEATURE_SERIALIZABLE
[Serializable]
@@ -45,37 +45,36 @@ namespace Lucene.Net.Util
}
}
- private T obj = default(T);
- private int set;
+ private volatile T obj = default(T);
+ private readonly AtomicBoolean set;
/// <summary>
/// A default constructor which does not set the internal object, and allows
- /// setting it by calling <seealso cref="#set(Object)"/>.
+ /// setting it by calling <see cref="Set(T)"/>.
/// </summary>
public SetOnce()
{
- set = 0;
+ set = new AtomicBoolean(false);
}
/// <summary>
/// Creates a new instance with the internal object set to the given object.
- /// Note that any calls to <seealso cref="#set(Object)"/> afterwards will result in
- /// <seealso cref="AlreadySetException"/>
+ /// Note that any calls to <see cref="Set(T)"/> afterwards will result in
+ /// <see cref="AlreadySetException"/>
/// </summary>
/// <exception cref="AlreadySetException"> if called more than once </exception>
- /// <seealso cref= #set(Object) </seealso>
+ /// <seealso cref="Set(T)"/>
public SetOnce(T obj)
{
this.obj = obj;
- set = 1;
+ set = new AtomicBoolean(true);
}
/// <summary>
/// Sets the given object. If the object has already been set, an exception is thrown. </summary>
public void Set(T obj)
{
- //if (set.compareAndSet(false, true))
- if (Interlocked.CompareExchange(ref set, 1, 0) == 0)
+ if (set.CompareAndSet(false, true))
{
this.obj = obj;
}
@@ -86,7 +85,7 @@ namespace Lucene.Net.Util
}
/// <summary>
- /// Returns the object set by <seealso cref="#set(Object)"/>. </summary>
+ /// Returns the object set by <see cref="Set(T)"/>. </summary>
public T Get()
{
return obj;
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/50bbf51b/src/Lucene.Net.Tests/Util/TestSetOnce.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Tests/Util/TestSetOnce.cs b/src/Lucene.Net.Tests/Util/TestSetOnce.cs
index fd53d74..e54c080 100644
--- a/src/Lucene.Net.Tests/Util/TestSetOnce.cs
+++ b/src/Lucene.Net.Tests/Util/TestSetOnce.cs
@@ -1,7 +1,8 @@
-using System.Threading;
using Lucene.Net.Support;
using NUnit.Framework;
using System;
+using System.Globalization;
+using System.Threading;
namespace Lucene.Net.Util
{
@@ -25,10 +26,20 @@ namespace Lucene.Net.Util
[TestFixture]
public class TestSetOnce : LuceneTestCase
{
+ private class Integer // LUCENENET specific class for testing (since int? is not a reference type)
+ {
+ public Integer(int value)
+ {
+ this.value = value;
+ }
+
+ internal int value;
+ }
+
private sealed class SetOnceThread : ThreadClass
{
- internal SetOnce<int?> Set;
- internal bool Success = false;
+ internal SetOnce<Integer> set;
+ internal bool success = false;
internal readonly Random RAND;
public SetOnceThread(Random random)
@@ -41,8 +52,8 @@ namespace Lucene.Net.Util
try
{
Sleep(RAND.Next(10)); // sleep for a short time
- Set.Set(new int?(Convert.ToInt32(Name.Substring(2))));
- Success = true;
+ set.Set(new Integer(Convert.ToInt32(Name.Substring(2), CultureInfo.InvariantCulture)));
+ success = true;
}
#if !NETSTANDARD
catch (ThreadInterruptedException)
@@ -54,7 +65,7 @@ namespace Lucene.Net.Util
{
// TODO: change exception type
// expected.
- Success = false;
+ success = false;
}
}
}
@@ -62,38 +73,38 @@ namespace Lucene.Net.Util
[Test]
public virtual void TestEmptyCtor()
{
- SetOnce<int?> set = new SetOnce<int?>();
+ SetOnce<Integer> set = new SetOnce<Integer>();
Assert.IsNull(set.Get());
}
[Test]
public virtual void TestSettingCtor()
{
- SetOnce<int?> set = new SetOnce<int?>(new int?(5));
- Assert.AreEqual(5, (int)set.Get());
- Assert.Throws<SetOnce<int?>.AlreadySetException>(() => set.Set(new int?(7)));
+ SetOnce<Integer> set = new SetOnce<Integer>(new Integer(5));
+ Assert.AreEqual(5, set.Get().value);
+ Assert.Throws<SetOnce<Integer>.AlreadySetException>(() => set.Set(new Integer(7)));
}
[Test]
public virtual void TestSetOnce_mem()
{
- SetOnce<int?> set = new SetOnce<int?>();
- set.Set(new int?(5));
- Assert.AreEqual(5, (int)set.Get());
- Assert.Throws<SetOnce<int?>.AlreadySetException>(() => set.Set(new int?(7)));
+ SetOnce<Integer> set = new SetOnce<Integer>();
+ set.Set(new Integer(5));
+ Assert.AreEqual(5, set.Get().value);
+ Assert.Throws<SetOnce<Integer>.AlreadySetException>(() => set.Set(new Integer(7)));
}
[Test]
public virtual void TestSetMultiThreaded()
{
- SetOnce<int?> set = new SetOnce<int?>();
+ SetOnce<Integer> set = new SetOnce<Integer>();
SetOnceThread[] threads = new SetOnceThread[10];
Random random = Random();
for (int i = 0; i < threads.Length; i++)
{
threads[i] = new SetOnceThread(random);
threads[i].Name = "t-" + (i + 1);
- threads[i].Set = set;
+ threads[i].set = set;
}
foreach (ThreadClass t in threads)
@@ -108,10 +119,10 @@ namespace Lucene.Net.Util
foreach (SetOnceThread t in threads)
{
- if (t.Success)
+ if (t.success)
{
int expectedVal = Convert.ToInt32(t.Name.Substring(2));
- Assert.AreEqual(expectedVal, t.Set.Get(), "thread " + t.Name);
+ Assert.AreEqual(expectedVal, t.set.Get().value, "thread " + t.Name);
}
}
}