public void ShortSet_CapacityHandling() { // Verify values above capacity are not reported, even if there are bits for them ShortSet s1 = new ShortSet(10); s1.Not(); Assert.AreEqual("0, 1, 2, 3, 4, 5, 6, 7, 8, 9", String.Join(", ", s1.Values)); // Verify the last value is not truncated if the this set in an operation is larger, // and that values above the other capacity aren't involved in operations. ShortSet s2 = new ShortSet(120); s2.Not(); ShortSet s3 = new ShortSet(64); s3.Not(); s2.And(s3); Assert.IsTrue(s2.Contains(63)); s2.Or(s3); Assert.IsTrue(s2.Contains(63)); s3.Not(); s2.AndNot(s3); Assert.IsTrue(s2.Contains(63)); }
public void ShortSet_Performance_Set() { // Goal: Set operations are <10k instructions, so at 2M instructions per millisecond, 200 per millisecond (Release build) // Set operations are used to combine where clauses and sets for specific words when word searching. Random r = new Random(); ShortSet s1 = BuildRandom(ushort.MaxValue, 1000, r); ShortSet s2 = BuildRandom(ushort.MaxValue, 10000, r); ShortSet s3 = BuildRandom(ushort.MaxValue, 50000, r); ushort[] s4 = { 1, 126, 950, 1024, 1025, 1670, 19240 }; ShortSet scratch = new ShortSet(ushort.MaxValue); // 9 Operations x 10k iterations = 90k operations. // Goal is 100ms. int iterations = 2500; Stopwatch w = Stopwatch.StartNew(); for (int i = 0; i < iterations; ++i) { // Singleton Operations / Reset scratch.Not(); scratch.Clear(); scratch.Or(s1); // Enumerable Operations scratch.And(s4); scratch.Or(s4); scratch.AndNot(s4); // ShortSet Operations scratch.Or(s2); scratch.And(s3); scratch.AndNot(s2); } int operations = (9 * iterations); double milliseconds = w.ElapsedMilliseconds; double operationsPerMillisecond = operations / milliseconds; Trace.Write(String.Format("{0:n0} operations in {1:n0} milliseconds; {2:n0} per millisecond.", operations, milliseconds, operationsPerMillisecond)); Assert.IsTrue(operationsPerMillisecond > 100, "Not within 200% of goal."); }
public void ShortSet_MismatchedCapacities() { ShortSet s1 = new ShortSet(10); s1.Add(1); s1.Add(3); ShortSet s2 = new ShortSet(20); s2.Add(2); s2.Add(4); s2.Add(10); // Verify values below common capacity are set, larger values not set. s1.Or(s2); Assert.AreEqual("1, 2, 3, 4", String.Join(", ", s1.Values)); // Verify values above common capacity are left alone. s2.Or(s1); Assert.AreEqual("1, 2, 3, 4, 10", String.Join(", ", s2.Values)); // Verify values below common capacity are cleared, values above not unexpectedly set. s1.AndNot(s2); Assert.AreEqual("", String.Join(", ", s1.Values)); // Verify values above common capacity are left set s1.Clear(); s1.Add(1); s1.Add(3); s2.AndNot(s1); Assert.AreEqual("2, 4, 10", String.Join(", ", s2.Values)); // Verify values above common capacity are not set s2.Or(s1); s1.And(s2); Assert.AreEqual("1, 3", String.Join(", ", s1.Values)); // Verify values above common capacity *are* cleared) s2.And(s1); Assert.AreEqual("1, 3", String.Join(", ", s2.Values)); }
unsafe public void ShortSet_Unsafe() { ShortSet s1 = new ShortSet(64); // Set the first three values from a "sparse packed" set ushort[] values = new ushort[] { 1, 3, 5, 7, 9, 11 }; fixed(ushort *vp = values) { s1.Or(vp, 3); Verify.Exception <ArgumentNullException>(() => s1.Or((ushort *)null, 1)); } Assert.AreEqual("1, 3, 5", String.Join(", ", s1.Values)); // Set the first 64 bits of values from a "dense packed" set [this is 0x3, so the last two bits are set; endianness specific] ulong[] bits = new ulong[] { 3 }; fixed(ulong *bp = bits) { s1.Or(bp, 1); Verify.Exception <ArgumentNullException>(() => s1.Or((ulong *)null, 1)); } Assert.AreEqual("1, 3, 5, 62, 63", String.Join(", ", s1.Values)); }
public void ShortSet_CapacityZero() { ShortSet s1 = new ShortSet(0); Assert.AreEqual(0, s1.Count()); s1.Not(); Assert.AreEqual(0, s1.Count()); ShortSet s2 = new ShortSet(10); s2.Not(); s1.And(s2); s1.Or(s2); Assert.AreEqual(0, s1.Count()); }
public void Aggregator_BaseBehaviors() { AggregatorBaseBehaviors(new CountAggregator(), false); AggregatorBaseBehaviors(new SumAggregator()); AggregatorBaseBehaviors(new MinAggregator()); AggregatorBaseBehaviors(new MaxAggregator()); // Check BaseAggregator doesn't implement unexpected types or methods IUntypedColumn column = ColumnFactory.Build(new ColumnDetails("ID", "bool", false), 100); ShortSet sample = new ShortSet(100); sample.Or(new ushort[] { 1, 2, 3 }); IAggregator aggregator = new BaseAggregator(); Verify.Exception <NotImplementedException>(() => aggregator.Aggregate(null, sample, new IUntypedColumn[] { column })); Verify.Exception <NotImplementedException>(() => aggregator.Merge(null, new object[2])); }
public void AddMatches(ushort[] sortedIDs, ShortSet matches) { ShortSet m = matches; // If negating, we have to negate in a separate set and then OR to preserve previously set values if (this.NegateResult) { m = new ShortSet(matches.Capacity); } // Add all items within or around the range as requested if (this.End != -1) { if (this.ScanWithinRange) { for (int i = this.Start; i <= this.End; ++i) { m.Add(sortedIDs[i]); } } else { for (int i = 0; i < this.Start; ++i) { m.Add(sortedIDs[i]); } for (int i = this.End + 1; i < this.Count; ++i) { m.Add(sortedIDs[i]); } } } // Negate if requested if (this.NegateResult) { m.Not(); matches.Or(m); } }
public void SetSize(ushort size) { ushort oldSize = this.Count; if (size != _trueItems.Capacity) { // Allocate a new size set and copy all set values ShortSet newItems = new ShortSet(size); newItems.Or(_trueItems); _trueItems = newItems; // If the default is true, set new values true initially if (this.DefaultValue == true) { for (ushort i = oldSize; i < size; ++i) { _trueItems.Add(i); } } } }
private void AggregatorBaseBehaviors(IAggregator aggregator, bool requiresColumns = true) { // Verify ToString returns the aggregator type, which matches the start of the class name string name = aggregator.ToString(); Assert.AreEqual(aggregator.GetType().Name.ToLowerInvariant(), (name + "aggregator").ToLowerInvariant()); // Verify Merge throws if the values are null Verify.Exception <ArgumentNullException>(() => aggregator.Merge(null, null)); // Verify Aggregate throws if the matches or columns are null Verify.Exception <ArgumentNullException>(() => aggregator.Aggregate(null, null, new IUntypedColumn[1] { ColumnFactory.Build(new ColumnDetails("ID", "int", null), 100) })); if (requiresColumns) { ShortSet sample = new ShortSet(100); sample.Or(new ushort[] { 1, 2, 3 }); Verify.Exception <ArgumentException>(() => aggregator.Aggregate(null, sample, null)); } }
public void TryEvaluate(Partition partition, ShortSet result, ExecutionDetails details) { if (partition == null) { throw new ArgumentNullException("partition"); } if (result == null) { throw new ArgumentNullException("result"); } ushort itemCount = partition.Count; ShortSet expressionResults = null; ShortSet partResults = new ShortSet(itemCount); foreach (IExpression part in _set) { partResults.Clear(); part.TryEvaluate(partition, partResults, details); if (expressionResults == null) { expressionResults = new ShortSet(itemCount); expressionResults.Or(partResults); } else { expressionResults.And(partResults); } if (expressionResults.IsEmpty()) { break; } } result.Or(expressionResults); }
public void TryWhere(Operator op, bool value, ShortSet result, ExecutionDetails details) { if (result == null) { throw new ArgumentNullException("result"); } bool matchesTrue = (value == true); switch (op) { case Operator.Equals: case Operator.Matches: case Operator.MatchesExact: break; case Operator.NotEquals: matchesTrue = !matchesTrue; break; default: if (details != null) { details.AddError(ExecutionDetails.ColumnDoesNotSupportOperator, op, this.Name); } return; } if (matchesTrue) { result.Or(_trueItems); } else { result.OrNot(_trueItems); } }
public void TryEvaluate(Partition partition, ShortSet result, ExecutionDetails details) { if (details == null) { throw new ArgumentNullException("details"); } if (result == null) { throw new ArgumentNullException("result"); } if (partition == null) { throw new ArgumentNullException("partition"); } ushort itemCount = partition.Count; ShortSet partResults = new ShortSet(itemCount); _part[0].TryEvaluate(partition, partResults, details); partResults.Not(); result.Or(partResults); }
public void ShortSet_Basic() { // Constructor ShortSet s1 = new ShortSet(100); // Empty Assert.AreEqual("", String.Join(", ", s1.Values)); // Set value and enumerate s1.Add(0); Assert.AreEqual("0", String.Join(", ", s1.Values)); // Set additional values s1.Add(15); s1.Add(64); Assert.AreEqual("0, 15, 64", String.Join(", ", s1.Values)); // Clear values s1.Remove(64); Assert.AreEqual("0, 15", String.Join(", ", s1.Values)); // Or ShortSet s2 = new ShortSet(120); s2.Or(new ushort[] { 0, 1, 2 }); s1.Or(s2); Assert.AreEqual("0, 1, 2, 15", String.Join(", ", s1.Values)); Assert.AreEqual("0, 1, 2", String.Join(", ", s2.Values)); Verify.Exception <ArgumentNullException>(() => s1.Or((ShortSet)null)); Verify.Exception <ArgumentNullException>(() => s1.Or((IEnumerable <ushort>)null)); // OrNot [only 15, 16 not set, so only they should be added] ShortSet s3 = new ShortSet(100); s3.Not(); s3.Remove(15); s3.Remove(16); s1.OrNot(s3); Assert.AreEqual("0, 1, 2, 15, 16", String.Join(", ", s1.Values)); Verify.Exception <ArgumentNullException>(() => s1.OrNot((ShortSet)null)); // And s1.And(s2); s1.And(new ushort[] { 1, 2 }); Assert.AreEqual("1, 2", String.Join(", ", s1.Values)); s1.And(new ushort[] { 1 }); Assert.AreEqual("1", String.Join(", ", s1.Values)); Verify.Exception <ArgumentNullException>(() => s1.And((ShortSet)null)); Verify.Exception <ArgumentNullException>(() => s1.And((IEnumerable <ushort>)null)); // AndNot s1.Add(96); s1.Add(64); s1.AndNot(s2); s1.AndNot(new ushort[] { 96 }); Assert.AreEqual("64", String.Join(", ", s1.Values)); Verify.Exception <ArgumentNullException>(() => s1.AndNot((ShortSet)null)); Verify.Exception <ArgumentNullException>(() => s1.AndNot((IEnumerable <ushort>)null)); // Clear s1.Clear(); Assert.AreEqual("", String.Join(", ", s1.Values)); // From s1.From(s2); Assert.AreEqual("0, 1, 2", String.Join(", ", s1.Values)); Verify.Exception <ArgumentNullException>(() => s1.From((ShortSet)null)); // FromAnd ShortSet s4 = new ShortSet(100); s4.Or(new ushort[] { 1, 2, 3 }); s1.Clear(); s1.Not(); s1.FromAnd(s2, s4); Assert.AreEqual("1, 2", String.Join(", ", s1.Values)); Verify.Exception <ArgumentNullException>(() => s1.FromAnd((ShortSet)null, s2)); Verify.Exception <ArgumentNullException>(() => s1.FromAnd(s2, (ShortSet)null)); // ToString Assert.AreEqual("[1, 2]", s1.ToString()); }