Logo Search packages:      
Sourcecode: f-spot version File versions  Download package

MemoryStore.cs

using System;
using System.Collections;

using SemWeb;
using SemWeb.Stores;
using SemWeb.Util;

namespace SemWeb {
      public class MemoryStore : Store, SupportsPersistableBNodes, IEnumerable {
            StatementList statements;
            
            Hashtable statementsAboutSubject = new Hashtable();
            Hashtable statementsAboutObject = new Hashtable();
            
            bool isIndexed = false;
            internal bool allowIndexing = true;
            internal bool checkForDuplicates = false;
            bool distinct = true;
            
            string guid = null;
            Hashtable pbnodeToId = null;
            Hashtable pbnodeFromId = null;
            
            public MemoryStore() {
                  statements = new StatementList();
            }
            
            public MemoryStore(StatementSource source) : this() {
                  Import(source);
            }
            
            public MemoryStore(Statement[] statements) {
                  this.statements = new StatementList(statements);
            }

            public Statement[] ToArray() {
                  return (Statement[])statements.ToArray(typeof(Statement));
            }

            public IList Statements { get { return statements.ToArray(); } }
            
            public override bool Distinct { get { return distinct; } }
            
            public override int StatementCount { get { return statements.Count; } }
            
            public Statement this[int index] {
                  get {
                        return statements[index];
                  }
            }
            
            IEnumerator IEnumerable.GetEnumerator() {
                  return statements.GetEnumerator();
            }
            
            public override void Clear() {
                  statements.Clear();
                  statementsAboutSubject.Clear();
                  statementsAboutObject.Clear();
                  distinct = true;
            }
            
            private StatementList GetIndexArray(Hashtable from, Resource entity) {
                  StatementList ret = (StatementList)from[entity];
                  if (ret == null) {
                        ret = new StatementList();
                        from[entity] = ret;
                  }
                  return ret;
            }
            
            public override void Add(Statement statement) {
                  if (statement.AnyNull) throw new ArgumentNullException();
                  if (checkForDuplicates && Contains(statement)) return;
                  statements.Add(statement);
                  if (isIndexed) {
                        GetIndexArray(statementsAboutSubject, statement.Subject).Add(statement);
                        GetIndexArray(statementsAboutObject, statement.Object).Add(statement);
                  }
                  if (!checkForDuplicates) distinct = false;
            }
            
            public override void Import(StatementSource source) {
                  bool newDistinct = checkForDuplicates || ((StatementCount==0) && source.Distinct);
                  base.Import(source); // distinct set to false if !checkForDuplicates
                  distinct = newDistinct;
            }
            
            public override void Remove(Statement statement) {
                  if (statement.AnyNull) {
                        for (int i = 0; i < statements.Count; i++) {
                              Statement s = (Statement)statements[i];
                              if (statement.Matches(s)) {
                                    statements.RemoveAt(i); i--;
                                    if (isIndexed) {
                                          GetIndexArray(statementsAboutSubject, s.Subject).Remove(s);
                                          GetIndexArray(statementsAboutObject, s.Object).Remove(s);
                                    }
                              }
                        }
                  } else {
                        statements.Remove(statement);
                        if (isIndexed) {
                              GetIndexArray(statementsAboutSubject, statement.Subject).Remove(statement);
                              GetIndexArray(statementsAboutObject, statement.Object).Remove(statement);
                        }
                  }
            }
            
            public override Entity[] GetEntities() {
                  Hashtable h = new Hashtable();
                  foreach (Statement s in Statements) {
                        if (s.Subject != null) h[s.Subject] = h;
                        if (s.Predicate != null) h[s.Predicate] = h;
                        if (s.Object != null && s.Object is Entity) h[s.Object] = h;
                        if (s.Meta != null && s.Meta != Statement.DefaultMeta) h[s.Meta] = h;
                  }
                  return (Entity[])new ArrayList(h.Keys).ToArray(typeof(Entity));
            }
            
            public override Entity[] GetPredicates() {
                  Hashtable h = new Hashtable();
                  foreach (Statement s in Statements)
                        h[s.Predicate] = h;
                  return (Entity[])new ArrayList(h.Keys).ToArray(typeof(Entity));
            }

            public override Entity[] GetMetas() {
                  Hashtable h = new Hashtable();
                  foreach (Statement s in Statements)
                        h[s.Meta] = h;
                  return (Entity[])new ArrayList(h.Keys).ToArray(typeof(Entity));
            }

            private void ShorterList(ref StatementList list1, StatementList list2) {
                  if (list2.Count < list1.Count)
                        list1 = list2;
            }
            
            public override void Select(Statement template, StatementSink result) {
                  StatementList source = statements;
                  
                  // The first time select is called, turn indexing on for the store.
                  // TODO: Perform this index in a background thread if there are a lot
                  // of statements.
                  if (!isIndexed && allowIndexing) {
                        isIndexed = true;
                        for (int i = 0; i < StatementCount; i++) {
                              Statement statement = this[i];
                              GetIndexArray(statementsAboutSubject, statement.Subject).Add(statement);
                              GetIndexArray(statementsAboutObject, statement.Object).Add(statement);
                        }
                  }
                  
                  if (template.Subject != null) ShorterList(ref source, GetIndexArray(statementsAboutSubject, template.Subject));
                  else if (template.Object != null) ShorterList(ref source, GetIndexArray(statementsAboutObject, template.Object));
                  
                  if (source == null) return;
                  
                  for (int i = 0; i < source.Count; i++) {
                        Statement statement = source[i];
                        if (!template.Matches(statement))
                              continue;
                        if (!result.Add(statement)) return;
                  }
            }

            public override void Select(SelectFilter filter, StatementSink result) {
                  ResSet
                        s = filter.Subjects == null ? null : new ResSet(filter.Subjects),
                        p = filter.Predicates == null ? null : new ResSet(filter.Predicates),
                        o = filter.Objects == null ? null : new ResSet(filter.Objects),
                        m = filter.Metas == null ? null : new ResSet(filter.Metas);
                        
                  foreach (Statement st in statements) {
                        if (s != null && !s.Contains(st.Subject)) continue;
                        if (p != null && !p.Contains(st.Predicate)) continue;
                        if (o != null && !o.Contains(st.Object)) continue;
                        if (m != null && !m.Contains(st.Meta)) continue;
                        if (filter.LiteralFilters != null && !LiteralFilter.MatchesFilters(st.Object, filter.LiteralFilters, this)) continue;
                        if (!result.Add(st)) return;
                  }
            }

            public override void Replace(Entity a, Entity b) {
                  MemoryStore removals = new MemoryStore();
                  MemoryStore additions = new MemoryStore();
                  foreach (Statement statement in statements) {
                        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)) {
                              removals.Add(statement);
                              additions.Add(statement.Replace(a, b));
                        }
                  }
                  RemoveAll(removals.ToArray());
                  Import(additions);
            }
            
            public override void Replace(Statement find, Statement replacement) {
                  if (find.AnyNull) throw new ArgumentNullException("find");
                  if (replacement.AnyNull) throw new ArgumentNullException("replacement");
                  if (find == replacement) return;
                  
                  foreach (Statement match in Select(find)) {
                        Remove(match);
                        Add(replacement);
                        break; // should match just one statement anyway
                  }
            }

            string SupportsPersistableBNodes.GetStoreGuid() {
                  if (guid == null) guid = Guid.NewGuid().ToString("N");;
                  return guid;
            }
            
            string SupportsPersistableBNodes.GetNodeId(BNode node) {
                  if (pbnodeToId == null) {
                        pbnodeToId = new Hashtable();
                        pbnodeFromId = new Hashtable();
                  }
                  if (pbnodeToId.ContainsKey(node)) return (string)pbnodeToId[node];
                  string id = pbnodeToId.Count.ToString();
                  pbnodeToId[node] = id;
                  pbnodeFromId[id] = node;
                  return id;
            }
            
            BNode SupportsPersistableBNodes.GetNodeFromId(string persistentId) {
                  if (pbnodeFromId == null) return null;
                  return (BNode)pbnodeFromId[persistentId];
            }
      }
}

Generated by  Doxygen 1.6.0   Back to index