1 #Region "Microsoft.VisualBasic::001b8cce47ecce5f7b8273fbd965f952, Microsoft.VisualBasic.Core\ComponentModel\DataSource\Repository\QueryCache.vb"
2
3     ' Author:
4     
5     '       asuka (amethyst.asuka@gcmodeller.org)
6     '       xie (genetics@smrucc.org)
7     '       xieguigang (xie.guigang@live.com)
8     
9     ' Copyright (c) 2018 GPL3 Licensed
10     
11     
12     ' GNU GENERAL PUBLIC LICENSE (GPL3)
13     
14     
15     ' This program is free software: you can redistribute it and/or modify
16     ' it under the terms of the GNU General Public License as published by
17     ' the Free Software Foundation, either version 3 of the License, or
18     ' (at your option) any later version.
19     
20     ' This program is distributed in the hope that it will be useful,
21     ' but WITHOUT ANY WARRANTY; without even the implied warranty of
22     ' MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23     ' GNU General Public License for more details.
24     
25     ' You should have received a copy of the GNU General Public License
26     ' along with this program. If not, see <http://www.gnu.org/licenses/>.
27
28
29
30     ' /********************************************************************************/
31
32     ' Summaries:
33
34     '     Class QueryCacheFactory
35     
36     '         Constructor: (+1 OverloadsSub New
37     
38     '         Function: Exists, GetAll, GetByKey, GetWhere, ToString
39     
40     '         Sub: Clear
41     
42     
43     ' /********************************************************************************/
44
45 #End Region
46
47 Imports System.Runtime.CompilerServices
48 Imports Microsoft.VisualBasic.Language
49 Imports Microsoft.VisualBasic.Language.Default
50 Imports Microsoft.VisualBasic.Linq
51
52 Namespace ComponentModel.DataSourceModel.Repository
53
54     ''' <summary>
55     ''' 这个库检索模型仅建议在目标数据量非常巨大的时候使用,如果数据量比较小,可以直接保存在一个文件之中,然后一次性加载在内存之中来进行查找
56     ''' </summary>
57     ''' <typeparam name="T"></typeparam>
58     Public MustInherit Class QueryCacheFactory(Of T As IKeyedEntity(Of String))
59         Implements IRepositoryRead(Of String, T)
60
61         Dim cache As New Dictionary(Of String, T)
62         Dim factory As Func(Of String, T)
63         Dim assertIsNothing As Assert(Of Object)
64
65         ''' <summary>
66         ''' 
67         ''' </summary>
68         ''' <param name="factory"></param>
69         ''' <param name="cache"></param>
70         ''' <param name="assertIsNothing">如果这个函数返回的结果是True,说明目标为空值,这个主要是针对于structure类型而言的</param>
71         Sub New(factory As Func(Of String, T), Optional cache As IReadOnlyDictionary(Of String, T) = NothingOptional assertIsNothing As Assert(Of Object) = Nothing)
72             Me.factory = factory
73             Me.cache = cache.SafeQuery.ToDictionary
74             Me.assertIsNothing = assertIsNothing Or defaultAssert
75         End Sub
76
77         <MethodImpl(MethodImplOptions.AggressiveInlining)>
78         Public Overrides Function ToString() As String
79             Return $"{cache.Count} entity was cached. (keys={cache.Keys.Take(5).JoinBy("")}...)"
80         End Function
81
82         ''' <summary>
83         ''' Clear the cache memory
84         ''' </summary>
85         ''' 
86         <MethodImpl(MethodImplOptions.AggressiveInlining)>
87         Public Overridable Sub Clear()
88             Call cache.Clear()
89         End Sub
90
91         Public Overridable Function Exists(key As StringAs Boolean Implements IRepositoryRead(Of String, T).Exists
92             If cache.ContainsKey(key) Then
93                 Return True
94             Else
95                 Return Not assertIsNothing(GetByKey(key))
96             End If
97         End Function
98
99         ''' <summary>
100         ''' Load by <see cref="factory"/> or read from <see cref="cache"/>.
101         ''' </summary>
102         ''' <param name="key"></param>
103         ''' <returns></returns>
104         Public Overridable Function GetByKey(key As StringAs T Implements IRepositoryRead(Of String, T).GetByKey
105             If cache.ContainsKey(key) Then
106                 ' hit in cache
107                 Return cache(key)
108             Else
109                 Dim entity As T = factory(key)
110
111                 If assertIsNothing(entity) = True Then
112                     Return Nothing
113                 Else
114                     cache.Add(entity.Key, entity)
115                 End If
116
117                 Return entity
118             End If
119         End Function
120
121         ''' <summary>
122         ''' Only works on cache
123         ''' </summary>
124         ''' <param name="clause"></param>
125         ''' <returns></returns>
126         Public Overridable Function GetWhere(clause As Func(Of T, Boolean)) As IReadOnlyDictionary(Of String, T) Implements IRepositoryRead(Of String, T).GetWhere
127             Return cache.Values.Where(clause).ToDictionary(Function(t) t.Key)
128         End Function
129
130         ''' <summary>
131         ''' Only works on cache
132         ''' </summary>
133         ''' <returns></returns>
134         Public Overridable Function GetAll() As IReadOnlyDictionary(Of String, T) Implements IRepositoryRead(Of String, T).GetAll
135             Return New Dictionary(Of String, T)(cache)
136         End Function
137     End Class
138 End Namespace