static void DumpObject(Thing thing, TextWriter writer, int indent, SearchKind kind, DateTime timestamp, int depth) { WriteTab(writer, indent); string typeName = GetQualifiedName(thing.type.vh.uri, writer); writer.WriteLine(" rdf:about=\"" + thing.vh.uri + "\" vr:timestamp=\"" + thing.timestamp + "\">"); foreach (PropVal pv in thing.props) { object val = pv.val; if (val is VersionHistory) { VersionHistory ptr = (VersionHistory)val; if (kind != SearchKind.AllVersions) { if (depth > 0 || ptr.uri.StartsWith(thing.vh.uri)) { Thing t = ptr.GetVersion(kind, timestamp); if (t != null) { DumpObject(t, writer, indent+1, kind, timestamp, depth-1); continue; } } } WriteTab(writer, indent+1); GetQualifiedName(pv.def.name, writer); writer.WriteLine(" rdf:resource=\"" + ptr.uri + "\"/>"); } else { WriteTab(writer, indent+1); string propName = GetQualifiedName(pv.def.name, writer); writer.WriteLine(">" + val + "</" + propName + ">"); } } WriteTab(writer, indent); writer.WriteLine("</" + typeName + ">"); }
private bool Match(Thing thing) { if (type != null && !thing.IsInstanceOf(type, kind, timestamp)) { return false; } switch (kind) { case SearchKind.LatestVersion: if (!thing.IsLatest()) { return false; } break; case SearchKind.LatestBefore: if (thing.timestamp > timestamp || thing.vh.GetLatestBefore(timestamp) != thing) { return false; } break; case SearchKind.OldestAfter: if (thing.timestamp < timestamp || thing.vh.GetOldestAfter(timestamp) != thing) { return false; } break; default: break; } if (uri != null) { if (!MatchString(thing.vh.uri, uri)) { return false; } } for (int i = 0; i < patterns.Length; i++) { if (!MatchProperty(patterns[i], thing)) { return false; } } currThing = thing; return true; }
private bool MatchProperty(NameVal prop, Thing thing) { switch (prop.name) { case Symbols.Point: if (prop.val is NameVal[]) { NameVal[] coord = (NameVal[])prop.val; if (coord.Length == 2) { double x = (double)coord[0].val; double y = (double)coord[1].val; RectangleR2 r = new RectangleR2(x, y, x, y); foreach (Thing t in root.spatialIndex.Overlaps(r)) { if (t == thing) { return true; } } return false; } } break; case Symbols.Rectangle: if (prop.val is NameVal[]) { NameVal[] coord = (NameVal[])prop.val; if (coord.Length == 4) { RectangleR2 r = new RectangleR2((double)coord[0].val, (double)coord[1].val, (double)coord[2].val, (double)coord[3].val); foreach (Thing t in root.spatialIndex.Overlaps(r)) { if (t == thing) { return true; } } return false; } } break; case Symbols.Keyword: if (prop.val is string) { Hashtable keywords = new Hashtable(); foreach (PropVal pv in thing.props) { object val = pv.val; if (val is string) { foreach (string keyword in ((string)val).ToLower().Split(keywordSeparators)) { if (keyword.Length > 0 && !keywordStopList.ContainsKey(keyword)) { keywords[keyword] = this; } } } } foreach (string keyword in ((string)prop.val).ToLower().Split(keywordSeparators)) { if (keyword.Length > 0 && !keywordStopList.ContainsKey(keyword) && !keywords.ContainsKey(keyword)) { return false; } } return true; } break; } NextItem: foreach (object val in thing[prop.name]) { object pattern = prop.val; if (val is string && pattern is string) { if (MatchString((string)val, (string)pattern)) { return true; } } else if (pattern is NameVal) { if (FollowReference((NameVal)pattern, val as VersionHistory)) { return true; } } else if (pattern is NameVal[]) { foreach (NameVal p in (NameVal[])prop.val) { if (!FollowReference(p, val as VersionHistory)) { goto NextItem; } } return true; } else if (pattern is Range && val is IComparable) { try { Range range = (Range)pattern; IComparable cmp = (IComparable)val; return cmp.CompareTo(range.from) >= (range.fromInclusive ? 0 : 1) && cmp.CompareTo(range.till) <= (range.tillInclusive ? 0 : -1); } catch (ArgumentException) {} } else if (pattern != null && pattern.Equals(val)) { return true; } } return false; }
public bool MoveNext() { currThing = null; Repeat: if (currHistory != null) { while (currVersion < currHistory.Count) { Thing thing = (Thing)currHistory[currVersion++]; if (Match(thing)) { return true; } } currHistory = null; } while (iterator.MoveNext()) { object curr = iterator.Current; if (curr is Thing) { if (Match((Thing)curr)) { return true; } } else if (curr is VersionHistory) { currHistory = ((VersionHistory)curr).versions; currVersion = 0; goto Repeat; } } return false; }
public void Reset() { iterator.Reset(); currThing = null; currHistory = null; }
public bool MoveNext() { while (true) { while (pos < iterators.Length && !iterators[pos].MoveNext()) { pos += 1; } if (pos == iterators.Length) { currThing = null; return false; } Thing thing = (Thing)iterators[pos].Current; switch (kind) { case SearchKind.LatestVersion: if (!thing.IsLatest()) { continue; } break; case SearchKind.LatestBefore: if (thing.timestamp > timestamp) { continue; } break; case SearchKind.OldestAfter: if (thing.timestamp < timestamp) { continue; } break; } if (pos == 0) { if (visited.ContainsKey(thing.Oid)) { continue; } else { visited[thing.Oid] = true; } currThing = thing; return true; } pos -= 1; Key key = new Key(new object[]{defs[pos], thing.vh}); iterators[pos] = root.refPropIndex.GetEnumerator(key, key); } }
public void Reset() { visited = new Hashtable(); currThing = null; pos = iterators.Length-1; iterators[pos].Reset(); }
private Thing CreateObject(Thing type, VersionHistory vh, NameVal[] props) { Thing thing = new Thing(); thing.vh = vh; thing.type = type; thing.timestamp = DateTime.Now; thing.props = new PropVal[props.Length]; for (int i = 0; i < props.Length; i++) { NameVal prop = props[i]; PropDef def = (PropDef)root.propDefIndex[prop.name]; if (def == null) { def = new PropDef(); def.name = prop.name; root.propDefIndex.Put(def); } object val = prop.val; PropVal pv = new PropVal(def, val); Key key = new Key(new object[]{def, val}); if (val is string) { root.strPropIndex.Put(key, thing); foreach (string keyword in ((string)val).ToLower().Split(keywordSeparators)) { if (keyword.Length > 0 && !keywordStopList.ContainsKey(keyword)) { root.inverseIndex.Put(keyword, thing); } } } else if (val is double) { root.numPropIndex.Put(key, thing); } else if (val is DateTime) { root.timePropIndex.Put(key, thing); } else if (val is VersionHistory || val == null) { root.refPropIndex.Put(key, thing); if (prop.name == Symbols.Rectangle) { PropVal[] coord = ((VersionHistory)val).Latest.props; RectangleR2 r = new RectangleR2((double)coord[0].val, (double)coord[1].val, (double)coord[2].val, (double)coord[3].val); root.spatialIndex.Put(r, thing); } else if (prop.name == Symbols.Point) { PropVal[] coord = ((VersionHistory)val).Latest.props; double x = (double)coord[0].val; double y = (double)coord[1].val; RectangleR2 r = new RectangleR2(x, y, x, y); root.spatialIndex.Put(r, thing); } } else { throw new InvalidOperationException("Invalid propery value type " + prop.val.GetType()); } thing.props[i] = pv; } thing.Modify(); vh.versions.Add(thing); root.timeIndex.Put(thing); root.latest.Add(thing); return thing; }