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 |
} |