lucenenet-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From mhern...@apache.org
Subject [5/5] git commit: adding SetOnce<T> with tests.
Date Thu, 14 Aug 2014 01:22:27 GMT
adding SetOnce<T> with tests.


Project: http://git-wip-us.apache.org/repos/asf/lucenenet/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucenenet/commit/7cfd98d5
Tree: http://git-wip-us.apache.org/repos/asf/lucenenet/tree/7cfd98d5
Diff: http://git-wip-us.apache.org/repos/asf/lucenenet/diff/7cfd98d5

Branch: refs/heads/pcl
Commit: 7cfd98d54732c0f5c4a17dc2121c3eb6b3b22dc4
Parents: 8ad0c83
Author: Michael Herndon <mherndon@michaelherndon.com>
Authored: Wed Aug 13 21:21:03 2014 -0400
Committer: Michael Herndon <mherndon@michaelherndon.com>
Committed: Wed Aug 13 21:21:03 2014 -0400

----------------------------------------------------------------------
 src/Lucene.Net.Core/Lucene.Net.Core.csproj      |   1 +
 src/Lucene.Net.Core/Util/BroadWord.cs           |   7 +-
 src/Lucene.Net.Core/Util/CharsRef.cs            |   6 +-
 src/Lucene.Net.Core/Util/SetOnce.cs             | 102 +++++++++++++++
 .../Lucene.Net.Core.Tests.csproj                |   1 +
 test/Lucene.Net.Core.Tests/Util/TestSetOnce.cs  | 126 +++++++++++++++++++
 6 files changed, 239 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucenenet/blob/7cfd98d5/src/Lucene.Net.Core/Lucene.Net.Core.csproj
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Core/Lucene.Net.Core.csproj b/src/Lucene.Net.Core/Lucene.Net.Core.csproj
index 64dfeb9..75c8337 100644
--- a/src/Lucene.Net.Core/Lucene.Net.Core.csproj
+++ b/src/Lucene.Net.Core/Lucene.Net.Core.csproj
@@ -82,6 +82,7 @@
     <Compile Include="Util\IBits.cs" />
     <Compile Include="Util\InPlaceMergeSorter.cs" />
     <Compile Include="Util\RamUsageEstimator.cs" />
+    <Compile Include="Util\SetOnce.cs" />
     <Compile Include="Util\Sorter.cs" />
     <Compile Include="Util\StringHelper.cs" />
     <Compile Include="Util\SystemProps.cs" />

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/7cfd98d5/src/Lucene.Net.Core/Util/BroadWord.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Core/Util/BroadWord.cs b/src/Lucene.Net.Core/Util/BroadWord.cs
index 1fa2f36..b73a68c 100644
--- a/src/Lucene.Net.Core/Util/BroadWord.cs
+++ b/src/Lucene.Net.Core/Util/BroadWord.cs
@@ -151,9 +151,14 @@ namespace Lucene.Net.Util
 
 
         /// <summary>
-        /// Naive implementation of <seealso cref="#select(long,int)"/>, using <seealso
cref="Long#numberOfTrailingZeros"/> repetitively.
+        /// Naive implementation of <seealso cref="Select(long,int)"/>.
         /// Works relatively fast for low ranks. 
         /// </summary>
+        /// <remarks>
+        ///     <para>
+        ///         Internally uses <see cref="Lucene.Net.Support.NumberExtensionMethods.NumberOfTrailingZeros"/>
repetitively.
+        ///     </para>
+        /// </remarks>
         /// <returns> The index of the r-th 1 bit in x, or if no such bit exists, 72.
</returns>
         public static int SelectNaive(long x, int r)
         {

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/7cfd98d5/src/Lucene.Net.Core/Util/CharsRef.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Core/Util/CharsRef.cs b/src/Lucene.Net.Core/Util/CharsRef.cs
index 744db7b..02afe39 100644
--- a/src/Lucene.Net.Core/Util/CharsRef.cs
+++ b/src/Lucene.Net.Core/Util/CharsRef.cs
@@ -152,10 +152,10 @@ namespace Lucene.Net.Util
         }
 
         /// <summary>
-        /// 
+        /// Determines if the other <see cref="CharsRef"/> is equal to the current
instance.
         /// </summary>
-        /// <param name="other"></param>
-        /// <returns></returns>
+        /// <param name="other">The instance to compare.</param>
+        /// <returns>True, if the other instance is equal to the current instance,
otherwise false.</returns>
         public bool CharsEquals(CharsRef other)
         {
             if (Length == other.Length)

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/7cfd98d5/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
new file mode 100644
index 0000000..ac3c821
--- /dev/null
+++ b/src/Lucene.Net.Core/Util/SetOnce.cs
@@ -0,0 +1,102 @@
+/*
+ * 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.
+ */
+
+namespace Lucene.Net.Util
+{
+    using System;
+    using Lucene.Net.Support;
+
+  
+
+    /// <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. 
+    /// </summary>
+    /// <typeparam name="T">The value type.</typeparam>
+    public class SetOnce<T> : Lucene.Net.Support.ICloneable
+    {
+        private T value;
+        private volatile bool isSet;
+
+        /// <summary>
+        /// Initializes a new instance of <see cref="SetOnce{T}"/>
+        /// </summary>
+        public SetOnce()
+        {
+            this.isSet = false;
+        }
+
+        /// <summary>
+        /// Initializes a new instance of <see cref="SetOnce{T}"/> with the 
+        /// specified <paramref name="value"/>/
+        /// </summary>
+        /// <param name="value">The value to set.</param>
+        public SetOnce(T value)
+        {
+            this.Set(value);
+        }
+
+        /// <summary>
+        /// Gets whether or not the value is already set.
+        /// </summary>
+        public bool ValueIsSet
+        {
+            get { return this.isSet; }
+        }
+
+        /// <summary>
+        /// Gets or sets the value once.
+        /// </summary>
+        public T Value
+        {
+            get { return this.value; }
+            set { this.Set(value); }
+        }
+
+        /// <summary>
+        /// Sets the value.
+        /// </summary>
+        /// <param name="value">The value to be set.</param>
+        /// <exception cref="SetOnce.AlreadySetException">Thrown when the value has
already been set.</exception>
+        protected void Set(T value)
+        {
+            if (!Object.ReferenceEquals(this.value, value) && isSet)
+                throw new AlreadySetException("value has already been set");
+
+            this.isSet = true;
+            this.value = value;
+        }
+
+        [Serializable]
+        public class AlreadySetException : Exception
+        {
+            public AlreadySetException() : this("The object cannot be set more than once.")
{ }
+            public AlreadySetException(string message) : base(message) { }
+            public AlreadySetException(string message, Exception inner) : base(message, inner)
{ }
+
+        }
+
+        public object Clone(bool deepClone)
+        {
+            if (deepClone)
+                throw new DeepCloneNotSupportedException();
+
+            return this.MemberwiseClone();
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/7cfd98d5/test/Lucene.Net.Core.Tests/Lucene.Net.Core.Tests.csproj
----------------------------------------------------------------------
diff --git a/test/Lucene.Net.Core.Tests/Lucene.Net.Core.Tests.csproj b/test/Lucene.Net.Core.Tests/Lucene.Net.Core.Tests.csproj
index 6a44bcd..8f6632f 100644
--- a/test/Lucene.Net.Core.Tests/Lucene.Net.Core.Tests.csproj
+++ b/test/Lucene.Net.Core.Tests/Lucene.Net.Core.Tests.csproj
@@ -68,6 +68,7 @@
     <Compile Include="Util\TestConstants.cs" />
     <Compile Include="Util\TestInPlaceMergeSorter.cs" />
     <Compile Include="Util\TestRamEstimatorUsage.cs" />
+    <Compile Include="Util\TestSetOnce.cs" />
     <Compile Include="Util\TestVersion.cs" />
   </ItemGroup>
   <ItemGroup>

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/7cfd98d5/test/Lucene.Net.Core.Tests/Util/TestSetOnce.cs
----------------------------------------------------------------------
diff --git a/test/Lucene.Net.Core.Tests/Util/TestSetOnce.cs b/test/Lucene.Net.Core.Tests/Util/TestSetOnce.cs
new file mode 100644
index 0000000..dcbd1e0
--- /dev/null
+++ b/test/Lucene.Net.Core.Tests/Util/TestSetOnce.cs
@@ -0,0 +1,126 @@
+/*
+ * 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.
+ */
+
+namespace Lucene.Net.Util
+{
+    using System;
+    using System.Collections.Generic;
+    using System.Linq;
+    using System.Text;
+    using System.Threading.Tasks;
+
+    public class TestSetOnce : LuceneTestCase
+    {
+        [Test(JavaMethodName = "TestEmptyCtor")]
+        public void Constructor()
+        {
+            var set = new SetOnce<int?>();
+            Equal(null, set.Value);
+        }
+
+        [Test(JavaMethodName = "TestSettingCtor")]
+        public void ConstructorWithValue()
+        {
+            var set = new SetOnce<int>(5);
+            Equal(5, set.Value);
+
+            Throws<SetOnce<int>.AlreadySetException>(() =>
+            {
+                set.Value = 7;
+            });
+        }
+
+        [Test]
+        public void TestSet()
+        {
+            var set = new SetOnce<int>();
+            Equal(0, set.Value);
+            
+            set.Value = 5;
+            Equal(5, set.Value);
+
+            Throws<SetOnce<int>.AlreadySetException>(() =>
+            {
+                set.Value = 7;
+            });
+        }
+       
+        [Test]
+        public void TestSetMultiThreaded()
+        {
+            // This test will always differ from the Java version 
+            // because the Lucene.Net.Core project is now a PCL project.
+            
+
+            var one = new SetOnce<int>();
+            Task<Result>[] tasks = new Task<Result>[10];
+            Result[] results = new Result[10];
+            tasks.Length.Times((i) =>
+            {
+                var result = new Result() {
+                      Name = "Thread " + i.ToString(),
+                      Value = i
+                };
+                results[i] = result;
+
+                tasks[i] = new Task<Result>(() => {
+                     
+
+                    try {
+                        one.Value = i;
+                        result.Success = true;
+                        result.Set = one;
+                    } catch {
+                        result.Set = one;
+                        result.Success = false;
+                    }
+                    
+                    return result;
+                });
+            });
+
+            foreach (var task in tasks)
+                task.Start();
+
+            var final = Task.WhenAll(tasks).Result; 
+
+            var successes = final.Where(o => o.Success).Count();
+
+            Ok(final.Count() == 10, "There should be 10 results.");
+            Ok(successes == 1, "There should be only one result that is a success.");
+
+            foreach(var task in tasks)
+            {
+                if(task.Result != null && task.Result.Success)
+                {
+                    var expected = results[task.Result.Value];
+                    Equal(expected.Value, task.Result.Set.Value);
+                }
+            }
+        }
+
+        public class Result
+        {
+            public string Name { get; set; }
+            public int Value { get; set; }
+
+            public bool Success { get; set; }
+
+            public SetOnce<int> Set { get; set; }
+        }
+    }
+}


Mime
View raw message