View | Details | Raw Unified | Return to bug 19203
Collapse All | Expand All

(-)java/src/org/apache/xindice/core/indexer/ValueIndexer.java (-10 / +39 lines)
Lines 177-182 Link Here
177
        return pattern;
177
        return pattern;
178
    }
178
    }
179
179
180
    /**
181
     * Creates new Value object that depends on string parameter and a type of indexer.
182
     * The idea here is that any value of any type should be transformed to a byte array
183
     * in such a way that two Values of the same type are comparable. Value objects are
184
     * compared by comparing their data arrays byte-by-byte, starting from byte with
185
     * index 0. Also, data arrays will behave as array of <b>unsigned</b> bytes with
186
     * values ranging from 0 to 255.
187
     * @param value
188
     * @return new Value object that represents specific value of this indexer type
189
     */
180
    public Value getTypedValue(String value) {
190
    public Value getTypedValue(String value) {
181
        if (type != STRING && type != TRIMMED) {
191
        if (type != STRING && type != TRIMMED) {
182
            value = value.trim();
192
            value = value.trim();
Lines 189-194 Link Here
189
            try {
199
            try {
190
                switch (type) {
200
                switch (type) {
191
                    case INTEGER:
201
                    case INTEGER:
202
                        /*
203
                            Generally, two integers can be compared byte-by-byte, returning correct results,
204
                            except negative numbers which will be always bigger than positive numbers.
205
                            To solve this, change the value to be unsigned. Number range changes from
206
                            Long.MIN_VALUE / Long.MAX_VALUE to 0 / Long.MAX_VALUE - Long.MIN_VALUE.
207
                            This is done by flipping the first bit of the byte with index 0.
208
                        */
192
                        long l = Long.parseLong(value);
209
                        long l = Long.parseLong(value);
193
                        b[0] = (byte) ((l >>> 56) & 0xFF);
210
                        b[0] = (byte) ((l >>> 56) & 0xFF);
194
                        b[1] = (byte) ((l >>> 48) & 0xFF);
211
                        b[1] = (byte) ((l >>> 48) & 0xFF);
Lines 198-219 Link Here
198
                        b[5] = (byte) ((l >>> 16) & 0xFF);
215
                        b[5] = (byte) ((l >>> 16) & 0xFF);
199
                        b[6] = (byte) ((l >>> 8) & 0xFF);
216
                        b[6] = (byte) ((l >>> 8) & 0xFF);
200
                        b[7] = (byte) ((l >>> 0) & 0xFF);
217
                        b[7] = (byte) ((l >>> 0) & 0xFF);
218
                        b[0] = (byte) (b[0] ^ 0x80);
201
                        break;
219
                        break;
202
                    case FLOAT:
220
                    case FLOAT:
221
                        /*
222
                            Float/Double number are stored according to IEEE standard 754. In short,
223
                            float numbers have the folloing format: 1 bit to indicate the sign of
224
                            the number, 8 bits for exponent, 23 bits for mantissa, and double
225
                            numbers have the following format: 1 bit to indicate the sign of
226
                            the number, 11 bits for exponent, 52 bits for mantissa. Both float and
227
                            double are normalized, so they can be compared byte-by-byte, except
228
                            that negative numbers will be bigger than positive. This is solved by
229
                            changing number sign (is is stored in the first bit).
230
                        */
203
                        double d = Double.parseDouble(value);
231
                        double d = Double.parseDouble(value);
204
                        int i1 = (int) Math.round(d);
232
                        long bits = Double.doubleToRawLongBits(d);
205
                        int i2 = (int) Math.round((d - i1) * 1000000000);
233
                        b[0] = (byte) ((bits >>> 56) & 0xFF);
206
                        b[0] = (byte) ((i1 >>> 24) & 0xFF);
234
                        b[1] = (byte) ((bits >>> 48) & 0xFF);
207
                        b[1] = (byte) ((i1 >>> 16) & 0xFF);
235
                        b[2] = (byte) ((bits >>> 40) & 0xFF);
208
                        b[2] = (byte) ((i1 >>> 8) & 0xFF);
236
                        b[3] = (byte) ((bits >>> 32) & 0xFF);
209
                        b[3] = (byte) ((i1 >>> 0) & 0xFF);
237
                        b[4] = (byte) ((bits >>> 24) & 0xFF);
210
                        b[4] = (byte) ((i2 >>> 24) & 0xFF);
238
                        b[5] = (byte) ((bits >>> 16) & 0xFF);
211
                        b[5] = (byte) ((i2 >>> 16) & 0xFF);
239
                        b[6] = (byte) ((bits >>> 8) & 0xFF);
212
                        b[6] = (byte) ((i2 >>> 8) & 0xFF);
240
                        b[7] = (byte) ((bits >>> 0) & 0xFF);
213
                        b[7] = (byte) ((i2 >>> 0) & 0xFF);
241
                        b[0] = (byte) (b[0] ^ 0x80);
214
                        break;
242
                        break;
215
                    case BYTE:
243
                    case BYTE:
216
                        b[0] = Byte.parseByte(value);
244
                        b[0] = Byte.parseByte(value);
245
                        b[0] = (byte) (b[0] ^ 0x80);
217
                        break;
246
                        break;
218
                    case CHAR:
247
                    case CHAR:
219
                        char c = value.charAt(0);
248
                        char c = value.charAt(0);
(-)java/src/org/apache/xindice/core/filer/BTree.java (-1 / +1 lines)
Lines 903-909 Link Here
903
                                    leftIdx = -(leftIdx + 1);
903
                                    leftIdx = -(leftIdx + 1);
904
                                }
904
                                }
905
                                n = Math.min(leftIdx + 1, ptrs.length);
905
                                n = Math.min(leftIdx + 1, ptrs.length);
906
                                for (int i = 0; i <= n; i++) {
906
                                for (int i = 0; i < n; i++) {
907
                                    if (query.testValue(values[i])) {
907
                                    if (query.testValue(values[i])) {
908
                                        callback.indexInfo(values[i], ptrs[i]);
908
                                        callback.indexInfo(values[i], ptrs[i]);
909
                                    }
909
                                    }
(-)java/src/org/apache/xindice/core/data/Value.java (-6 / +5 lines)
Lines 129-135 Link Here
129
    }
160
    }
130
161
131
    public boolean equals(Value value) {
162
    public boolean equals(Value value) {
132
        return len == value.len ? compareTo(value) == 0 : false;
163
        return len == value.len && compareTo(value) == 0;
133
    }
164
    }
134
165
135
    public boolean equals(Object obj) {
166
    public boolean equals(Object obj) {
Lines 154-164 Link Here
154
            byte b1 = data[pos + i];
185
            byte b1 = data[pos + i];
155
            byte b2 = ddata[dpos + i];
186
            byte b2 = ddata[dpos + i];
156
187
157
            if (b1 == b2)
188
            if (b1 != b2) {
158
                continue;
189
                // get unsigned value
159
            else {
190
                int s1 = ((int) b1) & 0xFF;
160
                short s1 = (short) (b1 >>> 0);
191
                int s2 = ((int) b2) & 0xFF;
161
                short s2 = (short) (b2 >>> 0);
162
                return s1 > s2 ? (i + 1) : -(i + 1);
192
                return s1 > s2 ? (i + 1) : -(i + 1);
163
            }
193
            }
164
        }
194
        }

Return to bug 19203