diff --git a/README.md b/README.md index c29d549..0ffd83b 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,7 @@ **使用Nuget安装** ```PM -Install-Package CatLib.Core -Version 1.2.6 +Install-Package CatLib.Core -Version 1.2.7 ``` **直接下载发布版本** diff --git a/src/CatLib.Core.NetStandard/CatLib.Core.NetStandard.csproj b/src/CatLib.Core.NetStandard/CatLib.Core.NetStandard.csproj index cf208fd..e622e81 100644 --- a/src/CatLib.Core.NetStandard/CatLib.Core.NetStandard.csproj +++ b/src/CatLib.Core.NetStandard/CatLib.Core.NetStandard.csproj @@ -100,6 +100,7 @@ + @@ -115,8 +116,6 @@ - - diff --git a/src/CatLib.Core.Tests/CatLib.Core.Tests.csproj b/src/CatLib.Core.Tests/CatLib.Core.Tests.csproj index fa20fec..e13b715 100644 --- a/src/CatLib.Core.Tests/CatLib.Core.Tests.csproj +++ b/src/CatLib.Core.Tests/CatLib.Core.Tests.csproj @@ -56,7 +56,6 @@ - diff --git a/src/CatLib.Core.Tests/Properties/AssemblyInfo.cs b/src/CatLib.Core.Tests/Properties/AssemblyInfo.cs index 0e93c29..cb1810d 100644 --- a/src/CatLib.Core.Tests/Properties/AssemblyInfo.cs +++ b/src/CatLib.Core.Tests/Properties/AssemblyInfo.cs @@ -25,5 +25,5 @@ [assembly: Guid("3c9f4024-910c-4881-a04d-34a6c3a09019")] -[assembly: AssemblyVersion("1.2.6.0")] -[assembly: AssemblyFileVersion("1.2.6.0")] +[assembly: AssemblyVersion("1.2.7.0")] +[assembly: AssemblyFileVersion("1.2.7.0")] diff --git a/src/CatLib.Core.Tests/Support/SortSet/SortSetTests.cs b/src/CatLib.Core.Tests/Support/SortSet/SortSetTests.cs index 0857f00..8b33683 100644 --- a/src/CatLib.Core.Tests/Support/SortSet/SortSetTests.cs +++ b/src/CatLib.Core.Tests/Support/SortSet/SortSetTests.cs @@ -9,10 +9,9 @@ * Document: http://catlib.io/ */ +using Microsoft.VisualStudio.TestTools.UnitTesting; using System; using System.Collections.Generic; -using System.Reflection; -using Microsoft.VisualStudio.TestTools.UnitTesting; namespace CatLib.Tests.Stl { @@ -30,6 +29,56 @@ public int Compare(int x, int y) } } + [TestMethod] + public void TestRandValue() + { + var sortSets = new SortSet(); + var random = new Random(); + + for (var i = 1000; i >= 1; i--) + { + sortSets.Add(i, random.Next(0, 1000)); + } + + for (var i = 1; i <= 1000; i++) + { + if (sortSets.Remove(i)) + { + continue; + } + + Assert.Fail("can not remove i : " + i); + } + + Assert.AreEqual(0, sortSets.Count); + foreach (var sortSet in sortSets) + { + Assert.Fail(); + } + } + + [TestMethod] + public void TestRank() + { + var sortSets = new SortSet(); + + sortSets.Add(1000, 85); + sortSets.Add(999, 75); + sortSets.Add(998, 185); + sortSets.Add(997, 85); + sortSets.Add(996, 185); + sortSets.Add(995, 85); + + Assert.AreEqual(1, sortSets.GetRank(995)); + Assert.AreEqual(995, sortSets.GetElementByRank(1)); + Assert.AreEqual(997, sortSets.GetElementByRank(2)); + Assert.AreEqual(1000, sortSets.GetElementByRank(3)); + Assert.AreEqual(996, sortSets.GetElementByRank(4)); + Assert.AreEqual(998, sortSets.GetElementByRank(5)); + + Assert.AreEqual(3, sortSets.GetRangeCount(80, 90)); + } + [TestMethod] public void TestCustomComparer() { diff --git a/src/CatLib.Core.Tests/Support/Util/ReferenceCountTests.cs b/src/CatLib.Core.Tests/Support/Util/ReferenceCountTests.cs deleted file mode 100644 index 07bdd8f..0000000 --- a/src/CatLib.Core.Tests/Support/Util/ReferenceCountTests.cs +++ /dev/null @@ -1,119 +0,0 @@ -/* - * This file is part of the CatLib package. - * - * (c) Yu Bin - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - * - * Document: http://catlib.io/ - */ - -using System; -using Microsoft.VisualStudio.TestTools.UnitTesting; - -namespace CatLib.Tests.Support.Util -{ - [TestClass] - public class ReferenceCountTests - { - public class TestReferenceClass : IDisposable - { - /// - /// 回调 - /// - private Action callback; - - public TestReferenceClass(Action callback) - { - this.callback = callback; - } - - /// - /// 释放 - /// - public void Dispose() - { - callback.Invoke(); - } - } - - public class TestInherit : ReferenceCount ,IDisposable - { - internal bool IsReleaseCall; - - internal bool IsRetainCall; - - internal bool IsDispose; - - public override void Release() - { - IsReleaseCall = true; - base.Release(); - } - - public override void Retain() - { - IsRetainCall = true; - base.Retain(); - } - - public void Dispose() - { - IsDispose = true; - } - } - - [TestMethod] - public void SimpleReferenceCountTest() - { - var isCall = false; - - var cls = new TestReferenceClass(() => - { - isCall = true; - }); - - var rc = new ReferenceCount(cls); - rc.Retain(); - Assert.AreEqual(1, rc.RefCount); - rc.Release(); - - Assert.AreEqual(true, isCall); - - ExceptionAssert.Throws(() => - { - rc.Release(); - }); - - ExceptionAssert.Throws(() => - { - rc.Retain(); - }); - } - - [TestMethod] - public void TestInheritReferenceCount() - { - var cls = new TestInherit(); - - cls.Retain(); - Assert.AreEqual(1, cls.RefCount); - cls.Release(); - - Assert.AreEqual(true, cls.IsReleaseCall); - Assert.AreEqual(true, cls.IsRetainCall); - Assert.AreEqual(true, cls.IsDispose); - - ExceptionAssert.Throws(() => - { - cls.Release(); - }); - - ExceptionAssert.Throws(() => - { - cls.Retain(); - }); - } - } -} diff --git a/src/CatLib.Core/CatLib.Core.csproj b/src/CatLib.Core/CatLib.Core.csproj index 7b3f85f..2fb2a97 100644 --- a/src/CatLib.Core/CatLib.Core.csproj +++ b/src/CatLib.Core/CatLib.Core.csproj @@ -83,6 +83,7 @@ + @@ -98,8 +99,6 @@ - - diff --git a/src/CatLib.Core/CatLib/Application.cs b/src/CatLib.Core/CatLib/Application.cs index 41221e9..58e38e9 100644 --- a/src/CatLib.Core/CatLib/Application.cs +++ b/src/CatLib.Core/CatLib/Application.cs @@ -11,7 +11,6 @@ using System; using System.Collections.Generic; -using System.Reflection; using System.Threading; namespace CatLib diff --git a/src/CatLib.Core/Properties/AssemblyInfo.cs b/src/CatLib.Core/Properties/AssemblyInfo.cs index 3d1fa3e..604d6bc 100644 --- a/src/CatLib.Core/Properties/AssemblyInfo.cs +++ b/src/CatLib.Core/Properties/AssemblyInfo.cs @@ -26,8 +26,8 @@ [assembly: Guid("4204658e-81fd-4106-a347-890cd369c8a4")] -[assembly: AssemblyVersion("1.2.6.0")] -[assembly: AssemblyFileVersion("1.2.6.0")] +[assembly: AssemblyVersion("1.2.7.0")] +[assembly: AssemblyFileVersion("1.2.7.0")] [assembly: InternalsVisibleTo("Assembly-CSharp-Editor"), InternalsVisibleTo("Assembly-CSharp-Editor-firstpass"), diff --git a/src/CatLib.Core/Support/Container/BindDataExtend.cs b/src/CatLib.Core/Support/Container/BindDataExtend.cs index 5ea0efc..c121d3f 100644 --- a/src/CatLib.Core/Support/Container/BindDataExtend.cs +++ b/src/CatLib.Core/Support/Container/BindDataExtend.cs @@ -34,6 +34,22 @@ public static IBindData OnResolving(this IBindData bindData, Action acti }); } + /// + /// 解决服务时触发的回调 + /// + /// 绑定数据 + /// 解决事件 + /// 服务绑定数据 + public static IBindData OnResolving(this IBindData bindData, Action action) + { + Guard.Requires(action != null); + return bindData.OnResolving((_, instance) => + { + action(); + return instance; + }); + } + /// /// 当静态服务被释放时 /// diff --git a/src/CatLib.Core/Support/RingBuffer/IRingBuffer.cs b/src/CatLib.Core/Support/RingBuffer/IRingBuffer.cs new file mode 100644 index 0000000..ddb50e0 --- /dev/null +++ b/src/CatLib.Core/Support/RingBuffer/IRingBuffer.cs @@ -0,0 +1,146 @@ +/* + * This file is part of the CatLib package. + * + * (c) Yu Bin + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + * + * Document: http://catlib.io/ + */ + +namespace CatLib +{ + /// + /// 环型缓冲区 + /// + public interface IRingBuffer + { + /// + /// 缓冲区容量 + /// + int Capacity { get; } + + /// + /// 同步锁 + /// + object SyncRoot { get; } + + /// + /// 可写容量 + /// + int WriteableCapacity { get; } + + /// + /// 可读容量 + /// + int ReadableCapacity { get; } + + /// + /// 是否可以进行读取 + /// + /// 指定的长度 + bool CanRead(int count = 1); + + /// + /// 是否可以进行写入 + /// + /// 指定的长度 + bool CanWrite(int count = 1); + + /// + /// 获取环型缓冲区的原始数组 + /// + /// 原始数组 + byte[] GetBuffer(); + + /// + /// 将可以读取的数据全部返回 + /// + /// 可以读取的数据 + byte[] Read(); + + /// + /// 将数据读取到中 + /// + /// 输出的数据 + /// 实际输出的长度 + int Read(byte[] buffer); + + /// + /// 将数据读取到中 + /// + /// 输出的数据 + /// 输出数组偏移多少作为起始 + /// 实际输出的长度 + int Read(byte[] buffer, int offset); + + /// + /// 将数据读取到中 + /// + /// 输出的数据 + /// 输出数组偏移多少作为起始 + /// 输出的长度 + /// 实际输出的长度 + int Read(byte[] buffer, int offset, int count); + + /// + /// 将环型缓冲区的数据全部返回,但是不前移读取位置 + /// + /// 实际输出的长度 + byte[] Peek(); + + /// + /// 将环型缓冲区的数据读取到中,但是不前移读取位置 + /// + /// 输出的数据 + /// 实际输出的长度 + int Peek(byte[] buffer); + + /// + /// 将环型缓冲区的数据读取到中,但是不前移读取位置 + /// + /// 输出的数据 + /// 输出数组偏移多少作为起始 + /// 实际输出的长度 + int Peek(byte[] buffer, int offset); + + /// + /// 将环型缓冲区的数据读取到中,但是不前移读取位置 + /// + /// 输出的数据 + /// 输出数组偏移多少作为起始 + /// 输出的长度 + /// 实际输出的长度 + int Peek(byte[] buffer, int offset, int count); + + /// + /// 将数据写入到环型缓冲区 + /// + /// 写入的数据 + /// 实际被写入的长度 + int Write(byte[] buffer); + + /// + /// 将数据写入到环型缓冲区 + /// + /// 写入的数据 + /// 偏移多少数据开始写入 + /// 实际被写入的长度 + int Write(byte[] buffer, int offset); + + /// + /// 将数据写入到环型缓冲区 + /// + /// 写入的数据 + /// 偏移多少数据开始写入 + /// 写入的长度 + /// 实际被写入的长度 + int Write(byte[] buffer, int offset, int count); + + /// + /// 清空缓冲区中的所有数据 + /// + void Flush(); + } +} diff --git a/src/CatLib.Core/Support/RingBuffer/RingBuffer.cs b/src/CatLib.Core/Support/RingBuffer/RingBuffer.cs index b1dccab..8b57c7f 100644 --- a/src/CatLib.Core/Support/RingBuffer/RingBuffer.cs +++ b/src/CatLib.Core/Support/RingBuffer/RingBuffer.cs @@ -1,7 +1,15 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; +/* + * This file is part of the CatLib package. + * + * (c) Yu Bin + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + * + * Document: http://catlib.io/ + */ + +using System; using System.Threading; namespace CatLib @@ -9,7 +17,7 @@ namespace CatLib /// /// 环型缓冲区 /// - public sealed class RingBuffer : IDisposable + public sealed class RingBuffer : IRingBuffer, IDisposable { /// /// 容量 @@ -83,7 +91,7 @@ public int WriteableCapacity /// public int ReadableCapacity { - get { return (int) GetCanReadSize(); } + get { return (int)GetCanReadSize(); } } /// @@ -204,7 +212,7 @@ public byte[] Peek() } /// - /// 将环型缓冲区的数据读取到中,但是不前移读取位置 + /// 将环型缓冲区的数据读取到中,但是不前移读取位置 /// /// 输出的数据 /// 实际输出的长度 @@ -215,7 +223,7 @@ public int Peek(byte[] buffer) } /// - /// 将环型缓冲区的数据读取到中,但是不前移读取位置 + /// 将环型缓冲区的数据读取到中,但是不前移读取位置 /// /// 输出的数据 /// 输出数组偏移多少作为起始 @@ -227,7 +235,7 @@ public int Peek(byte[] buffer, int offset) } /// - /// 将环型缓冲区的数据读取到中,但是不前移读取位置 + /// 将环型缓冲区的数据读取到中,但是不前移读取位置 /// /// 输出的数据 /// 输出数组偏移多少作为起始 diff --git a/src/CatLib.Core/Support/SortSet/SortSet.cs b/src/CatLib.Core/Support/SortSet/SortSet.cs index 04cd704..5b27a71 100644 --- a/src/CatLib.Core/Support/SortSet/SortSet.cs +++ b/src/CatLib.Core/Support/SortSet/SortSet.cs @@ -32,7 +32,7 @@ private class SkipNode internal struct SkipNodeLevel { /// - /// 前一个结点 + /// 下一个结点 /// internal SkipNode Forward; @@ -337,7 +337,7 @@ public TElement[] ToArray() { var elements = new TElement[Count]; var node = header.Level[0]; - int i = 0; + var i = 0; while (node.Forward != null) { elements[i++] = node.Forward.Element; @@ -489,19 +489,23 @@ public int GetRangeCount(TScore start, TScore end) rank += cursor.Level[i].Span; cursor = cursor.Level[i].Forward; } - if (bakCursor == null) + + if (bakCursor != null) { - bakCursor = cursor; - bakRank = rank; + continue; } + + bakCursor = cursor; + bakRank = rank; } - if (!isRight) + if (isRight) { - cursor = bakCursor; - rank ^= bakRank ^= rank ^= bakRank; + continue; } + cursor = bakCursor; + rank ^= bakRank ^= rank ^= bakRank; } while (isRight = !isRight); return Math.Max(0, rank - bakRank); @@ -713,7 +717,7 @@ public TElement GetElementByRank(int rank) { rank = Math.Max(0, rank); rank += 1; - int traversed = 0; + var traversed = 0; var cursor = header; for (var i = level - 1; i >= 0; i--) { @@ -723,15 +727,18 @@ public TElement GetElementByRank(int rank) traversed += cursor.Level[i].Span; cursor = cursor.Level[i].Forward; } + if (traversed == rank) { return cursor.Element; } } + if (Count > 0) { throw new ArgumentOutOfRangeException("Rank is out of range [" + rank + "]"); } + throw new InvalidOperationException("SortSet is Null"); } @@ -869,9 +876,7 @@ private bool Remove(TElement element, TScore score) //从跳跃层高到低的进行查找 for (var i = level - 1; i >= 0; --i) { - while (cursor.Level[i].Forward != null && - (Compare(cursor.Level[i].Forward.Score, score) <= 0 && - !cursor.Level[i].Forward.Element.Equals(element))) + while (IsFindNext(cursor.Level[i].Forward, element, score, i)) { cursor = cursor.Level[i].Forward; } @@ -902,27 +907,64 @@ private bool Remove(TElement element, TScore score) /// 排名,排名以0为底 private int GetRank(TElement element, TScore score) { - int rank = 0; + var rank = 0; var cursor = header; for (var i = level - 1; i >= 0; --i) { - while (cursor.Level[i].Forward != null && - (Compare(cursor.Level[i].Forward.Score, score) <= 0 && - !cursor.Level[i].Forward.Equals(element))) + while (IsFindNext(cursor.Level[i].Forward, element, score, i)) { rank += cursor.Level[i].Span; cursor = cursor.Level[i].Forward; } - if (cursor != header && - cursor.Element != null && - cursor.Element.Equals(element)) - { - return rank - 1; - } } + + cursor = cursor.Level[0].Forward; + + if (cursor != null && cursor != header && + cursor.Element != null && + cursor.Element.Equals(element)) + { + return rank; + } + return -1; } + /// + /// 是否查询下一个元素 + /// + /// 跳跃结点 + /// 元素 + /// 分数 + /// 层级 + /// 是否查找下一个 + private bool IsFindNext(SkipNode node, TElement element, TScore score, int level) + { + if (node == null) + { + return false; + } + + var compare = Compare(node.Score, score); + if (compare < 0 || compare > 0) + { + return compare < 0; + } + + // 如果层级大于0,说明有可能直接定位到元素2,从而导致bug + // 所以我们认为层级大于 0 那么值相等依旧返回前序跳跃结点 + // + // ------------------------------------------ + // | 元素1(分数:50) | 元素2 (分数:50) + // ------------------------------------------ + if (level > 0) + { + return false; + } + + return !node.Element.Equals(element); + } + /// /// 删除结点关系 /// diff --git a/src/CatLib.Core/Support/Util/IReferenceCount.cs b/src/CatLib.Core/Support/Util/IReferenceCount.cs deleted file mode 100644 index d51f78a..0000000 --- a/src/CatLib.Core/Support/Util/IReferenceCount.cs +++ /dev/null @@ -1,34 +0,0 @@ -/* - * This file is part of the CatLib package. - * - * (c) Yu Bin - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - * - * Document: http://catlib.io/ - */ - -namespace CatLib -{ - /// - /// 引用计数 - /// - public interface IReferenceCount - { - /// - /// 当前引用计数 - /// - int RefCount { get; } - - /// - /// 加计数。 - /// - void Retain(); - - /// - /// 减计数 - /// - void Release(); - } -} diff --git a/src/CatLib.Core/Support/Util/ReferenceCount.cs b/src/CatLib.Core/Support/Util/ReferenceCount.cs deleted file mode 100644 index c0f1864..0000000 --- a/src/CatLib.Core/Support/Util/ReferenceCount.cs +++ /dev/null @@ -1,83 +0,0 @@ -/* - * This file is part of the CatLib package. - * - * (c) Yu Bin - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - * - * Document: http://catlib.io/ - */ - -using System; -using System.Threading; - -namespace CatLib -{ - /// - /// 引用计数 - /// - public class ReferenceCount : IReferenceCount - { - /// - /// 计数 - /// - private int count; - - /// - /// 释放句柄 - /// - private readonly IDisposable disposable; - - /// - /// 当前计数 - /// - public int RefCount - { - get - { - return count; - } - } - - /// - /// 引用计数 - /// - public ReferenceCount() - { - disposable = this as IDisposable; - Guard.Requires(disposable != null); - } - - /// - /// 引用计数 - /// - /// 释放接口 - public ReferenceCount(IDisposable disposable) - { - Guard.Requires(disposable != null); - this.disposable = disposable; - } - - /// - /// 加计数。 - /// - public virtual void Retain() - { - var value = Interlocked.Increment(ref count); - Guard.Requires(value > 0); - } - - /// - /// 减计数 - /// - public virtual void Release() - { - if (Interlocked.Decrement(ref count) == 0) - { - disposable.Dispose(); - } - Guard.Requires(count >= 0); - } - } -} diff --git a/src/CatLib.Core/Support/Util/Str.cs b/src/CatLib.Core/Support/Util/Str.cs index a5103d3..f4c4fc2 100644 --- a/src/CatLib.Core/Support/Util/Str.cs +++ b/src/CatLib.Core/Support/Util/Str.cs @@ -10,7 +10,6 @@ */ using System; -using System.Collections.Specialized; using System.Text; using System.Text.RegularExpressions;