Statistics
| Revision:

root / trunk / libraries / libGDBMS / src / main / java / com / hardcode / gdbms / engine / data / indexes / QuickSort.java @ 10627

History | View | Annotate | Download (3.55 KB)

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

    
3
import com.hardcode.gdbms.driver.exceptions.ReadDriverException;
4
import com.hardcode.gdbms.engine.data.DataSource;
5
import com.hardcode.gdbms.engine.instruction.IncompatibleTypesException;
6
import com.hardcode.gdbms.engine.values.BooleanValue;
7
import com.hardcode.gdbms.engine.values.Value;
8

    
9
import java.io.IOException;
10

    
11
import java.util.Stack;
12

    
13

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

    
24
        /**
25
         * DOCUMENT ME!
26
         *
27
         * @param ini DOCUMENT ME!
28
         * @param fin DOCUMENT ME!
29
         *
30
         * @return DOCUMENT ME!
31
         * @throws ReadDriverException TODO
32
         * @throws IOException 
33
         */
34
        private long partition(long ini, long fin)
35
                throws ReadDriverException, IOException {
36
                long first = ini;
37
                long last = fin;
38

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

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

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

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

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

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

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

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

    
78
                return up;
79
        }
80

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

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

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

    
124
                ret = IndexFactory.createFixedIndex(high - low + 1);
125

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

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

    
134
                while (!intervalos.empty()) {
135
                        Intervalo i = (Intervalo) intervalos.pop();
136

    
137
                        long pivote = partition(i.ini, i.fin);
138

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

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

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

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

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