Free cookie consent management tool by TermsFeed Policy Generator

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

Last change on this file since 2148 was 2147, checked in by gkronber, 15 years ago

Implemented invalidation of RDF-statement cache. #696 (Cached RDF store is not invalidated when new statements are added to the sqlite-backed store (on disc))

File size: 8.5 KB
RevLine 
[545]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;
[557]42    private object bigLock = new object();
[2138]43    private SemWeb.Store cachedStore;
44
[545]45    public Store(string connectionString) {
[1287]46      lock (bigLock) {
[557]47        this.connectionString = connectionString;
48        store = SemWeb.Store.Create(connectionString);
[1287]49        InitStore();
[557]50      }
[545]51    }
52
[1287]53    private void InitStore() {
54      foreach (Statement s in Ontology.InitialStatements) {
55        Add(s);
56      }
57    }
58
[545]59    public void Add(Statement statement) {
[1287]60      lock (bigLock) {
[557]61        store.Add(Translate(statement));
[2147]62        InvalidateCachedStore();
[557]63      }
[545]64    }
65
[2053]66    public void AddRange(ICollection<Statement> statements) {
67      lock (bigLock) {
68        foreach (Statement s in statements) {
69          store.Add(Translate(s));
70        }
71      }
72    }
[1287]73
[2053]74
[1417]75    public ICollection<VariableBindings> Query(string query, int page, int pageSize) {
[2053]76      lock (bigLock) {
77        MyQueryResultSink resultSink = new MyQueryResultSink();
78        SemWeb.N3Reader n3Reader = new SemWeb.N3Reader(new StringReader(query));
79        SemWeb.Query.GraphMatch matcher = new SemWeb.Query.GraphMatch(n3Reader);
[2138]80        if (cachedStore == null) {
[2137]81          CacheStore();
82        }
[2138]83        matcher.Run(cachedStore, resultSink);
[2053]84        return resultSink.Bindings.Skip(page * pageSize).Take(pageSize).ToList();
85      }
[545]86    }
87
[2137]88    private void CacheStore() {
[2138]89      cachedStore = new SemWeb.MemoryStore();
90      cachedStore.Import(store);
[2137]91    }
92
[2147]93    private void InvalidateCachedStore() {
94      if (cachedStore != null) {
95        cachedStore.Dispose();
96        cachedStore = null;
97      }
98    }
99
100
[1417]101    public ICollection<VariableBindings> Query(ICollection<Statement> query, int page, int pageSize) {
[2053]102      lock (bigLock) {
103        MyQueryResultSink resultSink = new MyQueryResultSink();
[2138]104        if (cachedStore == null) {
[2137]105          CacheStore();
106        }
[2138]107        Translate(query).Run(cachedStore, resultSink);
[2053]108        return resultSink.Bindings.Skip(page * pageSize).Take(pageSize).ToList();
109      }
[551]110    }
111
[1287]112    private SemWeb.Query.Query Translate(ICollection<Statement> query) {
113      Dictionary<object, object> translatedObjects = new Dictionary<object, object>();
114      SemWeb.MemoryStore queryStore = new SemWeb.MemoryStore(query.Select(st => Translate(st, translatedObjects)).ToArray());
115
116      return new SemWeb.Query.GraphMatch(queryStore);
[551]117    }
118
[1287]119    private static SemWeb.Entity Translate(Entity e) {
[551]120      return e.Uri == null ? null : new SemWeb.Entity(e.Uri);
121    }
122
[1287]123    private static SemWeb.Resource Translate(Resource prop) {
124      if (prop is Literal) {
[551]125        return TranslateLiteral((Literal)prop);
[1287]126      } else if (prop is SerializedLiteral) {
[551]127        return TranslateLiteral((SerializedLiteral)prop);
128      } else {
129        return Translate((Entity)prop);
130      }
131    }
132
[1287]133    private static Statement Translate(SemWeb.Statement statement) {
134      return Translate(statement, new Dictionary<object, object>());
135    }
136
137    private static Statement Translate(SemWeb.Statement statement, Dictionary<object, object> translatedObjects) {
138      if (!translatedObjects.ContainsKey(statement.Subject)) {
139        translatedObjects[statement.Subject] = new Entity(statement.Subject.Uri);
[545]140      }
[1287]141      if (!translatedObjects.ContainsKey(statement.Predicate)) {
142        translatedObjects[statement.Predicate] = new Entity(statement.Predicate.Uri);
143      }
144      if (!translatedObjects.ContainsKey(statement.Object)) {
145        if (statement.Object is SemWeb.Literal) {
146          translatedObjects[statement.Object] = TranslateLiteral((SemWeb.Literal)statement.Object);
147        } else {
148          translatedObjects[statement.Object] = new Entity(((SemWeb.Entity)statement.Object).Uri);
149        }
150      }
151
152      Entity subjectEntity = (Entity)translatedObjects[statement.Subject];
153      Entity predicateEntity = (Entity)translatedObjects[statement.Predicate];
154      Resource property = (Resource)translatedObjects[statement.Object];
155
156      return new Statement(
157        subjectEntity,
158        predicateEntity,
159        property);
[545]160    }
161
[1287]162    private static SemWeb.Statement Translate(Statement statement) {
163      return Translate(statement, new Dictionary<object, object>());
164    }
165
166    private static SemWeb.Statement Translate(Statement statement, Dictionary<object, object> translatedObjects) {
167      if (!translatedObjects.ContainsKey(statement.Subject)) {
168        translatedObjects[statement.Subject] = Translate(statement.Subject);
169      }
170      if (!translatedObjects.ContainsKey(statement.Predicate)) {
171        translatedObjects[statement.Predicate] = Translate(statement.Predicate);
172      }
173      if (!translatedObjects.ContainsKey(statement.Property)) {
174        translatedObjects[statement.Property] = Translate(statement.Property);
175      }
176
177      SemWeb.Entity subject = (SemWeb.Entity)translatedObjects[statement.Subject];
178      SemWeb.Entity predicate = (SemWeb.Entity)translatedObjects[statement.Predicate];
179      SemWeb.Resource property = (SemWeb.Resource)translatedObjects[statement.Property];
180
[551]181      return new SemWeb.Statement(
[1287]182        subject,
183        predicate,
184        property);
[545]185    }
186
[1287]187    private static SemWeb.Literal TranslateLiteral(SerializedLiteral l) {
188      if (l.RawData == null) return null;
[545]189      return new SemWeb.Literal(l.RawData, null, "serializedItem");
190    }
191
[1287]192    private static SemWeb.Literal TranslateLiteral(Literal l) {
193      if (l.Value == null) return null;
194      if (l.Value is double) return SemWeb.Literal.FromValue((double)l.Value);
195      else if (l.Value is bool) return SemWeb.Literal.FromValue((bool)l.Value);
196      else if (l.Value is int) return SemWeb.Literal.FromValue((int)l.Value);
197      else if (l.Value is long) return SemWeb.Literal.FromValue((long)l.Value);
198      else if (l.Value is string) return SemWeb.Literal.FromValue((string)l.Value);
[545]199      else return new SemWeb.Literal(l.Value.ToString());
200    }
201
[1287]202    private static Resource TranslateLiteral(SemWeb.Literal l) {
203      if (l.DataType == "serializedItem") {
[545]204        return new SerializedLiteral(l.Value);
[1287]205      } else if (l.DataType != null) {
[545]206        return new Literal(l.ParseValue());
207      } else {
208        return new Literal(l.Value);
209      }
210    }
[1287]211
212    private class MyQueryResultSink : SemWeb.Query.QueryResultSink {
213
214      private List<VariableBindings> bindings = new List<VariableBindings>();
215      public ICollection<VariableBindings> Bindings {
216        get { return bindings.AsReadOnly(); }
217      }
218
219      public override bool Add(SemWeb.Query.VariableBindings result) {
220        VariableBindings varBindings = new VariableBindings();
221        foreach (SemWeb.Variable var in result.Variables) {
222          if (var.LocalName != null && result[var] != null) {
223            if (result[var] is SemWeb.Literal) {
224              varBindings.Add(var.LocalName, TranslateLiteral((SemWeb.Literal)result[var]));
225            } else {
226              varBindings.Add(var.LocalName, new Entity(((SemWeb.Entity)result[var]).Uri));
227            }
228          }
229          bindings.Add(varBindings);
230        }
231        return true;
232      }
233    }
[545]234  }
235}
Note: See TracBrowser for help on using the repository browser.