using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
namespace Core.Util
{
public class ParentChildrenMapping
{
#region 私有成员
private ConcurrentDictionary<string, string> _cToP { get; } = new ConcurrentDictionary<string, string>();
private ConcurrentDictionary<string, ConcurrentBag<string>> _pToC { get; } = new ConcurrentDictionary<string, ConcurrentBag<string>>();
#endregion
#region 外部接口
public void AddChild(string parentId,string childId)
{
if (string.IsNullOrEmpty(parentId))
throw new Exception("父键不能为Null或空");
if(string.IsNullOrEmpty(childId))
throw new Exception("子键不能为Null或空");
if (_cToP.ContainsKey(childId))
throw new Exception("该子键已存在!");
ConcurrentBag<string> children = null;
if (!_pToC.ContainsKey(parentId))
{
children = new ConcurrentBag<string>();
_pToC[parentId] = children;
}
else
children = _pToC[parentId];
children.Add(childId);
_cToP[childId] = parentId;
}
public void RemoveChild(string parentId, string childId)
{
if (string.IsNullOrEmpty(parentId))
throw new Exception("父键不能为Null或空");
if (string.IsNullOrEmpty(childId))
throw new Exception("子键不能为Null或空");
if (!_pToC.ContainsKey(parentId))
throw new Exception("该父键不存在");
if (!_cToP.ContainsKey(childId))
throw new Exception("该子键不存在");
var children = _pToC[parentId];
if (children == null)
throw new Exception("该父键不存在该子键");
if(!children.TryTake(out childId))
throw new Exception("该父键不存在该子键");
_cToP.TryRemove(childId, out string value);
}
public void RemoveParent(string parentId)
{
if (string.IsNullOrEmpty(parentId))
throw new Exception("父键不能为Null或空");
if (!_pToC.ContainsKey(parentId))
throw new Exception("父键不存在");
_pToC.TryRemove(parentId, out ConcurrentBag<string> children);
if (children != null)
{
var enumerator = children.GetEnumerator();
do
{
_cToP.TryRemove(enumerator.Current, out string value);
} while (enumerator.MoveNext());
}
}
public bool ExistsParent(string parentId)
{
if (string.IsNullOrEmpty(parentId))
throw new Exception("父键不能为Null或空");
return _pToC.ContainsKey(parentId);
}
public bool ExistsChild(string childId)
{
if (string.IsNullOrEmpty(childId))
throw new Exception("子键不能为Null或空");
return _cToP.ContainsKey(childId);
}
public List<string> GetChildren(string parentId)
{
if (string.IsNullOrEmpty(parentId))
throw new Exception("父键不能为Null或空");
if (!_pToC.ContainsKey(parentId))
throw new Exception("父键不存在");
return _pToC[parentId]?.ToList() ?? new List<string>();
}
public List<string> GetAllParents()
{
return _pToC.Keys.ToList();
}
public List<string> GetAllChildren()
{
return _cToP.Keys.ToList();
}
public string GetParent(string childId)
{
if (string.IsNullOrEmpty(childId))
throw new Exception("子键不能为Null或空");
if (!_cToP.ContainsKey(childId))
throw new Exception("该子键不存在");
return _cToP[childId];
}
#endregion
}
}