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

(-)java/src/org/apache/xindice/core/indexer/ValueIndexer.java (-11 / +56 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 197-219 Link Here
197
                        b[4] = (byte) ((l >>> 24) & 0xFF);
214
                        b[4] = (byte) ((l >>> 24) & 0xFF);
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 & 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 comparing two negative numbers or two number with different signs
229
                            will return incorrect results.
230
                            This is solved by changing number sign (is is stored in the first bit)
231
                            and flipping all the bits for negative numbers.
232
                        */
203
                        double d = Double.parseDouble(value);
233
                        double d = Double.parseDouble(value);
204
                        int i1 = (int) Math.round(d);
234
                        long bits = Double.doubleToLongBits(d);
205
                        int i2 = (int) Math.round((d - i1) * 1000000000);
235
206
                        b[0] = (byte) ((i1 >>> 24) & 0xFF);
236
                        b[0] = (byte) ((bits >>> 56) & 0xFF);
207
                        b[1] = (byte) ((i1 >>> 16) & 0xFF);
237
                        if ((b[0] & 0xFF) != 0) {
208
                        b[2] = (byte) ((i1 >>> 8) & 0xFF);
238
                            // negative numbers
209
                        b[3] = (byte) ((i1 >>> 0) & 0xFF);
239
                            b[0] ^= 0xFF;
210
                        b[4] = (byte) ((i2 >>> 24) & 0xFF);
240
                            b[1] = (byte) ((bits >>> 48) & 0xFF ^ 0xFF);
211
                        b[5] = (byte) ((i2 >>> 16) & 0xFF);
241
                            b[2] = (byte) ((bits >>> 40) & 0xFF ^ 0xFF);
212
                        b[6] = (byte) ((i2 >>> 8) & 0xFF);
242
                            b[3] = (byte) ((bits >>> 32) & 0xFF ^ 0xFF);
213
                        b[7] = (byte) ((i2 >>> 0) & 0xFF);
243
                            b[4] = (byte) ((bits >>> 24) & 0xFF ^ 0xFF);
244
                            b[5] = (byte) ((bits >>> 16) & 0xFF ^ 0xFF);
245
                            b[6] = (byte) ((bits >>> 8) & 0xFF ^ 0xFF);
246
                            b[7] = (byte) (bits & 0xFF ^ 0xFF);
247
                        } else {
248
                            b[0] ^= 0x80;
249
                            b[1] = (byte) ((bits >>> 48) & 0xFF);
250
                            b[2] = (byte) ((bits >>> 40) & 0xFF);
251
                            b[3] = (byte) ((bits >>> 32) & 0xFF);
252
                            b[4] = (byte) ((bits >>> 24) & 0xFF);
253
                            b[5] = (byte) ((bits >>> 16) & 0xFF);
254
                            b[6] = (byte) ((bits >>> 8) & 0xFF);
255
                            b[7] = (byte) (bits & 0xFF);
256
                        }
257
214
                        break;
258
                        break;
215
                    case BYTE:
259
                    case BYTE:
216
                        b[0] = Byte.parseByte(value);
260
                        b[0] = Byte.parseByte(value);
261
                        b[0] = (byte) (b[0] ^ 0x80);
217
                        break;
262
                        break;
218
                    case CHAR:
263
                    case CHAR:
219
                        char c = value.charAt(0);
264
                        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/filer/BTreeFiler.java (-1 / +1 lines)
Lines 61-67 Link Here
61
 *
61
 *
62
 * @version $Revision$, $Date$
62
 * @version $Revision$, $Date$
63
 */
63
 */
64
public final class BTreeFiler extends BTree
64
public class BTreeFiler extends BTree
65
                              implements Filer {
65
                              implements Filer {
66
66
67
    private static final Log log = LogFactory.getLog(BTreeFiler.class);
67
    private static final Log log = LogFactory.getLog(BTreeFiler.class);
(-)java/src/org/apache/xindice/core/data/Value.java (-5 / +4 lines)
Lines 187-197 Link Here
187
            byte b1 = data[pos + i];
187
            byte b1 = data[pos + i];
188
            byte b2 = ddata[dpos + i];
188
            byte b2 = ddata[dpos + i];
189
189
190
            if (b1 == b2)
190
            if (b1 != b2) {
191
                continue;
191
                // get unsigned value
192
            else {
192
                int s1 = ((int) b1) & 0xFF;
193
                short s1 = (short) (b1 >>> 0);
193
                int s2 = ((int) b2) & 0xFF;
194
                short s2 = (short) (b2 >>> 0);
195
                return s1 > s2 ? (i + 1) : -(i + 1);
194
                return s1 > s2 ? (i + 1) : -(i + 1);
196
            }
195
            }
197
        }
196
        }

Return to bug 19203