Skip to content

Commit

Permalink
增加双向链表,未处理线程安全
Browse files Browse the repository at this point in the history
  • Loading branch information
nnhy committed Oct 23, 2017
1 parent 9042f8d commit 4b21a7a
Show file tree
Hide file tree
Showing 4 changed files with 198 additions and 10 deletions.
109 changes: 109 additions & 0 deletions NewLife.Core/Collections/LinkList.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace NewLife.Collections
{
/// <summary>双向链表</summary>
/// <typeparam name="T"></typeparam>
public class LinkList<T> : ICollection<T>
{
#region 属性
/// <summary>头部</summary>
public LinkNode<T> Head { get; private set; }

/// <summary>尾部</summary>
public LinkNode<T> Tail { get; private set; }

private Int32 _Count;
/// <summary>元素个数</summary>
public Int32 Count { get => _Count; private set => _Count = value; }

Boolean ICollection<T>.IsReadOnly => false;
#endregion

#region 方法
/// <summary>添加项</summary>
/// <param name="item"></param>
public void Add(T item)
{
var node = new LinkNode<T>(item);

if (Head == null)
Head = Tail = node;
else
node.InsertAfter(Tail);

Interlocked.Increment(ref _Count);
}

/// <summary>删除项</summary>
/// <param name="item"></param>
/// <returns></returns>
public Boolean Remove(T item)
{
for (var node = Head; node != null; node = node.Next)
{
if (Object.Equals(node.Value, item))
{
node.Remove();

Interlocked.Decrement(ref _Count);

return true;
}
}

return false;
}

/// <summary>清空链表</summary>
public void Clear()
{
Head = Tail = null;
_Count = 0;
}

/// <summary>是否包含</summary>
/// <param name="item"></param>
/// <returns></returns>
public Boolean Contains(T item)
{
for (var node = Head; node != null; node = node.Next)
{
if (Object.Equals(node.Value, item)) return true;
}

return false;
}

/// <summary>拷贝到数组</summary>
/// <param name="array"></param>
/// <param name="arrayIndex"></param>
public void CopyTo(T[] array, Int32 arrayIndex)
{
var k = 0;
for (var node = Head; node != null; node = node.Next, k++)
{
array[arrayIndex] = node.Value;
}
}

/// <summary>枚举</summary>
/// <returns></returns>
public IEnumerator<T> GetEnumerator()
{
for (var node = Head; node != null; node = node.Next)
{
yield return node.Value;
}
}

IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); }
#endregion
}
}
63 changes: 63 additions & 0 deletions NewLife.Core/Collections/LinkNode.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
using System;

namespace NewLife.Collections
{
/// <summary>双链表节点</summary>
/// <typeparam name="T"></typeparam>
public class LinkNode<T>
{
#region 属性
/// <summary>数值</summary>
public T Value { get; set; }

/// <summary>前一个</summary>
public LinkNode<T> Prev { get; set; }

/// <summary>下一个</summary>
public LinkNode<T> Next { get; set; }
#endregion

#region 构造
/// <summary>实例化一个双链表节点</summary>
public LinkNode() { }

/// <summary>实例化一个双链表节点</summary>
/// <param name="value"></param>
public LinkNode(T value) { Value = value; }
#endregion

#region 方法
/// <summary>在指定节点之后插入</summary>
/// <param name="after"></param>
public void InsertAfter(LinkNode<T> after)
{
Prev = after ?? throw new ArgumentNullException(nameof(after));
Next = after.Next;

after.Next = this;
if (Next != null) Next.Prev = this;
}

/// <summary>在指定节点之前插入</summary>
/// <param name="before"></param>
public void InsertBefore(LinkNode<T> before)
{
Next = before ?? throw new ArgumentNullException(nameof(before));
Prev = before.Prev;

before.Prev = this;
if (Prev != null) Prev.Next = this;
}

/// <summary>移除节点</summary>
public void Remove()
{
if (Prev != null) Prev.Next = Next;
if (Next != null) Next.Prev = Prev;

Prev = this;
Next = this;
}
#endregion
}
}
2 changes: 2 additions & 0 deletions NewLife.Core/NewLife.Core.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,8 @@
<Compile Include="Collections\CollectionHelper.cs" />
<Compile Include="Collections\ConcurrentHashSet.cs" />
<Compile Include="Collections\DictionaryCache.cs" />
<Compile Include="Collections\LinkNode.cs" />
<Compile Include="Collections\LinkList.cs" />
<Compile Include="Collections\NullableDictionary.cs" />
<Compile Include="Collections\Pool.cs" />
<Compile Include="Common\CombGuid.cs" />
Expand Down
34 changes: 24 additions & 10 deletions Test/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
using System.Threading.Tasks;
using NewLife.Agent;
using NewLife.Caching;
using NewLife.Collections;
using NewLife.Log;
using NewLife.Reflection;
using NewLife.Remoting;
Expand Down Expand Up @@ -147,17 +148,30 @@ static void Test2()
private static TimerX _timer;
static void Test3()
{
if (_timer == null) _timer = new TimerX(s =>
//if (_timer == null) _timer = new TimerX(s =>
//{
// Console.WriteLine();
// XTrace.WriteLine("start");
// Parallel.For(0, 3, k =>
// {
// Thread.Sleep(300);
// XTrace.WriteLine("pfor {0}", k);
// });
// XTrace.WriteLine("end");
//}, null, 1000, 5000);

var list = new LinkList<Int32>();
list.Add(123);
list.Add(456);
list.Add(789);

Console.WriteLine(list.Contains(456));
list.Remove(456);

foreach (var item in list)
{
Console.WriteLine();
XTrace.WriteLine("start");
Parallel.For(0, 3, k =>
{
Thread.Sleep(300);
XTrace.WriteLine("pfor {0}", k);
});
XTrace.WriteLine("end");
}, null, 1000, 5000);
Console.WriteLine(item);
}
}
}
}

0 comments on commit 4b21a7a

Please sign in to comment.