PageRenderTime 53ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 1ms

/Main/Source/Libraries/GSF.SortedTreeStore/Snap/Services/Configuration/AdvancedServerDatabaseConfig.cs

#
C# | 388 lines | 272 code | 34 blank | 82 comment | 10 complexity | 00c1d3f9182d9d74279ca2ba5fa4fd90 MD5 | raw file
Possible License(s): MPL-2.0-no-copyleft-exception, EPL-1.0
  1. //******************************************************************************************************
  2. // AdvancedServerDatabaseConfig.cs - Gbtc
  3. //
  4. // Copyright © 2014, Grid Protection Alliance. All Rights Reserved.
  5. //
  6. // Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See
  7. // the NOTICE file distributed with this work for additional information regarding copyright ownership.
  8. // The GPA licenses this file to you under the Eclipse Public License -v 1.0 (the "License"); you may
  9. // not use this file except in compliance with the License. You may obtain a copy of the License at:
  10. //
  11. // http://www.opensource.org/licenses/eclipse-1.0.php
  12. //
  13. // Unless agreed to in writing, the subject software distributed under the License is distributed on an
  14. // "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the
  15. // License for the specific language governing permissions and limitations.
  16. //
  17. // Code Modification History:
  18. // ----------------------------------------------------------------------------------------------------
  19. // 10/05/2014 - Steven E. Chisholm
  20. // Generated original version of source code.
  21. // 11/25/2014 - J. Ritchie Carroll
  22. // Updated final staging file name to use database name as prefix instead of "stage(n)".
  23. //
  24. //******************************************************************************************************
  25. using System;
  26. using System.Collections.Generic;
  27. using GSF.IO;
  28. using GSF.Snap.Services.Writer;
  29. using GSF.Snap.Storage;
  30. namespace GSF.Snap.Services.Configuration
  31. {
  32. /// <summary>
  33. /// Creates a configuration for the database to utilize.
  34. /// </summary>
  35. public class AdvancedServerDatabaseConfig<TKey, TValue>
  36. : IToServerDatabaseSettings
  37. where TKey : SnapTypeBase<TKey>, new()
  38. where TValue : SnapTypeBase<TValue>, new()
  39. {
  40. private bool m_supportsWriting;
  41. private string m_databaseName;
  42. private string m_mainPath;
  43. private string m_finalFileExtension;
  44. private string m_intermediateFileExtension;
  45. private List<string> m_importPaths;
  46. private List<string> m_finalWritePaths;
  47. private EncodingDefinition m_archiveEncodingMethod;
  48. private List<EncodingDefinition> m_streamingEncodingMethods;
  49. private long m_targetFileSize;
  50. private int m_stagingCount;
  51. private ArchiveDirectoryMethod m_directoryMethod;
  52. private int m_diskFlushInterval;
  53. private int m_cacheFlushInterval;
  54. /// <summary>
  55. /// Gets a database config.
  56. /// </summary>
  57. public AdvancedServerDatabaseConfig(string databaseName, string mainPath, bool supportsWriting)
  58. {
  59. m_supportsWriting = supportsWriting;
  60. m_databaseName = databaseName;
  61. m_mainPath = mainPath;
  62. m_intermediateFileExtension = ".d2i";
  63. m_finalFileExtension = ".d2";
  64. m_importPaths = new List<string>();
  65. m_finalWritePaths = new List<string>();
  66. m_archiveEncodingMethod = EncodingDefinition.FixedSizeCombinedEncoding;
  67. m_streamingEncodingMethods = new List<EncodingDefinition>();
  68. m_targetFileSize = 2 * 1024 * 1024 * 1024L;
  69. m_stagingCount = 3;
  70. m_directoryMethod = ArchiveDirectoryMethod.TopDirectoryOnly;
  71. m_diskFlushInterval = 10000;
  72. m_cacheFlushInterval = 100;
  73. }
  74. /// <summary>
  75. /// Gets the method of how the directory will be stored. Defaults to
  76. /// top directory only.
  77. /// </summary>
  78. public ArchiveDirectoryMethod DirectoryMethod
  79. {
  80. get
  81. {
  82. return m_directoryMethod;
  83. }
  84. set
  85. {
  86. m_directoryMethod = value;
  87. }
  88. }
  89. /// <summary>
  90. /// The name associated with the database.
  91. /// </summary>
  92. public string DatabaseName
  93. {
  94. get
  95. {
  96. return m_databaseName;
  97. }
  98. }
  99. /// <summary>
  100. /// The desired size of archive files
  101. /// </summary>
  102. public long TargetFileSize
  103. {
  104. get
  105. {
  106. return m_targetFileSize;
  107. }
  108. set
  109. {
  110. m_targetFileSize = value;
  111. }
  112. }
  113. /// <summary>
  114. /// The number of stages.
  115. /// </summary>
  116. public int StagingCount
  117. {
  118. get
  119. {
  120. return m_stagingCount;
  121. }
  122. set
  123. {
  124. m_stagingCount = value;
  125. }
  126. }
  127. /// <summary>
  128. /// The extension to use for the intermediate files
  129. /// </summary>
  130. public string IntermediateFileExtension
  131. {
  132. get
  133. {
  134. return m_intermediateFileExtension;
  135. }
  136. set
  137. {
  138. m_intermediateFileExtension = PathHelpers.FormatExtension(value);
  139. }
  140. }
  141. /// <summary>
  142. /// The extension to use for the final file
  143. /// </summary>
  144. public string FinalFileExtension
  145. {
  146. get
  147. {
  148. return m_finalFileExtension;
  149. }
  150. set
  151. {
  152. m_finalFileExtension = PathHelpers.FormatExtension(value);
  153. }
  154. }
  155. /// <summary>
  156. /// Gets all of the paths that are known by this historian.
  157. /// A path can be a file name or a folder.
  158. /// </summary>
  159. public List<string> ImportPaths
  160. {
  161. get
  162. {
  163. return m_importPaths;
  164. }
  165. }
  166. /// <summary>
  167. /// The list of directories where final files can be placed written.
  168. /// If nothing is specified, the main directory is used.
  169. /// </summary>
  170. public List<string> FinalWritePaths
  171. {
  172. get
  173. {
  174. return m_finalWritePaths;
  175. }
  176. }
  177. /// <summary>
  178. /// Gets the default encoding methods for storing files.
  179. /// </summary>
  180. public EncodingDefinition ArchiveEncodingMethod
  181. {
  182. get
  183. {
  184. return m_archiveEncodingMethod;
  185. }
  186. set
  187. {
  188. m_archiveEncodingMethod = value;
  189. }
  190. }
  191. /// <summary>
  192. /// Gets the supported encoding methods for streaming data. This list is in a prioritized order.
  193. /// </summary>
  194. public List<EncodingDefinition> StreamingEncodingMethods
  195. {
  196. get
  197. {
  198. return m_streamingEncodingMethods;
  199. }
  200. }
  201. /// <summary>
  202. /// Gets if writing will be supported
  203. /// </summary>
  204. public bool SupportsWriting
  205. {
  206. get
  207. {
  208. return m_supportsWriting;
  209. }
  210. }
  211. /// <summary>
  212. /// The number of milliseconds before data is automatically flushed to the disk.
  213. /// </summary>
  214. /// <remarks>
  215. /// Must be between 1,000 ms and 60,000 ms.
  216. /// </remarks>
  217. public int DiskFlushInterval
  218. {
  219. get
  220. {
  221. return m_diskFlushInterval;
  222. }
  223. set
  224. {
  225. m_diskFlushInterval = value;
  226. }
  227. }
  228. /// <summary>
  229. /// The number of milliseconds before data is taken from it's cache and put in the
  230. /// memory file.
  231. /// </summary>
  232. /// <remarks>
  233. /// Must be between 1 and 1,000
  234. /// </remarks>
  235. public int CacheFlushInterval
  236. {
  237. get
  238. {
  239. return m_cacheFlushInterval;
  240. }
  241. set
  242. {
  243. m_cacheFlushInterval = value;
  244. }
  245. }
  246. #region [ IToServerDatabaseSettings ]
  247. public ServerDatabaseSettings ToServerDatabaseSettings()
  248. {
  249. var settings = new ServerDatabaseSettings();
  250. settings.DatabaseName = m_databaseName;
  251. if (m_supportsWriting)
  252. ToWriteProcessorSettings(settings.WriteProcessor);
  253. settings.SupportsWriting = m_supportsWriting;
  254. ToArchiveListSettings(settings.ArchiveList);
  255. settings.RolloverLog.LogPath = m_mainPath;
  256. settings.KeyType = new TKey().GenericTypeGuid;
  257. settings.ValueType = new TValue().GenericTypeGuid;
  258. if (m_streamingEncodingMethods.Count == 0)
  259. {
  260. settings.StreamingEncodingMethods.Add(EncodingDefinition.FixedSizeCombinedEncoding);
  261. }
  262. else
  263. {
  264. settings.StreamingEncodingMethods.AddRange(m_streamingEncodingMethods);
  265. }
  266. return settings;
  267. }
  268. private void ToWriteProcessorSettings(WriteProcessorSettings settings)
  269. {
  270. string intermediateFilePendingExtension;
  271. string intermediateFileFinalExtension;
  272. string finalFilePendingExtension;
  273. string finalFileFinalExtension;
  274. ValidateExtension(IntermediateFileExtension, out intermediateFilePendingExtension, out intermediateFileFinalExtension);
  275. ValidateExtension(FinalFileExtension, out finalFilePendingExtension, out finalFileFinalExtension);
  276. if (m_supportsWriting)
  277. {
  278. List<string> finalPaths = new List<string>();
  279. if (FinalWritePaths.Count > 0)
  280. {
  281. finalPaths.AddRange(FinalWritePaths);
  282. }
  283. else
  284. {
  285. finalPaths.Add(m_mainPath);
  286. }
  287. settings.IsEnabled = true;
  288. //0.1 seconds
  289. settings.PrebufferWriter.RolloverInterval = m_cacheFlushInterval;
  290. settings.PrebufferWriter.MaximumPointCount = 25000;
  291. settings.PrebufferWriter.RolloverPointCount = 25000;
  292. //10 seconds
  293. settings.FirstStageWriter.MaximumAllowedMb = 100; //about 10 million points
  294. settings.FirstStageWriter.RolloverSizeMb = 100; //about 10 million points
  295. settings.FirstStageWriter.RolloverInterval = m_diskFlushInterval; //10 seconds
  296. settings.FirstStageWriter.EncodingMethod = ArchiveEncodingMethod;
  297. settings.FirstStageWriter.FinalSettings.ConfigureOnDisk(new string[] { m_mainPath }, 1024 * 1024 * 1024, ArchiveDirectoryMethod.TopDirectoryOnly, ArchiveEncodingMethod, "stage1", intermediateFilePendingExtension, intermediateFileFinalExtension, FileFlags.Stage1, FileFlags.IntermediateFile);
  298. for (int stage = 2; stage <= StagingCount; stage++)
  299. {
  300. int remainingStages = StagingCount - stage;
  301. var rollover = new CombineFilesSettings();
  302. if (remainingStages > 0)
  303. {
  304. rollover.ArchiveSettings.ConfigureOnDisk(new string[] { m_mainPath }, 1024 * 1024 * 1024,
  305. ArchiveDirectoryMethod.TopDirectoryOnly, ArchiveEncodingMethod, "stage" + stage,
  306. intermediateFilePendingExtension, intermediateFileFinalExtension, FileFlags.GetStage(stage), FileFlags.IntermediateFile);
  307. }
  308. else
  309. {
  310. //Final staging file
  311. rollover.ArchiveSettings.ConfigureOnDisk(finalPaths, 5 * 1024L * 1024 * 1024,
  312. m_directoryMethod, ArchiveEncodingMethod, m_databaseName.ToNonNullNorEmptyString("stage" + stage).RemoveInvalidFileNameCharacters(),
  313. finalFilePendingExtension, finalFileFinalExtension, FileFlags.GetStage(stage));
  314. }
  315. rollover.LogPath = m_mainPath;
  316. rollover.ExecuteTimer = 1000;
  317. rollover.CombineOnFileCount = 60;
  318. rollover.CombineOnFileSize = m_targetFileSize / (long)Math.Pow(30, remainingStages);
  319. rollover.MatchFlag = FileFlags.GetStage(stage - 1);
  320. settings.StagingRollovers.Add(rollover);
  321. }
  322. }
  323. }
  324. private void ToArchiveListSettings(ArchiveListSettings listSettings)
  325. {
  326. string intermediateFilePendingExtension;
  327. string intermediateFileFinalExtension;
  328. string finalFilePendingExtension;
  329. string finalFileFinalExtension;
  330. ValidateExtension(IntermediateFileExtension, out intermediateFilePendingExtension, out intermediateFileFinalExtension);
  331. ValidateExtension(FinalFileExtension, out finalFilePendingExtension, out finalFileFinalExtension);
  332. listSettings.AddExtension(intermediateFileFinalExtension);
  333. listSettings.AddExtension(finalFileFinalExtension);
  334. if (!string.IsNullOrWhiteSpace(m_mainPath))
  335. listSettings.AddPath(m_mainPath);
  336. listSettings.AddPaths(ImportPaths);
  337. listSettings.AddPaths(FinalWritePaths);
  338. listSettings.LogSettings.LogPath = m_mainPath;
  339. }
  340. private static void ValidateExtension(string extension, out string pending, out string final)
  341. {
  342. if (string.IsNullOrWhiteSpace(extension))
  343. throw new ArgumentException("Cannot be null or whitespace", "extension");
  344. extension = extension.Trim();
  345. if (extension.Contains("."))
  346. {
  347. extension = extension.Substring(extension.IndexOf('.') + 1);
  348. }
  349. pending = ".~" + extension;
  350. final = "." + extension;
  351. }
  352. #endregion
  353. }
  354. }