]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.db.procore/src/org/simantics/db/procore/cluster/TableIntArraySet2.java
Help investigation of query caching problems via query histogram data
[simantics/platform.git] / bundles / org.simantics.db.procore / src / org / simantics / db / procore / cluster / TableIntArraySet2.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.procore.cluster;
13
14 import org.simantics.db.exception.DatabaseException;
15 import org.simantics.db.impl.ClusterI;
16 import org.simantics.db.impl.IntAllocatorI;
17 import org.simantics.db.impl.Modifier;
18
19 final class TableIntArraySet2 {
20     public static final int HeaderSize = 1; 
21     private static final int SIZE_OFFSET = -1;
22     static int create(final int[] keys, final int[] vals, IntAllocatorI allocator)
23     throws DatabaseException {
24         final int LENGTH = keys.length;
25         if (LENGTH < 1 || LENGTH != vals.length)
26             throw new DatabaseException("Illegal argument to create TableIntArraySet2.");
27         int newBase = allocator.allocate(LENGTH*2 + HeaderSize) + HeaderSize;
28         int[] table = allocator.getTable();
29         table[newBase + SIZE_OFFSET] = -LENGTH;
30         for (int i=0; i<LENGTH; ++i) {
31             if (0 == keys[i])
32                 throw new DatabaseException("Illegal value to create TableIntArraySet2.");
33             table[newBase + i*2] = keys[i];
34             table[newBase + i*2 + 1] = vals[i];
35         }
36         return newBase;
37     }
38     static boolean isArraySet(int[] table, int base) {
39         return table[base + SIZE_OFFSET] < 0;
40     }
41     static class Tables {
42         int[] keys;
43         int[] vals;
44         public Tables() {
45             this.keys = null;
46             this.vals = null;
47         }
48     }
49     static Tables getInts(int[] table, int base) {
50         final int REAL_SIZE = -table[base + SIZE_OFFSET];
51         assert(REAL_SIZE > 0);
52         Tables t = new Tables();
53         int i;
54         for (i=0; i<REAL_SIZE; ++i) {
55             int k = table[base + i*2];
56             if (0 == k)
57                 break;
58         }
59         final int size = i;
60         assert(size > 0);
61         t.keys = new int[size];
62         t.vals = new int[size];
63         for (i=0; i<size; ++i){
64             t.keys[i] = table[base + i*2];
65             t.vals[i] = table[base + i*2 + 1];
66         }
67         return t;
68     }
69     static int get(int[] table, int base, int aKey) {
70         final int REAL_SIZE = -table[base + SIZE_OFFSET];
71         assert(REAL_SIZE > 0);
72         for (int i=0; i<REAL_SIZE; ++i, base += 2) {
73             if (0 == table[base])
74                 return 0;
75             else if (aKey == table[base]) {
76                 return table[base + 1];
77             }
78         }
79         return 0;
80     }
81     /**
82      * @param table
83      * @param base
84      * @param key
85      * @param allocator
86      * @return new base if object was actually added.
87      */
88     static int addInt(int[] table, int base, final int key, int val, IntAllocatorI allocator) {
89         final int size = -table[base + SIZE_OFFSET];
90         assert(size > 0);
91         int i;
92         for (i=0; i<size; ++i) {
93             if (key == table[base + i*2]) {
94                 if (val == table[base + i*2 + 1])
95                     return 0;
96                 else {
97                     table[base + i*2 + 1] = val;
98                     return base;
99                 }
100             } else if (0 == table[base + i*2])
101                 break;
102         }
103         if (i < size) {
104             assert(0 == table[base + i*2]);
105             table[base + i*2] = key;
106             table[base + i*2 + 1] = val;
107             return base;
108         }
109         final int newSize = size + 1;
110         int newBase = allocator.allocate(newSize*2 + HeaderSize) + HeaderSize;
111         int[] newTable = allocator.getTable();
112         newTable[newBase + SIZE_OFFSET] = -newSize;
113         System.arraycopy(table, base, newTable, newBase, size*2);
114         newTable[newBase + size*2] = key;
115         newTable[newBase + size*2 + 1] = val;
116         return newBase;
117     }       
118     
119     static boolean removeInt(int[] table, int base, int key) {
120         final int size = -table[base + SIZE_OFFSET];
121         assert(size > 0);
122         int i;
123         for (i=0; i<size; ++i)
124             if (key == table[base + i*2])
125                 break;
126             else if (0 == table[base + i*2])
127                 return false; // not found
128         if (i == size)
129             return false; // not found
130         int end = size - 1;
131         for (;end>i; --end)
132                 if (0 != table[base + end*2])
133                         break;
134         table[base + i*2] = table[base + end*2];
135         table[base + i*2 + 1] = table[base + end*2 + 1];
136         table[base + end*2] = 0;
137         table[base + end*2 + 1] = 0;
138         return true;
139     }
140
141     static int getSize(int[] table, int base) {
142         final int size = -table[base + SIZE_OFFSET];
143         assert(size > 0);
144         int i;
145         for (i=0; i<size; ++i)
146             if (0 == table[base + i*2])
147                 break;
148         return i;
149     }
150     
151     static int getAllocatedSize(int[] table, int base) {
152         final int size = -table[base + SIZE_OFFSET];
153         assert(size>0);
154         return size + HeaderSize;
155     }
156     
157     static <Context> boolean foreachInt(final int[] table, final int base
158                 , final ClusterI.PredicateProcedure<Context> procedure, final Context context, final Modifier modifier) throws DatabaseException {
159         final int size = -table[base + SIZE_OFFSET];
160         assert(size>0);
161         for (int i=0; i<size; ++i) {
162             int pRef = table[base + i*2];
163             if (0 == pRef)
164                 break;
165             int key;
166             if (null == modifier)
167                 key = pRef;
168             else
169                 key = modifier.execute(pRef);
170             if (procedure.execute(context, key, table[base + i*2 + 1]))
171                 return true; // loop broken by procedure
172         }
173         return false; // loop finished
174     }
175 }
176