private void indexAnswerForSignature(object[] answer, int signature) { // First find out which of the answer values can be used as an index. object[] indexValues = new object[answer.Length]; for (int i = 0; i < answer.Length; ++i) { // We limit the number of indexed args in a 32-bit signature. if (i >= MAX_INDEX_ARGS) { indexValues[i] = null; } else { indexValues[i] = getIndexValue(YP.getValue(answer[i])); } } // We need an entry in indexArgs from indexValues for each 1 bit in signature. HashedList indexArgs = new HashedList(indexValues.Length); for (int i = 0; i < indexValues.Length; ++i) { if ((signature & (1 << i)) == 0) { indexArgs.Add(null); } else { if (indexValues[i] == null) { // The signature wants an index value here, but we don't have one so // we can't add it as an answer for this signature. return; } else { indexArgs.Add(indexValues[i]); } } } // Add the answer to the answers list for indexArgs, creating the entry if needed. List <object[]> answers; if (!_indexedAnswers.TryGetValue(indexArgs, out answers)) { answers = new List <object[]>(); _indexedAnswers[indexArgs] = answers; } answers.Add(answer); }
public IEnumerable <bool> match(object[] arguments) { if (arguments.Length != _arity) { yield break; } // Set up indexArgs, up to arg position MAX_INDEX_ARGS. The signature has a 1 bit for // each non-null index arg. HashedList indexArgs = new HashedList(arguments.Length); bool gotAllIndexArgs = true; int signature = 0; for (int i = 0; i < arguments.Length; ++i) { object indexValue = null; if (i < MAX_INDEX_ARGS) { // We limit the number of args in a 32-bit signature. indexValue = getIndexValue(YP.getValue(arguments[i])); if (indexValue != null) { signature += (1 << i); } } if (indexValue == null) { gotAllIndexArgs = false; } indexArgs.Add(indexValue); } List <object[]> answers; if (signature == 0) { // No index args, so we have to match from _allAnswers. answers = _allAnswers; } else { if (!_gotAnswersForSignature.ContainsKey(signature)) { // We need to create the entry in _indexedAnswers. foreach (object[] answer in _allAnswers) { indexAnswerForSignature(answer, signature); } // Mark that we did this signature. _gotAnswersForSignature[signature] = null; } if (!_indexedAnswers.TryGetValue(indexArgs, out answers)) { yield break; } } if (gotAllIndexArgs) { // All the arguments were already bound, so we don't need to do bindings. yield return(false); yield break; } // Find matches in answers. IEnumerator <bool>[] iterators = new IEnumerator <bool> [arguments.Length]; // Debug: If the caller asserts another answer into this same predicate during yield, the iterator // over clauses will be corrupted. Should we take the time to copy answers? foreach (object[] answer in answers) { bool gotMatch = true; int nIterators = 0; // Try to bind all the arguments. for (int i = 0; i < arguments.Length; ++i) { if (indexArgs[i] != null) { // We already matched this argument by looking up _indexedAnswers. continue; } IEnumerator <bool> iterator = YP.unify(arguments[i], answer[i]).GetEnumerator(); iterators[nIterators++] = iterator; // MoveNext() is true if YP.unify succeeds. if (!iterator.MoveNext()) { gotMatch = false; break; } } int z = 0; try { if (gotMatch) { yield return(false); } } finally { // Manually finalize all the iterators. for (z = 0; z < nIterators; ++z) { iterators[z].Dispose(); } } } }
public IEnumerable<bool> match(object[] arguments) { if (arguments.Length != _arity) yield break; // Set up indexArgs, up to arg position MAX_INDEX_ARGS. The signature has a 1 bit for // each non-null index arg. HashedList indexArgs = new HashedList(arguments.Length); bool gotAllIndexArgs = true; int signature = 0; for (int i = 0; i < arguments.Length; ++i) { object indexValue = null; if (i < MAX_INDEX_ARGS) { // We limit the number of args in a 32-bit signature. indexValue = getIndexValue(YP.getValue(arguments[i])); if (indexValue != null) signature += (1 << i); } if (indexValue == null) gotAllIndexArgs = false; indexArgs.Add(indexValue); } List<object[]> answers; if (signature == 0) // No index args, so we have to match from _allAnswers. answers = _allAnswers; else { if (!_gotAnswersForSignature.ContainsKey(signature)) { // We need to create the entry in _indexedAnswers. foreach (object[] answer in _allAnswers) indexAnswerForSignature(answer, signature); // Mark that we did this signature. _gotAnswersForSignature[signature] = null; } if (!_indexedAnswers.TryGetValue(indexArgs, out answers)) yield break; } if (gotAllIndexArgs) { // All the arguments were already bound, so we don't need to do bindings. yield return false; yield break; } // Find matches in answers. IEnumerator<bool>[] iterators = new IEnumerator<bool>[arguments.Length]; // Debug: If the caller asserts another answer into this same predicate during yield, the iterator // over clauses will be corrupted. Should we take the time to copy answers? foreach (object[] answer in answers) { bool gotMatch = true; int nIterators = 0; // Try to bind all the arguments. for (int i = 0; i < arguments.Length; ++i) { if (indexArgs[i] != null) // We already matched this argument by looking up _indexedAnswers. continue; IEnumerator<bool> iterator = YP.unify(arguments[i], answer[i]).GetEnumerator(); iterators[nIterators++] = iterator; // MoveNext() is true if YP.unify succeeds. if (!iterator.MoveNext()) { gotMatch = false; break; } } try { if (gotMatch) yield return false; } finally { // Manually finalize all the iterators. for (int i = 0; i < nIterators; ++i) iterators[i].Dispose(); } } }
private void indexAnswerForSignature(object[] answer, int signature) { // First find out which of the answer values can be used as an index. object[] indexValues = new object[answer.Length]; for (int i = 0; i < answer.Length; ++i) { // We limit the number of indexed args in a 32-bit signature. if (i >= MAX_INDEX_ARGS) indexValues[i] = null; else indexValues[i] = getIndexValue(YP.getValue(answer[i])); } // We need an entry in indexArgs from indexValues for each 1 bit in signature. HashedList indexArgs = new HashedList(indexValues.Length); for (int i = 0; i < indexValues.Length; ++i) { if ((signature & (1 << i)) == 0) indexArgs.Add(null); else { if (indexValues[i] == null) // The signature wants an index value here, but we don't have one so // we can't add it as an answer for this signature. return; else indexArgs.Add(indexValues[i]); } } // Add the answer to the answers list for indexArgs, creating the entry if needed. List<object[]> answers; if (!_indexedAnswers.TryGetValue(indexArgs, out answers)) { answers = new List<object[]>(); _indexedAnswers[indexArgs] = answers; } answers.Add(answer); }
public static void Test(System.String[] args) { HashedList h1 = new HashedList(); HashedList h2 = new HashedList(); Cursor i = h1.GetCursor(0); Cursor j; // Add a few unkeyed rows. h1.Add("Row 1"); h1.Add("Row 2"); h1.Add("Row 3"); System.Console.Out.WriteLine("***** Collection methods *****\n"); show("Three unkeyed elements", h1); h1.RemoveUnkeyedObject("Row 2"); show("Did we remove Row 2?", h1); h1.Clear(); show("Cleared", h1); h1.Add("key 1", "Row 1"); h1.Add("key 2", "Row 2"); h1.Add("key 3", "Row 3"); show("Three keyed elements", h1); // h1.RemoveKey("key 2"); h1.Remove("key 2"); show("Did we remove Row 2 using a key?", h1); h1.Clear(); show("Cleared", h1); h1.Add("key 1", "Row 1"); h1.Add("key 2", "Row 2"); h1.Add("key 3", "Row 3"); show("Three elements again!", h1); System.Console.Out.WriteLine("Check contains (true):" + h1.ContainsValue("Row 2")); h2.Add("key 4", "Row 4"); h2.Add("key 5", "Row 5"); // System.Console.Out.WriteLine("Check containsAll (false):" + h1.containsAll(h2)); // h1.addAll(h2); // show("Should have 5 elements now", h1); // System.Console.Out.WriteLine("Check containsAll (true):" + h1.containsAll(h2)); // System.Console.Out.WriteLine("Check contains (true):" + h1.Contains("Row 4")); // h1.RemoveUnkeyedObject("Row 4"); // show("Dropped Row 4:", h1); // System.Console.Out.WriteLine("Check containsAll (false):" + h1.containsAll(h2)); System.Console.Out.WriteLine("Check contains (false):" + h1.Contains("Row 4")); System.Console.Out.WriteLine("Check isEmpty (false):" + h1.Empty); h1.RemoveValue("Row 1"); h1.RemoveValue("Row 2"); h1.RemoveValue("Row 3"); h1.RemoveValue("Row 5"); show("Removed all elements", h1); System.Console.Out.WriteLine("Check isEmpty (true):" + h1.Empty); h1.Add("Row 1"); h1.Add("Row 2"); h1.Add("Row 3"); // h1.addAll(h2); // show("Back to 5", h1); // h1.removeAll(h2); // show("Testing removeAll back to 3?", h1); // h1.addAll(h2); // h1.retainAll(h2); // show("Testing retainAll now just 2?", h1); System.Console.Out.WriteLine("\n\n**** Test Cursor **** \n"); j = h1.GetCursor(); while (j.MoveNext()) { System.Console.Out.WriteLine("Cursor got:" + j.Current); } h1.Clear(); h1.Add("key 1", "Row 1"); h1.Add("key 2", "Row 2"); h1.Add("Row 3"); h1.Add("key 4", "Row 4"); h1.Add("Row 5"); j = h1.GetCursor(); j.MoveNext(); j.MoveNext(); j.Remove(); // Should get rid of second row show("Removed second row with cursor", h1); System.Console.Out.WriteLine("Cursor should still be OK:" + j.MoveNext() + " " + j.Current); System.Console.Out.WriteLine("Cursor should still be OK:" + j.MoveNext() + " " + j.Current); System.Console.Out.WriteLine("Cursor should still be OK:" + j.MoveNext() + " " + j.Current); System.Console.Out.WriteLine("Cursor should be done:" + j.MoveNext()); System.Console.Out.WriteLine("\n\n**** HashedListCursor ****\n"); i = h1.GetCursor(0); System.Console.Out.WriteLine("Cursor should still be OK:" + i.MoveNext() + " " + i.Current); System.Console.Out.WriteLine("Cursor should still be OK:" + i.MoveNext() + " " + i.Current); System.Console.Out.WriteLine("Cursor should still be OK:" + i.MoveNext() + " " + i.Current); System.Console.Out.WriteLine("Cursor should still be OK:" + i.MoveNext() + " " + i.Current); System.Console.Out.WriteLine("Cursor should be done:" + i.MoveNext()); i.Key = "key 1"; // i.Current; i.Add("key 2", "Row 2"); System.Console.Out.WriteLine("Cursor should still be OK:" + i.MoveNext() + " " + i.Current); System.Console.Out.WriteLine("Cursor should still be OK:" + i.MoveNext() + " " + i.Current); System.Console.Out.WriteLine("Cursor should still be OK:" + i.MoveNext() + " " + i.Current); System.Console.Out.WriteLine("Cursor should be done:" + i.MoveNext()); i.Key = "key 4"; System.Console.Out.WriteLine("Cursor should still be OK:" + i.MoveNext() + " " + i.Current); // System.Console.Out.WriteLine("Cursor should still be OK:" + i.MoveNext() + " " + i.Current); System.Console.Out.WriteLine("Cursor should be done:" + i.MoveNext()); i.Key = "key 2"; i.MoveNext(); i.MoveNext(); i.Add("Row 3.5"); i.Add("Row 3.6"); show("Added some rows... should be 7", h1); i = h1.GetCursor("key 2"); i.Add("Row 1.5"); i.Add("key 1.7", "Row 1.7"); i.Add("Row 1.9"); System.Console.Out.WriteLine("Cursor should point to 2:" + ((System.Collections.DictionaryEntry)i.Current).Key); i.Key = "key 1.7"; System.Console.Out.WriteLine("Cursor should point to 1.7:" + ((System.Collections.DictionaryEntry)i.Current).Key); }
/// <summary> /// Creates Compound commands if necessary /// </summary> /// <param name="commands"></param> private Command[] OptimizeCommands(SyncEngine engine, IList<Entity> commands) { if (commands == null) throw new ArgumentNullException("commands"); if (commands.Count == 0) return new Command[0]; HashedList<Command> optimizedCommands = new HashedList<Command>(); System.Collections.Generic.List<CompoundCreateCommand> createdCommands = new System.Collections.Generic.List<CompoundCreateCommand>(); int j; for (int i = 0; i < commands.Count; i++) { Entity e = commands[i]; string currentId = e.GetString(SyncUtils.PARENTID); int transaction = e.GetInt32(SyncUtils.TRANSACTION); switch (e.Type) { case SyncUtils.CREATE_ENTITY: string createType = e.GetString(SyncUtils.TYPE); j = i + 1; CompoundCreateCommand ccc = new CompoundCreateCommand(currentId, createType, new List<AttributeCommand>()); CompoundCreateCommand actual = createdCommands.Find(delegate(CompoundCreateCommand toFind) { return toFind.ClientId == ccc.ClientId && toFind.ParentId == ccc.ParentId && toFind.Type == ccc.Type; }); if (actual == null) { createdCommands.Add(ccc); optimizedCommands.Add(ccc); while (j < commands.Count) { string subType = commands[j].GetString(SyncUtils.PARENTTYPE); string subId = commands[j].GetString(SyncUtils.PARENTID); int subTransaction = commands[j].GetInt32(SyncUtils.TRANSACTION); string subCommand = commands[j].Type; if (commands[j].Type == SyncUtils.CREATE_ATTRIBUTE && subId == currentId && subType == createType) { if (subTransaction != transaction) break; ccc.InnerCommands.Add((AttributeCommand)engine.CreateCommand(commands[j])); commands.RemoveAt(j); } else { j++; } } } else { optimizedCommands.Remove(actual); optimizedCommands.Add(ccc); createdCommands.Remove(actual); createdCommands.Add(ccc); } break; case SyncUtils.UPDATE_ATTRIBUTE: string updateType = e.GetString(SyncUtils.PARENTTYPE); j = i + 1; CompoundUpdateCommand cuc = new CompoundUpdateCommand(currentId, updateType, new List<AttributeCommand>()); cuc.InnerCommands.Add((AttributeCommand)engine.CreateCommand(commands[i])); optimizedCommands.Add(cuc); while (j < commands.Count) { string subType = commands[j].GetString(SyncUtils.PARENTTYPE); string subId = commands[j].GetString(SyncUtils.PARENTID); int subTransaction = commands[j].GetInt32(SyncUtils.TRANSACTION); string subCommand = commands[j].Type; if (commands[j].Type == SyncUtils.UPDATE_ATTRIBUTE && subId == currentId && subType == updateType) { if (subTransaction != transaction) break; cuc.InnerCommands.Add((AttributeCommand)engine.CreateCommand(commands[j])); commands.RemoveAt(j); } else { j++; } } break; default: optimizedCommands.Add(engine.CreateCommand(e)); break; } } Command[] result = new Command[optimizedCommands.Count]; for (int i = 0; i < result.Length; i++) result[i] = (Command)optimizedCommands[i]; return result; }
public void ComputeChanges(IEnumerable<Entity> entities, bool ignoreReferences) { HashedList<Entity> processing = new HashedList<Entity>(); foreach (Entity e in entities) { if (ignoreReferences) { foreach (Entry entry in e) { if (!(!entry.IsEntity || processing.Contains((Entity)entry.Value))) { processing.Add((Entity)entry.Value); } } } ComputeChanges(e, processing, Commands); } }