From 6513a04b24db5d2e7fc2b62ecadb8a2becedffc4 Mon Sep 17 00:00:00 2001 From: "Brian S. O'Neill" Date: Sun, 28 Jan 2007 21:25:21 +0000 Subject: Fixed bug when filtering against negative floating point values. --- .../carbonado/cursor/TestFilteredCursor.java | 426 +++++++++++++++++++++ 1 file changed, 426 insertions(+) create mode 100644 src/test/java/com/amazon/carbonado/cursor/TestFilteredCursor.java (limited to 'src') diff --git a/src/test/java/com/amazon/carbonado/cursor/TestFilteredCursor.java b/src/test/java/com/amazon/carbonado/cursor/TestFilteredCursor.java new file mode 100644 index 0000000..82854c2 --- /dev/null +++ b/src/test/java/com/amazon/carbonado/cursor/TestFilteredCursor.java @@ -0,0 +1,426 @@ +/* + * Copyright 2007 Amazon Technologies, Inc. or its affiliates. + * Amazon, Amazon.com and Carbonado are trademarks or registered trademarks + * of Amazon Technologies, Inc. or its affiliates. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.amazon.carbonado.cursor; + +import java.util.Arrays; +import java.util.Iterator; +import java.util.List; + +import junit.framework.TestCase; +import junit.framework.TestSuite; + +import com.amazon.carbonado.*; +import com.amazon.carbonado.filter.*; + +import com.amazon.carbonado.repo.toy.ToyRepository; + +/** + * + * + * @author Brian S O'Neill + */ +public class TestFilteredCursor extends TestCase { + public static void main(String[] args) { + junit.textui.TestRunner.run(suite()); + } + + public static TestSuite suite() { + return new TestSuite(TestFilteredCursor.class); + } + + public TestFilteredCursor(String name) { + super(name); + } + + protected void setUp() { + } + + protected void tearDown() { + } + + public void testFloat() throws Exception { + // Tests that float values are compared properly because the + // implementation compares against float bits. + + Repository repo = new ToyRepository(); + Storage storage = repo.storageFor(FloatRecord.class); + + float[] floats = { + 0.0f, -0.0f, 5.0f, 5.1f, -10.1f, -10.2f, + 0.0f/0.0f, 1.0f/0.0f, -1.0f/0.0f + }; + + for (int i=0; i filter = Filter.filterFor(FloatRecord.class, "floatValue < ?").bind(); + + testFloatFilter(storage, filter, 0.0f, -0.0f, -10.1f, -10.2f, -1.0f/0.0f); + testFloatFilter(storage, filter, -0.0f, -10.1f, -10.2f, -1.0f/0.0f); + testFloatFilter(storage, filter, 5.0f, 0.0f, -0.0f, -10.1f, -10.2f, -1.0f/0.0f); + testFloatFilter(storage, filter, 5.1f, 5.0f, 0.0f, -0.0f, -10.1f, -10.2f, -1.0f/0.0f); + testFloatFilter(storage, filter, -10.1f, -10.2f, -1.0f/0.0f); + testFloatFilter(storage, filter, -10.2f, -1.0f/0.0f); + testFloatFilter(storage, filter, 0.0f/0.0f, + 0.0f, -0.0f, 5.0f, 5.1f, -10.1f, -10.2f, 1.0f/0.0f, -1.0f/0.0f); + testFloatFilter(storage, filter, 1.0f/0.0f, + 0.0f, -0.0f, 5.0f, 5.1f, -10.1f, -10.2f, -1.0f/0.0f); + testFloatFilter(storage, filter, -1.0f/0.0f); + } + + private void testFloatFilter(Storage storage, Filter filter, + float filterValue, float... expected) + throws Exception + { + Cursor all = storage.query().fetch(); + + Cursor filtered = FilteredCursor + .applyFilter(filter, filter.initialFilterValues().with(filterValue), all); + + List records = filtered.toList(); + + float[] actual = new float[records.size()]; + for (int i=0; i storage = repo.storageFor(FloatObjRecord.class); + + Float[] floats = { + 0.0f, -0.0f, 5.0f, 5.1f, -10.1f, -10.2f, + 0.0f/0.0f, 1.0f/0.0f, -1.0f/0.0f, null + }; + + for (int i=0; i filter = Filter + .filterFor(FloatObjRecord.class, "floatValue < ?").bind(); + + testFloatFilter(storage, filter, 0.0f, -0.0f, -10.1f, -10.2f, -1.0f/0.0f); + testFloatFilter(storage, filter, -0.0f, -10.1f, -10.2f, -1.0f/0.0f); + testFloatFilter(storage, filter, 5.0f, 0.0f, -0.0f, -10.1f, -10.2f, -1.0f/0.0f); + testFloatFilter(storage, filter, 5.1f, 5.0f, 0.0f, -0.0f, -10.1f, -10.2f, -1.0f/0.0f); + testFloatFilter(storage, filter, -10.1f, -10.2f, -1.0f/0.0f); + testFloatFilter(storage, filter, -10.2f, -1.0f/0.0f); + testFloatFilter(storage, filter, 0.0f/0.0f, + 0.0f, -0.0f, 5.0f, 5.1f, -10.1f, -10.2f, 1.0f/0.0f, -1.0f/0.0f); + testFloatFilter(storage, filter, 1.0f/0.0f, + 0.0f, -0.0f, 5.0f, 5.1f, -10.1f, -10.2f, -1.0f/0.0f); + testFloatFilter(storage, filter, -1.0f/0.0f); + testFloatFilter(storage, filter, null, + 0.0f, -0.0f, 5.0f, 5.1f, -10.1f, -10.2f, + 0.0f/0.0f, 1.0f/0.0f, -1.0f/0.0f); + + filter = Filter.filterFor(FloatObjRecord.class, "floatValue <= ?").bind(); + + testFloatFilter(storage, filter, 0.0f, 0.0f, -0.0f, -10.1f, -10.2f, -1.0f/0.0f); + testFloatFilter(storage, filter, -0.0f, -0.0f, -10.1f, -10.2f, -1.0f/0.0f); + testFloatFilter(storage, filter, 5.0f, 0.0f, 5.0f, -0.0f, -10.1f, -10.2f, -1.0f/0.0f); + testFloatFilter(storage, filter, 5.1f, + 5.0f, 0.0f, 5.1f, -0.0f, -10.1f, -10.2f, -1.0f/0.0f); + testFloatFilter(storage, filter, -10.1f, -10.1f, -10.2f, -1.0f/0.0f); + testFloatFilter(storage, filter, -10.2f, -10.2f, -1.0f/0.0f); + testFloatFilter(storage, filter, 0.0f/0.0f, + 0.0f/0.0f, 0.0f, -0.0f, 5.0f, 5.1f, -10.1f, -10.2f, 1.0f/0.0f, -1.0f/0.0f); + testFloatFilter(storage, filter, 1.0f/0.0f, + 1.0f/0.0f, 0.0f, -0.0f, 5.0f, 5.1f, -10.1f, -10.2f, -1.0f/0.0f); + testFloatFilter(storage, filter, -1.0f/0.0f, -1.0f/0.0f); + testFloatFilter(storage, filter, null, + 0.0f, -0.0f, 5.0f, 5.1f, -10.1f, -10.2f, + 0.0f/0.0f, 1.0f/0.0f, -1.0f/0.0f, null); + } + + private void testFloatFilter(Storage storage, Filter filter, + Float filterValue, Float... expected) + throws Exception + { + Cursor all = storage.query().fetch(); + + Cursor filtered = FilteredCursor + .applyFilter(filter, filter.initialFilterValues().with(filterValue), all); + + List records = filtered.toList(); + int actualCount = records.size(); + + boolean hadNull = false; + Iterator it = records.iterator(); + while (it.hasNext()) { + FloatObjRecord rec = it.next(); + if (rec.getFloatValue() == null) { + it.remove(); + hadNull = true; + } + } + + Float[] actual = new Float[records.size()]; + for (int i=0; i storage = repo.storageFor(DoubleRecord.class); + + double[] doubles = { + 0.0, -0.0, 5.0, 5.1, -10.1, -10.2, + 0.0/0.0, 1.0/0.0, -1.0/0.0 + }; + + for (int i=0; i filter = Filter + .filterFor(DoubleRecord.class, "doubleValue < ?").bind(); + + testDoubleFilter(storage, filter, 0.0, -0.0, -10.1, -10.2, -1.0/0.0); + testDoubleFilter(storage, filter, -0.0, -10.1, -10.2, -1.0/0.0); + testDoubleFilter(storage, filter, 5.0, 0.0, -0.0, -10.1, -10.2, -1.0/0.0); + testDoubleFilter(storage, filter, 5.1, 5.0, 0.0, -0.0, -10.1, -10.2, -1.0/0.0); + testDoubleFilter(storage, filter, -10.1, -10.2, -1.0/0.0); + testDoubleFilter(storage, filter, -10.2, -1.0/0.0); + testDoubleFilter(storage, filter, 0.0/0.0, + 0.0, -0.0, 5.0, 5.1, -10.1, -10.2, 1.0/0.0, -1.0/0.0); + testDoubleFilter(storage, filter, 1.0/0.0, + 0.0, -0.0, 5.0, 5.1, -10.1, -10.2, -1.0/0.0); + testDoubleFilter(storage, filter, -1.0/0.0); + } + + private void testDoubleFilter(Storage storage, Filter filter, + double filterValue, double... expected) + throws Exception + { + Cursor all = storage.query().fetch(); + + Cursor filtered = FilteredCursor + .applyFilter(filter, filter.initialFilterValues().with(filterValue), all); + + List records = filtered.toList(); + + double[] actual = new double[records.size()]; + for (int i=0; i storage = repo.storageFor(DoubleObjRecord.class); + + Double[] doubles = { + 0.0, -0.0, 5.0, 5.1, -10.1, -10.2, + 0.0/0.0, 1.0/0.0, -1.0/0.0, null + }; + + for (int i=0; i filter = Filter + .filterFor(DoubleObjRecord.class, "doubleValue < ?").bind(); + + testDoubleFilter(storage, filter, 0.0, -0.0, -10.1, -10.2, -1.0/0.0); + testDoubleFilter(storage, filter, -0.0, -10.1, -10.2, -1.0/0.0); + testDoubleFilter(storage, filter, 5.0, 0.0, -0.0, -10.1, -10.2, -1.0/0.0); + testDoubleFilter(storage, filter, 5.1, 5.0, 0.0, -0.0, -10.1, -10.2, -1.0/0.0); + testDoubleFilter(storage, filter, -10.1, -10.2, -1.0/0.0); + testDoubleFilter(storage, filter, -10.2, -1.0/0.0); + testDoubleFilter(storage, filter, 0.0/0.0, + 0.0, -0.0, 5.0, 5.1, -10.1, -10.2, 1.0/0.0, -1.0/0.0); + testDoubleFilter(storage, filter, 1.0/0.0, + 0.0, -0.0, 5.0, 5.1, -10.1, -10.2, -1.0/0.0); + testDoubleFilter(storage, filter, -1.0/0.0); + testDoubleFilter(storage, filter, null, + 0.0, -0.0, 5.0, 5.1, -10.1, -10.2, + 0.0/0.0, 1.0/0.0, -1.0/0.0); + + filter = Filter.filterFor(DoubleObjRecord.class, "doubleValue <= ?").bind(); + + testDoubleFilter(storage, filter, 0.0, 0.0, -0.0, -10.1, -10.2, -1.0/0.0); + testDoubleFilter(storage, filter, -0.0, -0.0, -10.1, -10.2, -1.0/0.0); + testDoubleFilter(storage, filter, 5.0, 0.0, 5.0, -0.0, -10.1, -10.2, -1.0/0.0); + testDoubleFilter(storage, filter, 5.1, 5.0, 0.0, 5.1, -0.0, -10.1, -10.2, -1.0/0.0); + testDoubleFilter(storage, filter, -10.1, -10.1, -10.2, -1.0/0.0); + testDoubleFilter(storage, filter, -10.2, -10.2, -1.0/0.0); + testDoubleFilter(storage, filter, 0.0/0.0, + 0.0/0.0, 0.0, -0.0, 5.0, 5.1, -10.1, -10.2, 1.0/0.0, -1.0/0.0); + testDoubleFilter(storage, filter, 1.0/0.0, + 1.0/0.0, 0.0, -0.0, 5.0, 5.1, -10.1, -10.2, -1.0/0.0); + testDoubleFilter(storage, filter, -1.0/0.0, -1.0/0.0); + testDoubleFilter(storage, filter, null, + 0.0, -0.0, 5.0, 5.1, -10.1, -10.2, + 0.0/0.0, 1.0/0.0, -1.0/0.0, null); + } + + private void testDoubleFilter(Storage storage, Filter filter, + Double filterValue, Double... expected) + throws Exception + { + Cursor all = storage.query().fetch(); + + Cursor filtered = FilteredCursor + .applyFilter(filter, filter.initialFilterValues().with(filterValue), all); + + List records = filtered.toList(); + int actualCount = records.size(); + + boolean hadNull = false; + Iterator it = records.iterator(); + while (it.hasNext()) { + DoubleObjRecord rec = it.next(); + if (rec.getDoubleValue() == null) { + it.remove(); + hadNull = true; + } + } + + Double[] actual = new Double[records.size()]; + for (int i=0; i