]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/QuerySerializer.java
Fixed multiple issues causing dangling references to discarded queries
[simantics/platform.git] / bundles / org.simantics.db.impl / src / org / simantics / db / impl / query / QuerySerializer.java
1 package org.simantics.db.impl.query;
2
3 import java.util.HashMap;
4 import java.util.Map;
5 import java.util.Map.Entry;
6
7 import org.simantics.db.impl.ClusterTraitsBase;
8
9 import gnu.trove.list.array.TByteArrayList;
10 import gnu.trove.map.hash.TLongIntHashMap;
11 import gnu.trove.procedure.TLongIntProcedure;
12
13 public class QuerySerializer {
14
15     private QueryProcessor processor;
16     private QuerySupport querySupport;
17     private TByteArrayList bytes = new TByteArrayList();
18     private TLongIntHashMap clusterKeys = new TLongIntHashMap();
19     private Map<String,Integer> ids = new HashMap<String,Integer>();
20
21     public QuerySerializer(QueryProcessor processor) {
22         this.processor = processor;
23         this.querySupport = processor.querySupport;
24     }
25
26     public int writeUnknownSize() {
27         int pos = bytes.size();
28         bytes.add((byte)0);
29         bytes.add((byte)0);
30         bytes.add((byte)0);
31         bytes.add((byte)0);
32         return pos;
33     }
34
35     public void setUnknownSize(int pos, int value) {
36         bytes.set(pos, (byte) (value & 0xFF));
37         bytes.set(pos+1, (byte) ((value >>> 8) & 0xFF));
38         bytes.set(pos+2, (byte) ((value >>> 16) & 0xFF));
39         bytes.set(pos+3, (byte) ((value >>> 24) & 0xFF));
40     }
41
42     public void serializeId(String classId) {
43         Integer id = ids.get(classId);
44         if(id == null) {
45             id = ids.size() + 1;
46             ids.put(classId, id);
47         }
48         writeLE(id);
49     }
50
51     public void addResource(int r) {
52         if(r < 0) {
53             writeLE(r);
54         } else {
55             long clusterId = querySupport.getClusterId(r);
56             int clusterKey = clusterKeys.get(clusterId);
57             if(clusterKey == 0) {
58                 clusterKey = clusterKeys.size() + 1;
59                 clusterKeys.put(clusterId, clusterKey);
60             }
61             int i = ClusterTraitsBase.createResourceKeyNoThrow(clusterKey, ClusterTraitsBase.getResourceIndexFromResourceKeyNoThrow(r));
62             writeLE(i);
63         }
64     }
65
66     public void addString(String s) {
67         byte[] b = s.getBytes();
68         writeLE(b.length);
69         bytes.add(b);
70     }
71
72     public void add(byte b) {
73         bytes.add(b);
74     }
75
76     public void add(byte[] bs) {
77         bytes.add(bs);
78     }
79
80     public byte[] bytes() {
81         TByteArrayList header = new TByteArrayList();
82         writeLE(header, ids.size());
83         for(Entry<String,Integer> entry : ids.entrySet()) {
84             String id = entry.getKey();
85             writeLE(header, id.length());
86             header.add(id.getBytes());
87             writeLE(header, entry.getValue());
88         }
89
90         writeLE(header, clusterKeys.size());
91         clusterKeys.forEachEntry(new TLongIntProcedure() {
92
93             @Override
94             public boolean execute(long a, int b) {
95                 writeLE(header, a);
96                 writeLE(header, b);
97                 return true;
98             }
99
100         });
101
102         header.add(bytes.toArray());
103         return header.toArray();
104     }
105
106     public void writeLE(int value) {
107         writeLE(bytes, value);
108     }
109
110     public static void writeLE(TByteArrayList bytes, int value) {
111         bytes.add((byte) (value & 0xFF));
112         bytes.add((byte) ((value >>> 8) & 0xFF));
113         bytes.add((byte) ((value >>> 16) & 0xFF));
114         bytes.add((byte) ((value >>> 24) & 0xFF));
115     }
116
117     public void writeLE(long value) {
118         writeLE(bytes, value);
119     }
120
121     public static void writeLE(TByteArrayList bytes, long value) {
122         bytes.add((byte) (value & 0xFF));
123         bytes.add((byte) ((value >>> 8) & 0xFF));
124         bytes.add((byte) ((value >>> 16) & 0xFF));
125         bytes.add((byte) ((value >>> 24) & 0xFF));
126         bytes.add((byte) ((value >>> 32) & 0xFF));
127         bytes.add((byte) ((value >>> 40) & 0xFF));
128         bytes.add((byte) ((value >>> 48) & 0xFF));
129         bytes.add((byte) ((value >>> 56) & 0xFF));
130     }
131
132     public QueryProcessor getQueryProcessor() {
133         return processor;
134     }
135
136 }