Statistics
| Revision:

svn-gvsig-desktop / trunk / libraries / libGDBMS / src / com / hardcode / gdbms / engine / data / indexes / QuickSort.java @ 466

History | View | Annotate | Download (4.36 KB)

1
package com.hardcode.gdbms.engine.data.indexes;
2

    
3
import java.io.IOException;
4
import java.util.Stack;
5

    
6
import com.hardcode.gdbms.engine.data.DataSource;
7
import com.hardcode.gdbms.engine.data.DriverException;
8
import com.hardcode.gdbms.engine.instruction.IncompatibleTypesException;
9
import com.hardcode.gdbms.engine.values.BooleanValue;
10
import com.hardcode.gdbms.engine.values.Value;
11

    
12

    
13
/**
14
 * DOCUMENT ME!
15
 *
16
 * @author Fernando Gonz?lez Cort?s
17
 */
18
public class QuickSort {
19
    private FixedIndexSet ret;
20
    private int fieldId;
21
    private DataSource dataSource;
22

    
23
    /**
24
     * DOCUMENT ME!
25
     *
26
     * @param ini DOCUMENT ME!
27
     * @param fin DOCUMENT ME!
28
     *
29
     * @return DOCUMENT ME!
30
     *
31
     * @throws DriverException
32
     * @throws IOException
33
     */
34
    private long partition(long ini, long fin)
35
        throws DriverException, IOException {
36

    
37
        long first = ini;
38
        long last = fin;
39

    
40
        long pivotIndex = first;
41
        Object pivot = dataSource.getFieldValue(ret.getIndex(pivotIndex),
42
                fieldId);
43

    
44
        long up = first;
45
        long down = last;
46

    
47
        while (up < down) {
48
            //Encuentra el primer valor > que el pivote
49
            while (compare(pivot,
50
                        dataSource.getFieldValue(ret.getIndex(up), fieldId)) <= 0) {
51
                up++;
52

    
53
                if (up > fin) {
54
                    break;
55
                }
56
            }
57

    
58
            //Encuentra el primer valor <= que el pivote
59
            while (compare(pivot,
60
                        dataSource.getFieldValue(ret.getIndex(down), fieldId)) > 0) {
61
                down--;
62

    
63
                if (down < ini) {
64
                    break;
65
                }
66
            }
67

    
68
            if (up < down) {
69
                long aux = ret.getIndex(up);
70
                ret.setIndex(up, ret.getIndex(down));
71
                ret.setIndex(down, aux);
72
            }
73
        }
74

    
75
        long aux = ret.getIndex(pivotIndex);
76
        ret.setIndex(pivotIndex, ret.getIndex(down));
77
        ret.setIndex(down, aux);
78

    
79
        return up;
80
    }
81

    
82
    /**
83
     * DOCUMENT ME!
84
     *
85
     * @param o1 DOCUMENT ME!
86
     * @param o2 DOCUMENT ME!
87
     *
88
     * @return DOCUMENT ME!
89
     *
90
     * @throws RuntimeException DOCUMENT ME!
91
     */
92
    private int compare(Object o1, Object o2) {
93
        Value v1 = (Value) o1;
94
        Value v2 = (Value) o2;
95

    
96
        try {
97
            if (((BooleanValue) v1.less(v2)).getValue()) {
98
                return -1;
99
            } else if (((BooleanValue) v2.less(v1)).getValue()) {
100
                return 1;
101
            } else {
102
                return 0;
103
            }
104
        } catch (IncompatibleTypesException e) {
105
            throw new RuntimeException(
106
                "Como incompatibles si se indexa sobre la misma columna?");
107
        }
108
    }
109

    
110
    /**
111
     * DOCUMENT ME!
112
     *
113
     * @param v DOCUMENT ME!
114
     * @param fieldId DOCUMENT ME!
115
     * @param low DOCUMENT ME!
116
     * @param high DOCUMENT ME!
117
     *
118
     * @throws DriverException
119
     * @throws IOException
120
     */
121
    public void quickSort(DataSource v, int fieldId, long low, long high)
122
        throws DriverException, IOException {
123
        dataSource = v;
124
        this.fieldId = fieldId;
125

    
126
        ret = IndexFactory.createFixedIndex(high - low + 1);
127

    
128
        for (int i = 0; i < ret.getIndexCount(); i++) {
129
            ret.setIndex(i, i);
130
        }
131

    
132
        Stack intervalos = new Stack();
133
        Intervalo inicial = new Intervalo(low, high);
134
        intervalos.push(inicial);
135

    
136
        while (!intervalos.empty()) {
137
            Intervalo i = (Intervalo) intervalos.pop();
138

    
139
            long pivote = partition(i.ini, i.fin);
140

    
141
            if (i.ini < (pivote - 1)) {
142
                intervalos.push(new Intervalo(i.ini, pivote - 2));
143
            }
144

    
145
            if ((pivote + 1) < i.fin) {
146
                intervalos.push(new Intervalo(pivote, i.fin));
147
            }
148
        }
149
    }
150

    
151
    /**
152
     * DOCUMENT ME!
153
     *
154
     * @return Returns the indexes.
155
     */
156
    public FixedIndexSet getIndexes() {
157
        return ret;
158
    }
159

    
160
    /**
161
     * DOCUMENT ME!
162
     *
163
     * @author Fernando Gonz?lez Cort?s
164
     */
165
    public class Intervalo {
166
        long ini;
167
        long fin;
168

    
169
        /**
170
         * Crea un nuevo Intervalo.
171
         *
172
         * @param ini DOCUMENT ME!
173
         * @param fin DOCUMENT ME!
174
         */
175
        public Intervalo(long ini, long fin) {
176
            this.ini = ini;
177
            this.fin = fin;
178
        }
179
    }
180
}