KernelOutputKeywordSet.cs 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. using LiteDB;
  2. using NTMiner.Core;
  3. using System;
  4. using System.Collections;
  5. using System.Collections.Generic;
  6. using System.Linq;
  7. namespace NTMiner.KernelOutputKeyword {
  8. public class KernelOutputKeywordSet : IKernelOutputKeywordSet {
  9. private readonly Dictionary<Guid, KernelOutputKeywordData> _dicById = new Dictionary<Guid, KernelOutputKeywordData>();
  10. private readonly string _connectionString;
  11. public KernelOutputKeywordSet(string dbFileFullName, bool isServer) {
  12. if (!string.IsNullOrEmpty(dbFileFullName)) {
  13. _connectionString = $"filename={dbFileFullName};journal=false";
  14. }
  15. if (!isServer) {
  16. VirtualRoot.BuildCmdPath<LoadKernelOutputKeywordCommand>(action: message => {
  17. if (!VirtualRoot.IsKernelOutputKeywordVisible) {
  18. return;
  19. }
  20. DateTime localTimestamp = VirtualRoot.LocalKernelOutputKeywordSetTimestamp;
  21. // 如果已知服务器端最新内核输出关键字时间戳不比本地已加载的最新内核输出关键字时间戳新就不用加载了
  22. if (message.KnowKernelOutputKeywordTimestamp <= Timestamp.GetTimestamp(localTimestamp)) {
  23. return;
  24. }
  25. OfficialServer.KernelOutputKeywordService.GetKernelOutputKeywords((response, e) => {
  26. if (response.IsSuccess()) {
  27. Guid[] toRemoves = _dicById.Where(a => a.Value.DataLevel == DataLevel.Global).Select(a => a.Key).ToArray();
  28. foreach (var id in toRemoves) {
  29. _dicById.Remove(id);
  30. }
  31. DateTime maxTime = localTimestamp;
  32. if (response.Data.Count != 0) {
  33. foreach (var item in response.Data) {
  34. if (item.Timestamp > maxTime) {
  35. maxTime = item.Timestamp;
  36. }
  37. item.SetDataLevel(DataLevel.Global);
  38. _dicById.Add(item.Id, item);
  39. }
  40. if (maxTime != localTimestamp) {
  41. VirtualRoot.LocalKernelOutputKeywordSetTimestamp = maxTime;
  42. }
  43. VirtualRoot.RaiseEvent(new KernelOutputKeywordLoadedEvent(response.Data));
  44. }
  45. }
  46. });
  47. });
  48. }
  49. VirtualRoot.BuildCmdPath<AddOrUpdateKernelOutputKeywordCommand>(action: (message) => {
  50. InitOnece();
  51. if (message == null || message.Input == null || message.Input.GetId() == Guid.Empty) {
  52. throw new ArgumentNullException();
  53. }
  54. if (string.IsNullOrEmpty(message.Input.MessageType)) {
  55. throw new ValidationException("MessageType can't be null or empty");
  56. }
  57. if (string.IsNullOrEmpty(message.Input.Keyword)) {
  58. throw new ValidationException("Keyword can't be null or empty");
  59. }
  60. if (_dicById.Values.Any(a => a.KernelOutputId == message.Input.KernelOutputId && a.Keyword == message.Input.Keyword && a.Id != message.Input.GetId())) {
  61. throw new ValidationException($"关键字{message.Input.Keyword}已存在");
  62. }
  63. if (_dicById.TryGetValue(message.Input.GetId(), out KernelOutputKeywordData exist)) {
  64. exist.Update(message.Input);
  65. using (LiteDatabase db = new LiteDatabase(_connectionString)) {
  66. var col = db.GetCollection<KernelOutputKeywordData>();
  67. col.Update(exist);
  68. }
  69. }
  70. else {
  71. KernelOutputKeywordData entity = new KernelOutputKeywordData().Update(message.Input);
  72. _dicById.Add(entity.Id, entity);
  73. using (LiteDatabase db = new LiteDatabase(_connectionString)) {
  74. var col = db.GetCollection<KernelOutputKeywordData>();
  75. col.Insert(entity);
  76. }
  77. }
  78. });
  79. VirtualRoot.BuildCmdPath<RemoveKernelOutputKeywordCommand>(action: (message) => {
  80. InitOnece();
  81. if (message == null || message.EntityId == Guid.Empty) {
  82. throw new ArgumentNullException();
  83. }
  84. if (!_dicById.ContainsKey(message.EntityId)) {
  85. return;
  86. }
  87. KernelOutputKeywordData entity = _dicById[message.EntityId];
  88. _dicById.Remove(entity.GetId());
  89. using (LiteDatabase db = new LiteDatabase(_connectionString)) {
  90. var col = db.GetCollection<KernelOutputKeywordData>();
  91. col.Delete(message.EntityId);
  92. }
  93. });
  94. }
  95. private bool _isInited = false;
  96. private readonly object _locker = new object();
  97. private void InitOnece() {
  98. if (_isInited) {
  99. return;
  100. }
  101. Init();
  102. }
  103. private void Init() {
  104. lock (_locker) {
  105. if (!_isInited) {
  106. using (LiteDatabase db = new LiteDatabase(_connectionString)) {
  107. var col = db.GetCollection<KernelOutputKeywordData>();
  108. foreach (var item in col.FindAll()) {
  109. if (!_dicById.ContainsKey(item.GetId())) {
  110. item.SetDataLevel(DataLevel.Profile);
  111. _dicById.Add(item.GetId(), item);
  112. }
  113. }
  114. }
  115. _isInited = true;
  116. }
  117. }
  118. }
  119. public IEnumerable<IKernelOutputKeyword> GetKeywords(Guid kernelOutputId) {
  120. InitOnece();
  121. return _dicById.Values.Where(a => a.KernelOutputId == kernelOutputId);
  122. }
  123. public bool Contains(Guid kernelOutputId, string keyword) {
  124. InitOnece();
  125. return _dicById.Values.Any(a => a.KernelOutputId == kernelOutputId && a.Keyword == keyword);
  126. }
  127. public bool TryGetKernelOutputKeyword(Guid id, out IKernelOutputKeyword keyword) {
  128. InitOnece();
  129. var result = _dicById.TryGetValue(id, out KernelOutputKeywordData data);
  130. keyword = data;
  131. return result;
  132. }
  133. public IEnumerator<IKernelOutputKeyword> GetEnumerator() {
  134. InitOnece();
  135. return _dicById.Values.GetEnumerator();
  136. }
  137. IEnumerator IEnumerable.GetEnumerator() {
  138. InitOnece();
  139. return _dicById.Values.GetEnumerator();
  140. }
  141. }
  142. }