Statistics
| Revision:

root / trunk / libraries / libGDBMS / src / main / java / com / hardcode / gdbms / engine / strategies / DistinctDataSource.java @ 10627

History | View | Annotate | Download (5.68 KB)

1
package com.hardcode.gdbms.engine.strategies;
2

    
3
import java.util.Comparator;
4
import java.util.TreeSet;
5

    
6
import com.hardcode.gdbms.driver.exceptions.ReadDriverException;
7
import com.hardcode.gdbms.engine.data.DataSource;
8
import com.hardcode.gdbms.engine.data.FieldNameAccessSupport;
9
import com.hardcode.gdbms.engine.data.persistence.Memento;
10
import com.hardcode.gdbms.engine.data.persistence.MementoException;
11
import com.hardcode.gdbms.engine.data.persistence.OperationLayerMemento;
12
import com.hardcode.gdbms.engine.instruction.EvaluationException;
13
import com.hardcode.gdbms.engine.instruction.Expression;
14
import com.hardcode.gdbms.engine.instruction.IncompatibleTypesException;
15
import com.hardcode.gdbms.engine.internalExceptions.InternalException;
16
import com.hardcode.gdbms.engine.internalExceptions.InternalExceptionCatcher;
17
import com.hardcode.gdbms.engine.internalExceptions.InternalExceptionEvent;
18
import com.hardcode.gdbms.engine.values.BooleanValue;
19
import com.hardcode.gdbms.engine.values.Value;
20
import com.hardcode.gdbms.engine.values.ValueCollection;
21
import com.hardcode.gdbms.engine.values.ValueFactory;
22

    
23

    
24
/**
25
 * DOCUMENT ME!
26
 *
27
 * @author Fernando Gonz?lez Cort?s
28
 */
29
public class DistinctDataSource extends OperationDataSource {
30
    private DataSource dataSource;
31
    private int[] indexes;
32
    private FieldNameAccessSupport fnaSupport = new FieldNameAccessSupport(this);
33
    private Expression[] expressions;
34

    
35
    /**
36
     * Crea un nuevo DistinctDataSource.
37
     *
38
     * @param ds DOCUMENT ME!
39
     * @param expressions DOCUMENT ME!
40
     */
41
    public DistinctDataSource(DataSource ds, Expression[] expressions) {
42
        dataSource = ds;
43
        this.expressions = expressions;
44
    }
45

    
46
    /**
47
     * @see com.hardcode.gdbms.engine.data.DataSource#start()
48
     */
49
    public void start() throws ReadDriverException {
50
        dataSource.start();
51
    }
52

    
53
    /**
54
     * @see com.hardcode.gdbms.engine.data.DataSource#stop()
55
     */
56
    public void stop() throws ReadDriverException {
57
        dataSource.stop();
58
    }
59

    
60
    /**
61
     * @see com.hardcode.gdbms.engine.data.DataSource#getMemento()
62
     */
63
    public Memento getMemento() throws MementoException {
64
        return new OperationLayerMemento(getName(),
65
            new Memento[] { dataSource.getMemento() }, getSQL());
66
    }
67

    
68
    /**
69
     * @see com.hardcode.gdbms.engine.data.DataSource#getFieldIndexByName(java.lang.String)
70
     */
71
    public int getFieldIndexByName(String fieldName) throws ReadDriverException {
72
        return fnaSupport.getFieldIndexByName(fieldName);
73
    }
74

    
75
    /**
76
     * @see com.hardcode.gdbms.engine.data.driver.ReadAccess#getFieldValue(long,
77
     *      int)
78
     */
79
    public Value getFieldValue(long rowIndex, int fieldId)
80
        throws ReadDriverException {
81
        return dataSource.getFieldValue(indexes[(int) rowIndex], fieldId);
82
    }
83

    
84
    /**
85
     * @see com.hardcode.gdbms.engine.data.driver.ReadAccess#getFieldCount()
86
     */
87
    public int getFieldCount() throws ReadDriverException {
88
        return dataSource.getFieldCount();
89
    }
90

    
91
    /**
92
     * @see com.hardcode.gdbms.engine.data.driver.ReadAccess#getFieldName(int)
93
     */
94
    public String getFieldName(int fieldId) throws ReadDriverException {
95
        return dataSource.getFieldName(fieldId);
96
    }
97

    
98
    /**
99
     * @see com.hardcode.gdbms.engine.data.driver.ReadAccess#getRowCount()
100
     */
101
    public long getRowCount() throws ReadDriverException {
102
        return indexes.length;
103
    }
104

    
105
    /**
106
     * @see com.hardcode.gdbms.engine.data.driver.ReadAccess#getFieldType(int)
107
     */
108
    public int getFieldType(int i) throws ReadDriverException {
109
        return dataSource.getFieldType(i);
110
    }
111

    
112
    /**
113
     * DOCUMENT ME!
114
     * @throws EvaluationException DOCUMENT ME!
115
     * @throws ReadDriverException TODO
116
     * @throws RuntimeException DOCUMENT ME!
117
     */
118
    public void filter() throws EvaluationException, ReadDriverException {
119
        int[] idx = new int[(int) dataSource.getRowCount()];
120
        TreeSet h = new TreeSet(new Comparator() {
121
                    public int compare(Object o1, Object o2) {
122
                        try {
123
                            Value v1 = (Value) o1;
124
                            Value v2 = (Value) o2;
125

    
126
                            if (((BooleanValue) v1.equals(v2)).getValue()) {
127
                                return 0;
128
                            } else {
129
                                return 1;
130
                            } 
131
                        } catch (IncompatibleTypesException e) {
132
                            InternalExceptionCatcher.callExceptionRaised(new InternalExceptionEvent(DistinctDataSource.this, new InternalException("Internal error calculating distinct clause", e)));
133
                            return 0;
134
                        }
135
                    }
136
                });
137
        int index = 0;
138

    
139
        for (int i = 0; i < dataSource.getRowCount(); i++) {
140
            Value[] values;
141
            if (expressions == null){
142
                values = new Value[dataSource.getFieldCount()];
143
                for (int j = 0; j < values.length; j++) {
144
                    values[j] = dataSource.getFieldValue(i, j);
145
                }
146
            } else {
147
                values = new Value[expressions.length];
148
                for (int j = 0; j < values.length; j++) {
149
                    values[j] = expressions[j].evaluate(i);
150
                }
151
            }
152

    
153
            ValueCollection vc = ValueFactory.createValue(values);
154

    
155
            if (!h.contains(vc)) {
156
                idx[index] = i;
157
                index++;
158
                h.add(vc);
159
            }
160
        }
161

    
162
        indexes = new int[index];
163
        System.arraycopy(idx, 0, indexes, 0, index);
164
    }
165

    
166
        public int getFieldWidth(int i) throws ReadDriverException {
167
        return dataSource.getFieldType(i);
168
        }
169
}