Skip to content

Commit 82d4613

Browse files
authored
Merge pull request #290 from DataObjects-NET/master-shared-cache
Shared query cache for storage nodes
2 parents d1e4da8 + 3631e02 commit 82d4613

File tree

3 files changed

+159
-1
lines changed

3 files changed

+159
-1
lines changed

ChangeLog/7.1.0-Beta-2-dev.txt

+1
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
[main] IgnoreRule supports indexes
2424
[main] Queries use parameters instead of constant values for type indentifiers within columns list
2525
[main] Added DomainConfiguration.PreferTypeIdsAsQueryParameters to choose between contants and parameters for TypeIds
26+
[main] ShareStorageSchemaOverNodes option now includes shared query cache when TypeIds as paremters are prefered
2627
[main] BitFaster.Caching package reference is updated to 1.0.7
2728
[main] No error caused by ambiguity due to new IQueryable extension methods of .Net 6
2829
[reprocessing] DomainBuildErrorEventArgs (not sealed) became read-only structure
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
// Copyright (C) 2022 Xtensive LLC.
2+
// This code is distributed under MIT license terms.
3+
// See the License.txt file in the project root for more information.
4+
5+
using NUnit.Framework;
6+
using Xtensive.Orm.Configuration;
7+
using Xtensive.Orm.Tests.Storage.SchemaSharing.SharedCacheTestModel;
8+
9+
namespace Xtensive.Orm.Tests.Storage.SchemaSharing.SharedCacheTestModel
10+
{
11+
[HierarchyRoot]
12+
public class TestEntity : Entity
13+
{
14+
[Field, Key]
15+
public int Id { get; private set; }
16+
17+
[Field(Length = 50)]
18+
public string StorageNodeMark { get; private set; }
19+
20+
public TestEntity(Session session)
21+
: base(session)
22+
{
23+
StorageNodeMark = Session.StorageNodeId;
24+
}
25+
}
26+
}
27+
28+
namespace Xtensive.Orm.Tests.Storage.SchemaSharing
29+
{
30+
[TestFixture]
31+
public class SharedCacheTest
32+
{
33+
private const string AdditionalNodeId = "Addtional";
34+
private const int DefaultNodeEntityCount = 3;
35+
private const int AdditionalNodeEntityCount = 5;
36+
37+
private string additionalNodeSchema;
38+
private string defaultSchema;
39+
40+
41+
[OneTimeSetUp]
42+
public void OneTimeSetup()
43+
{
44+
Require.AnyFeatureSupported(Orm.Providers.ProviderFeatures.Multischema);
45+
46+
defaultSchema = StorageProviderInfo.Instance.CheckProviderIs(StorageProvider.PostgreSql)
47+
? WellKnownSchemas.PgSqlDefalutSchema
48+
: WellKnownSchemas.SqlServerDefaultSchema;
49+
additionalNodeSchema = WellKnownSchemas.Schema1;
50+
}
51+
52+
[Test]
53+
[TestCase(true, true, 4, TestName = "SharedCacheOn")]
54+
[TestCase(true, false, 4 * 2, TestName = "OnlyParameters")]
55+
[TestCase(false, true, 4 * 2, TestName = "OnlySharedSchema")]
56+
public void MainTest(bool preferParameter, bool sharedSchame, int expectedCacheItems)
57+
{
58+
using (var domain = Domain.Build(BuildDomainConfiguration(preferParameter, sharedSchame))) {
59+
_ = domain.StorageNodeManager.AddNode(BuildNodeConfiguration());
60+
61+
PopulateDefaultNode(domain);
62+
PopilateAdditionalNode(domain);
63+
64+
RunQueries(domain.StorageNodeManager.GetNode(WellKnown.DefaultNodeId), DefaultNodeEntityCount);
65+
RunQueries(domain.StorageNodeManager.GetNode(AdditionalNodeId), AdditionalNodeEntityCount);
66+
67+
Assert.That(domain.QueryCache.Count, Is.EqualTo(expectedCacheItems));
68+
}
69+
}
70+
71+
private void RunQueries(StorageNode node, int expectedCount)
72+
{
73+
using (var session = node.OpenSession())
74+
using (var tx = session.OpenTransaction()) {
75+
76+
//method as key for cache
77+
var results = session.Query.Execute(q => q.All<TestEntity>());
78+
var rowCount = 0;
79+
foreach (var result in results) {
80+
Assert.That(result.StorageNodeMark, Is.EqualTo(node.Id));
81+
rowCount++;
82+
}
83+
Assert.That(rowCount, Is.EqualTo(expectedCount));
84+
85+
var delayedResults = session.Query.CreateDelayedQuery(q => q.All<TestEntity>());
86+
rowCount = 0;
87+
foreach (var result in delayedResults) {
88+
Assert.That(result.StorageNodeMark, Is.EqualTo(node.Id));
89+
rowCount++;
90+
}
91+
Assert.That(rowCount, Is.EqualTo(expectedCount));
92+
93+
// custom keys
94+
results = session.Query.Execute("fancyCustomKeyExec", q => q.All<TestEntity>());
95+
rowCount = 0;
96+
foreach (var result in results) {
97+
Assert.That(result.StorageNodeMark, Is.EqualTo(node.Id));
98+
rowCount++;
99+
}
100+
Assert.That(rowCount, Is.EqualTo(expectedCount));
101+
102+
delayedResults = session.Query.CreateDelayedQuery("fancyCustomKeyDelayed", q => q.All<TestEntity>());
103+
rowCount = 0;
104+
foreach (var result in delayedResults) {
105+
Assert.That(result.StorageNodeMark, Is.EqualTo(node.Id));
106+
rowCount++;
107+
}
108+
Assert.That(rowCount, Is.EqualTo(expectedCount));
109+
tx.Complete();
110+
}
111+
}
112+
113+
private static void PopulateDefaultNode(Domain domain) =>
114+
PopulateNode(domain.StorageNodeManager.GetNode(WellKnown.DefaultNodeId), DefaultNodeEntityCount);
115+
116+
private static void PopilateAdditionalNode(Domain domain) =>
117+
PopulateNode(domain.StorageNodeManager.GetNode(AdditionalNodeId), AdditionalNodeEntityCount);
118+
119+
private static void PopulateNode(StorageNode node, int itemCount)
120+
{
121+
using (var session = node.OpenSession())
122+
using (var tx = session.OpenTransaction()) {
123+
for(var i = 0; i < itemCount; i++) {
124+
_ = new TestEntity(session);
125+
}
126+
tx.Complete();
127+
}
128+
}
129+
130+
private DomainConfiguration BuildDomainConfiguration(bool preferParamters, bool shareSchema)
131+
{
132+
var domainConfig = DomainConfigurationFactory.Create();
133+
domainConfig.Types.Register(typeof(TestEntity));
134+
domainConfig.UpgradeMode = DomainUpgradeMode.Recreate;
135+
domainConfig.DefaultSchema = defaultSchema;
136+
137+
domainConfig.PreferTypeIdsAsQueryParameters = preferParamters;
138+
domainConfig.ShareStorageSchemaOverNodes = shareSchema;
139+
140+
return domainConfig;
141+
}
142+
143+
private NodeConfiguration BuildNodeConfiguration()
144+
{
145+
var nodeConfig = new NodeConfiguration(AdditionalNodeId) {
146+
UpgradeMode = DomainUpgradeMode.Recreate
147+
};
148+
nodeConfig.SchemaMapping.Add(defaultSchema, additionalNodeSchema);
149+
150+
return nodeConfig;
151+
}
152+
}
153+
}

Orm/Xtensive.Orm/Orm/Internals/CompiledQueryRunner.cs

+5-1
Original file line numberDiff line numberDiff line change
@@ -221,9 +221,13 @@ public CompiledQueryRunner(QueryEndpoint endpoint, object queryKey, object query
221221
domain = session.Domain;
222222

223223
this.endpoint = endpoint;
224-
this.queryKey = new Pair<object, string>(queryKey, session.StorageNodeId);
225224
this.queryTarget = queryTarget;
226225
this.outerContext = outerContext;
226+
227+
var domainConfig = domain.Configuration;
228+
this.queryKey = domainConfig.ShareStorageSchemaOverNodes && domainConfig.PreferTypeIdsAsQueryParameters
229+
? queryKey
230+
: new Pair<object, string>(queryKey, session.StorageNodeId);
227231
}
228232
}
229233
}

0 commit comments

Comments
 (0)