Yet another. Init the gobject type system.
[beagle.git] / Util / SemWeb / MemoryStore.cs
blob85437ff0fe4ba79da4492a3e407389fa54c51724
1 using System;
2 using System.Collections;
4 using SemWeb;
6 namespace SemWeb {
7 public class MemoryStore : Store, IEnumerable {
8 ArrayList statements = new ArrayList();
10 Hashtable statementsAboutSubject = new Hashtable();
11 Hashtable statementsAboutObject = new Hashtable();
13 bool isIndexed = false;
14 internal bool allowIndexing = true;
16 public MemoryStore() {
19 public MemoryStore(StatementSource source) {
20 Import(source);
23 public IList Statements { get { return ArrayList.ReadOnly(statements); } }
25 public override int StatementCount { get { return statements.Count; } }
27 IEnumerator IEnumerable.GetEnumerator() {
28 return statements.GetEnumerator();
31 public override void Clear() {
32 statements.Clear();
33 statementsAboutSubject.Clear();
34 statementsAboutObject.Clear();
37 private ArrayList GetIndexArray(Hashtable from, Resource entity) {
38 ArrayList ret = (ArrayList)from[entity];
39 if (ret == null) {
40 ret = new ArrayList();
41 from[entity] = ret;
43 return ret;
46 public override void Add(Statement statement) {
47 if (statement.AnyNull) throw new ArgumentNullException();
48 statements.Add(statement);
49 if (isIndexed) {
50 GetIndexArray(statementsAboutSubject, statement.Subject).Add(statement);
51 GetIndexArray(statementsAboutObject, statement.Object).Add(statement);
55 public override void Remove(Statement statement) {
56 if (statement.AnyNull) {
57 for (int i = 0; i < statements.Count; i++) {
58 Statement s = (Statement)statements[i];
59 if (statement.Matches(s)) {
60 statements.RemoveAt(i); i--;
61 if (isIndexed) {
62 GetIndexArray(statementsAboutSubject, s.Subject).Remove(s);
63 GetIndexArray(statementsAboutObject, s.Object).Remove(s);
67 } else {
68 statements.Remove(statement);
69 if (isIndexed) {
70 GetIndexArray(statementsAboutSubject, statement.Subject).Remove(statement);
71 GetIndexArray(statementsAboutObject, statement.Object).Remove(statement);
76 public override Entity[] GetAllEntities() {
77 Hashtable h = new Hashtable();
78 foreach (Statement s in Statements) {
79 if (s.Subject != null) h[s.Subject] = h;
80 if (s.Predicate != null) h[s.Predicate] = h;
81 if (s.Object != null && s.Object is Entity) h[s.Object] = h;
82 if (s.Meta != null && s.Meta != Statement.DefaultMeta) h[s.Meta] = h;
84 return (Entity[])new ArrayList(h.Keys).ToArray(typeof(Entity));
87 public override Entity[] GetAllPredicates() {
88 Hashtable h = new Hashtable();
89 foreach (Statement s in Statements)
90 h[s.Predicate] = h;
91 return (Entity[])new ArrayList(h.Keys).ToArray(typeof(Entity));
94 private void ShorterList(ref IList list1, IList list2) {
95 if (list2.Count < list1.Count)
96 list1 = list2;
99 public override void Select(Statement template, SelectPartialFilter partialFilter, StatementSink result) {
100 IList source = statements;
102 // The first time select is called, turn indexing on for the store.
103 // TODO: Perform this index in a background thread if there are a lot
104 // of statements.
105 if (!isIndexed && allowIndexing) {
106 isIndexed = true;
107 foreach (Statement statement in statements) {
108 GetIndexArray(statementsAboutSubject, statement.Subject).Add(statement);
109 GetIndexArray(statementsAboutObject, statement.Object).Add(statement);
113 if (template.Subject != null) ShorterList(ref source, GetIndexArray(statementsAboutSubject, template.Subject));
114 else if (template.Object != null) ShorterList(ref source, GetIndexArray(statementsAboutObject, template.Object));
116 if (source == null) return;
118 foreach (Statement statement in source) {
119 if (!template.Matches(statement))
120 continue;
121 if (!result.Add(statement)) return;
125 public override void Select(Statement[] templates, SelectPartialFilter partialFilter, StatementSink result) {
126 foreach (Statement t in templates)
127 Select(t, result);
130 public override void Replace(Entity a, Entity b) {
131 foreach (Statement statement in statements) {
132 if ((statement.Subject != null && statement.Subject == a) || (statement.Predicate != null && statement.Predicate == a) || (statement.Object != null && statement.Object == a) || (statement.Meta != null && statement.Meta == a)) {
133 Remove(statement);
134 Add(new Statement(
135 statement.Subject == a ? b : a,
136 statement.Predicate == a ? b : a,
137 statement.Object == a ? b : a,
138 statement.Meta == a ? b : a
144 public override void Replace(Statement find, Statement replacement) {
145 if (find.AnyNull) throw new ArgumentNullException("find");
146 if (replacement.AnyNull) throw new ArgumentNullException("replacement");
147 if (find == replacement) return;
149 foreach (Statement match in Select(find)) {
150 Remove(match);
151 Add(replacement);
152 break; // should match just one statement anyway
156 public override Entity[] FindEntities(Statement[] filters) {
157 ArrayList ents = new ArrayList();
158 foreach (Statement s in Select(filters[0])) {
159 if (s.Subject != null && filters[0].Subject == null)
160 ents.Add(s.Subject);
161 if (s.Predicate != null && filters[0].Predicate == null)
162 ents.Add(s.Predicate);
163 if (s.Object != null && filters[0].Object == null && s.Object is Entity)
164 ents.Add(s.Object);
165 if (s.Meta != null && filters[0].Meta == null)
166 ents.Add(s.Meta);
169 foreach (Statement f in filters) {
170 if (f == filters[0]) continue;
172 ArrayList e2 = new ArrayList();
173 foreach (Entity e in ents) {
174 Statement fe = new Statement(
175 f.Subject == null ? e : f.Subject,
176 f.Predicate == null ? e : f.Predicate,
177 f.Object == null ? e : f.Object,
178 f.Meta == null ? e : f.Meta);
179 if (Contains(fe))
180 e2.Add(e);
183 ents = e2;
186 return (Entity[])ents.ToArray(typeof(Entity));