Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.CEDMA.DB/3.3/Store.cs @ 2188

Last change on this file since 2188 was 2149, checked in by gkronber, 15 years ago

Fixed a bug where in-memory rdf-cache was not invalidated. #696 (Cached RDF store is not invalidated when new statements are added to the sqlite-backed store (on disc))

File size: 8.6 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2008 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
4 *
5 * This file is part of HeuristicLab.
6 *
7 * HeuristicLab is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * HeuristicLab is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
19 */
20#endregion
21
22using System;
23using System.Collections.Generic;
24using System.Linq;
25using System.Text;
26using System.Data.Linq;
27using HeuristicLab.CEDMA.DB.Interfaces;
28using System.ServiceModel;
29using System.Data;
30using System.Data.Common;
31using System.Threading;
32using HeuristicLab.Data;
33using HeuristicLab.Core;
34using System.Xml;
35using System.IO;
36
37namespace HeuristicLab.CEDMA.DB {
38  [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, ConcurrencyMode = ConcurrencyMode.Multiple, UseSynchronizationContext = false)]
39  public class Store : IStore {
40    private string connectionString;
41    private SemWeb.Store store;
42    private object bigLock = new object();
43    private SemWeb.Store cachedStore;
44
45    public Store(string connectionString) {
46      lock (bigLock) {
47        this.connectionString = connectionString;
48        store = SemWeb.Store.Create(connectionString);
49        InitStore();
50      }
51    }
52
53    private void InitStore() {
54      foreach (Statement s in Ontology.InitialStatements) {
55        Add(s);
56      }
57    }
58
59    public void Add(Statement statement) {
60      lock (bigLock) {
61        store.Add(Translate(statement));
62        InvalidateCachedStore();
63      }
64    }
65
66    public void AddRange(ICollection<Statement> statements) {
67      lock (bigLock) {
68        foreach (Statement s in statements) {
69          store.Add(Translate(s));
70        }
71        InvalidateCachedStore();
72      }
73    }
74
75
76    public ICollection<VariableBindings> Query(string query, int page, int pageSize) {
77      lock (bigLock) {
78        MyQueryResultSink resultSink = new MyQueryResultSink();
79        SemWeb.N3Reader n3Reader = new SemWeb.N3Reader(new StringReader(query));
80        SemWeb.Query.GraphMatch matcher = new SemWeb.Query.GraphMatch(n3Reader);
81        if (cachedStore == null) {
82          CacheStore();
83        }
84        matcher.Run(cachedStore, resultSink);
85        return resultSink.Bindings.Skip(page * pageSize).Take(pageSize).ToList();
86      }
87    }
88
89    private void CacheStore() {
90      cachedStore = new SemWeb.MemoryStore();
91      cachedStore.Import(store);
92    }
93
94    private void InvalidateCachedStore() {
95      if (cachedStore != null) {
96        cachedStore.Dispose();
97        cachedStore = null;
98      }
99    }
100
101
102    public ICollection<VariableBindings> Query(ICollection<Statement> query, int page, int pageSize) {
103      lock (bigLock) {
104        MyQueryResultSink resultSink = new MyQueryResultSink();
105        if (cachedStore == null) {
106          CacheStore();
107        }
108        Translate(query).Run(cachedStore, resultSink);
109        return resultSink.Bindings.Skip(page * pageSize).Take(pageSize).ToList();
110      }
111    }
112
113    private SemWeb.Query.Query Translate(ICollection<Statement> query) {
114      Dictionary<object, object> translatedObjects = new Dictionary<object, object>();
115      SemWeb.MemoryStore queryStore = new SemWeb.MemoryStore(query.Select(st => Translate(st, translatedObjects)).ToArray());
116
117      return new SemWeb.Query.GraphMatch(queryStore);
118    }
119
120    private static SemWeb.Entity Translate(Entity e) {
121      return e.Uri == null ? null : new SemWeb.Entity(e.Uri);
122    }
123
124    private static SemWeb.Resource Translate(Resource prop) {
125      if (prop is Literal) {
126        return TranslateLiteral((Literal)prop);
127      } else if (prop is SerializedLiteral) {
128        return TranslateLiteral((SerializedLiteral)prop);
129      } else {
130        return Translate((Entity)prop);
131      }
132    }
133
134    private static Statement Translate(SemWeb.Statement statement) {
135      return Translate(statement, new Dictionary<object, object>());
136    }
137
138    private static Statement Translate(SemWeb.Statement statement, Dictionary<object, object> translatedObjects) {
139      if (!translatedObjects.ContainsKey(statement.Subject)) {
140        translatedObjects[statement.Subject] = new Entity(statement.Subject.Uri);
141      }
142      if (!translatedObjects.ContainsKey(statement.Predicate)) {
143        translatedObjects[statement.Predicate] = new Entity(statement.Predicate.Uri);
144      }
145      if (!translatedObjects.ContainsKey(statement.Object)) {
146        if (statement.Object is SemWeb.Literal) {
147          translatedObjects[statement.Object] = TranslateLiteral((SemWeb.Literal)statement.Object);
148        } else {
149          translatedObjects[statement.Object] = new Entity(((SemWeb.Entity)statement.Object).Uri);
150        }
151      }
152
153      Entity subjectEntity = (Entity)translatedObjects[statement.Subject];
154      Entity predicateEntity = (Entity)translatedObjects[statement.Predicate];
155      Resource property = (Resource)translatedObjects[statement.Object];
156
157      return new Statement(
158        subjectEntity,
159        predicateEntity,
160        property);
161    }
162
163    private static SemWeb.Statement Translate(Statement statement) {
164      return Translate(statement, new Dictionary<object, object>());
165    }
166
167    private static SemWeb.Statement Translate(Statement statement, Dictionary<object, object> translatedObjects) {
168      if (!translatedObjects.ContainsKey(statement.Subject)) {
169        translatedObjects[statement.Subject] = Translate(statement.Subject);
170      }
171      if (!translatedObjects.ContainsKey(statement.Predicate)) {
172        translatedObjects[statement.Predicate] = Translate(statement.Predicate);
173      }
174      if (!translatedObjects.ContainsKey(statement.Property)) {
175        translatedObjects[statement.Property] = Translate(statement.Property);
176      }
177
178      SemWeb.Entity subject = (SemWeb.Entity)translatedObjects[statement.Subject];
179      SemWeb.Entity predicate = (SemWeb.Entity)translatedObjects[statement.Predicate];
180      SemWeb.Resource property = (SemWeb.Resource)translatedObjects[statement.Property];
181
182      return new SemWeb.Statement(
183        subject,
184        predicate,
185        property);
186    }
187
188    private static SemWeb.Literal TranslateLiteral(SerializedLiteral l) {
189      if (l.RawData == null) return null;
190      return new SemWeb.Literal(l.RawData, null, "serializedItem");
191    }
192
193    private static SemWeb.Literal TranslateLiteral(Literal l) {
194      if (l.Value == null) return null;
195      if (l.Value is double) return SemWeb.Literal.FromValue((double)l.Value);
196      else if (l.Value is bool) return SemWeb.Literal.FromValue((bool)l.Value);
197      else if (l.Value is int) return SemWeb.Literal.FromValue((int)l.Value);
198      else if (l.Value is long) return SemWeb.Literal.FromValue((long)l.Value);
199      else if (l.Value is string) return SemWeb.Literal.FromValue((string)l.Value);
200      else return new SemWeb.Literal(l.Value.ToString());
201    }
202
203    private static Resource TranslateLiteral(SemWeb.Literal l) {
204      if (l.DataType == "serializedItem") {
205        return new SerializedLiteral(l.Value);
206      } else if (l.DataType != null) {
207        return new Literal(l.ParseValue());
208      } else {
209        return new Literal(l.Value);
210      }
211    }
212
213    private class MyQueryResultSink : SemWeb.Query.QueryResultSink {
214
215      private List<VariableBindings> bindings = new List<VariableBindings>();
216      public ICollection<VariableBindings> Bindings {
217        get { return bindings.AsReadOnly(); }
218      }
219
220      public override bool Add(SemWeb.Query.VariableBindings result) {
221        VariableBindings varBindings = new VariableBindings();
222        foreach (SemWeb.Variable var in result.Variables) {
223          if (var.LocalName != null && result[var] != null) {
224            if (result[var] is SemWeb.Literal) {
225              varBindings.Add(var.LocalName, TranslateLiteral((SemWeb.Literal)result[var]));
226            } else {
227              varBindings.Add(var.LocalName, new Entity(((SemWeb.Entity)result[var]).Uri));
228            }
229          }
230          bindings.Add(varBindings);
231        }
232        return true;
233      }
234    }
235  }
236}
Note: See TracBrowser for help on using the repository browser.