]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/genericrelation/combinators/Selection.java
Fixed all line endings of the repository
[simantics/platform.git] / bundles / org.simantics.db.layer0 / src / org / simantics / db / layer0 / genericrelation / combinators / Selection.java
1 /*******************************************************************************
2  * Copyright (c) 2007, 2010 Association for Decentralized Information Management
3  * in Industry THTH ry.
4  * All rights reserved. This program and the accompanying materials
5  * are made available under the terms of the Eclipse Public License v1.0
6  * which accompanies this distribution, and is available at
7  * http://www.eclipse.org/legal/epl-v10.html
8  *
9  * Contributors:
10  *     VTT Technical Research Centre of Finland - initial API and implementation
11  *******************************************************************************/
12 package org.simantics.db.layer0.genericrelation.combinators;
13
14 import gnu.trove.list.array.TIntArrayList;
15
16 import java.util.ArrayList;
17 import java.util.List;
18
19 import org.simantics.db.ReadGraph;
20 import org.simantics.db.exception.DatabaseException;
21 import org.simantics.db.layer0.adapter.GenericRelation;
22 import org.simantics.db.layer0.genericrelation.AbstractRelation;
23 import org.simantics.utils.datastructures.Pair;
24
25 /**
26  * Selects tuples from the relation by fixing certain fields.
27  * Also projects the relation to unfixed fields. 
28  * 
29  * Do not use this class directly, because relations have often
30  * optimized selection methods, but use IRelation.select method.
31  */
32 public class Selection extends AbstractRelation {
33         
34         AbstractRelation base;
35         int baseLength;
36         int[] constantPositions;
37         int[] variablePositions;
38         Object[] constants;
39         
40         public Selection(AbstractRelation base, String bindingPattern,
41                         Object[] constants) {
42                 this.base = base;
43                 TIntArrayList constantPositionArray = new TIntArrayList();
44                 TIntArrayList variablePositionsArray = new TIntArrayList();
45                 baseLength = bindingPattern.length();
46                 for(int i=0;i<baseLength;++i)
47                         switch(bindingPattern.charAt(i)) {
48                         case 'b': constantPositionArray.add(i); break;
49                         case 'v': variablePositionsArray.add(i); break;
50                         }
51                 constantPositions = constantPositionArray.toArray();
52                 variablePositions = variablePositionsArray.toArray();
53                 this.constants = constants;
54         }
55
56         @Override
57         public boolean contains(ReadGraph g, Object[] tuple) throws DatabaseException {
58                 assert(tuple.length == variablePositions.length);
59                 Object[] temp = new Object[baseLength];
60                 for(int i=0;i<constantPositions.length;++i)
61                         temp[constantPositions[i]] = constants[i];
62                 for(int i=0;i<variablePositions.length;++i)
63                         temp[variablePositions[i]] = tuple[i];
64                 return base.contains(g, temp);
65         }
66
67         @Override
68         public boolean isRealizable() {
69                 return base.isRealizable();
70         }
71
72         @Override
73         public List<Object[]> realize(ReadGraph g) throws DatabaseException {
74                 ArrayList<Object[]> result = new ArrayList<Object[]>(); 
75                 loop:
76                 for(Object[] tuple : base.realize(g)) {
77                         for(int i=0;i<constantPositions.length;++i)
78                                 if(!constants[i].equals(tuple[constantPositions[i]]))
79                                         continue loop;
80                         Object[] temp = new Object[variablePositions.length];
81                         for(int i=0;i<variablePositions.length;++i)
82                                 temp[i] = tuple[variablePositions[i]];
83                         result.add(temp);
84                 }
85                 return result;
86         }
87
88         @Override
89         public GenericRelation select(String bindingPattern, Object[] givenConstants) {
90                 assert(bindingPattern.length() == variablePositions.length);
91                 char[] baseBindingPattern = new char[baseLength];
92                 Object[] baseConstants = new Object[baseLength];
93                 for(int i=0;i<constantPositions.length;++i) {
94                         baseBindingPattern[constantPositions[i]] = 'b';
95                         baseConstants[constantPositions[i]] = constants[i];
96                 }
97                 int j = 0;
98                 for(int i=0;i<variablePositions.length;++i) {
99                         char c = baseBindingPattern[variablePositions[i]] = bindingPattern.charAt(i);
100                         if(c == 'b')
101                                 baseConstants[constantPositions[i]] = givenConstants[j++];
102                 }
103                 assert(j == givenConstants.length);
104                 return base.select(new String(baseBindingPattern), constants);
105         }
106
107         @SuppressWarnings("unchecked")
108     @Override
109         public Pair<String, String>[] getFields() {
110                 Pair<String, String>[] baseFields = base.getFields();
111                 Pair<String, String>[] result = new Pair[variablePositions.length];
112                 for(int i=0;i<variablePositions.length;++i)
113                         result[i] = baseFields[variablePositions[i]];
114                 return result;
115         }       
116         
117 }