Skip to content

Commit c27c747

Browse files
committed
First SQL execution
1 parent 4a42b88 commit c27c747

39 files changed

Lines changed: 1590 additions & 73 deletions

cloudata-keyvalue/src/main/java/com/cloudata/keyvalue/KeyValueClient.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,12 +158,16 @@ public KeyValueRecordset query(long storeId) throws IOException {
158158
}
159159

160160
static class KeyValueRecordset extends StreamingRecordsetBase<KeyValueEntry> {
161+
private final DataInputStream dis;
162+
161163
public KeyValueRecordset(ClientResponse response) {
162164
super(response);
165+
InputStream is = response.getEntityInputStream();
166+
this.dis = new DataInputStream(is);
163167
}
164168

165169
@Override
166-
protected KeyValueEntry read(DataInputStream dis) throws IOException {
170+
protected KeyValueEntry read() throws IOException {
167171
int keyLength = dis.readInt();
168172
if (keyLength == -1) {
169173
return null;

cloudata-server-shared/pom.xml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,24 @@
99
<version>1.0-SNAPSHOT</version>
1010
</parent>
1111

12+
<properties>
13+
<jetty.version>9.1.0.v20131115</jetty.version>
14+
</properties>
15+
1216
<artifactId>cloudata-server-shared</artifactId>
1317

1418
<dependencies>
19+
<dependency>
20+
<groupId>org.eclipse.jetty</groupId>
21+
<artifactId>jetty-server</artifactId>
22+
<version>${jetty.version}</version>
23+
</dependency>
1524

25+
<dependency>
26+
<groupId>org.eclipse.jetty</groupId>
27+
<artifactId>jetty-webapp</artifactId>
28+
<version>${jetty.version}</version>
29+
</dependency>
1630
<dependency>
1731
<groupId>com.cloudata</groupId>
1832
<artifactId>cloudata-shared</artifactId>

cloudata-shared/pom.xml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,12 @@
4848
<groupId>com.sun.jersey</groupId>
4949
<artifactId>jersey-server</artifactId>
5050
<version>1.17.1</version>
51+
<exclusions>
52+
<exclusion>
53+
<groupId>asm</groupId>
54+
<artifactId>asm</artifactId>
55+
</exclusion>
56+
</exclusions>
5157
</dependency>
5258
<dependency>
5359
<groupId>com.sun.jersey</groupId>

cloudata-shared/src/main/java/com/cloudata/clients/StreamingRecordsetBase.java

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
package com.cloudata.clients;
22

3-
import java.io.DataInputStream;
43
import java.io.IOException;
5-
import java.io.InputStream;
64
import java.util.Iterator;
75
import java.util.NoSuchElementException;
86

@@ -29,9 +27,6 @@ public Iterator<V> iterator() {
2927
throw new IllegalStateException();
3028
}
3129
read = true;
32-
InputStream is = response.getEntityInputStream();
33-
34-
final DataInputStream dis = new DataInputStream(is);
3530

3631
return new Iterator<V>() {
3732
V next;
@@ -66,7 +61,7 @@ private void ensureHaveNext() {
6661
if (next == null) {
6762
if (!done) {
6863
try {
69-
next = read(dis);
64+
next = read();
7065
} catch (IOException e) {
7166
throw Throwables.propagate(e);
7267
}
@@ -81,5 +76,5 @@ private void ensureHaveNext() {
8176

8277
}
8378

84-
protected abstract V read(DataInputStream dis) throws IOException;
79+
protected abstract V read() throws IOException;
8580
}

cloudata-structured/src/main/java/com/cloudata/structured/StructuredClient.java

Lines changed: 86 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,15 @@
55
import java.io.IOException;
66
import java.io.InputStream;
77
import java.io.InputStreamReader;
8+
import java.util.Arrays;
89

910
import javax.ws.rs.core.MediaType;
1011

1112
import org.slf4j.Logger;
1213
import org.slf4j.LoggerFactory;
1314

1415
import com.cloudata.clients.StreamingRecordsetBase;
16+
import com.cloudata.structured.sql.value.ValueHolder;
1517
import com.cloudata.util.ByteStringMessageBodyWriter;
1618
import com.cloudata.util.GsonObjectMessageBodyHandler;
1719
import com.cloudata.util.Hex;
@@ -20,6 +22,7 @@
2022
import com.google.gson.JsonObject;
2123
import com.google.gson.JsonParser;
2224
import com.google.protobuf.ByteString;
25+
import com.google.protobuf.CodedInputStream;
2326
import com.sun.jersey.api.client.Client;
2427
import com.sun.jersey.api.client.ClientResponse;
2528
import com.sun.jersey.api.client.config.ClientConfig;
@@ -141,13 +144,43 @@ public KeyValueJsonRecordset queryJson(long storeId) throws IOException {
141144
}
142145
}
143146

147+
public RowRecordset queryJson(long storeId, String sql) throws IOException {
148+
ClientResponse response = CLIENT.resource(url).path(toUrlPath(storeId) + "/sql").queryParam("sql", sql)
149+
.accept(MediaType.APPLICATION_JSON_TYPE).get(ClientResponse.class);
150+
151+
try {
152+
int status = response.getStatus();
153+
154+
switch (status) {
155+
case 200:
156+
break;
157+
158+
default:
159+
throw new IllegalStateException("Unexpected status: " + status);
160+
}
161+
162+
RowRecordset records = new RowRecordset(response);
163+
response = null;
164+
return records;
165+
} finally {
166+
if (response != null) {
167+
response.close();
168+
}
169+
}
170+
}
171+
144172
public static class KeyValueJsonRecordset extends StreamingRecordsetBase<KeyValueJsonEntry> {
173+
private final DataInputStream dis;
174+
145175
public KeyValueJsonRecordset(ClientResponse response) {
146176
super(response);
177+
178+
InputStream is = response.getEntityInputStream();
179+
this.dis = new DataInputStream(is);
147180
}
148181

149182
@Override
150-
protected KeyValueJsonEntry read(DataInputStream dis) throws IOException {
183+
protected KeyValueJsonEntry read() throws IOException {
151184
int keyLength = dis.readInt();
152185
if (keyLength == -1) {
153186
return null;
@@ -165,6 +198,58 @@ protected KeyValueJsonEntry read(DataInputStream dis) throws IOException {
165198
}
166199
}
167200

201+
public static class RowRecordset extends StreamingRecordsetBase<RowEntry> {
202+
private final CodedInputStream cis;
203+
204+
public RowRecordset(ClientResponse response) {
205+
super(response);
206+
207+
InputStream is = response.getEntityInputStream();
208+
this.cis = CodedInputStream.newInstance(is);
209+
}
210+
211+
@Override
212+
protected RowEntry read() throws IOException {
213+
int rowCount = cis.readRawVarint32();
214+
if (rowCount == -1) {
215+
return null;
216+
}
217+
218+
ValueHolder[] values = new ValueHolder[rowCount];
219+
for (int i = 0; i < rowCount; i++) {
220+
values[i] = new ValueHolder();
221+
}
222+
223+
for (int i = 0; i < rowCount; i++) {
224+
values[i].deserialize(cis);
225+
}
226+
227+
return new RowEntry(values);
228+
}
229+
}
230+
231+
public static class RowEntry {
232+
final ValueHolder[] values;
233+
234+
public RowEntry(ValueHolder[] values) {
235+
this.values = values;
236+
}
237+
238+
public int size() {
239+
return values.length;
240+
}
241+
242+
public ValueHolder get(int i) {
243+
return values[i];
244+
}
245+
246+
@Override
247+
public String toString() {
248+
return "RowEntry [values=" + Arrays.toString(values) + "]";
249+
}
250+
251+
}
252+
168253
private String toUrlPath(long storeId, ByteString key) {
169254
return Long.toString(storeId) + "/" + Hex.toHex(key);
170255
}

cloudata-structured/src/main/java/com/cloudata/structured/StructuredServer.java

Lines changed: 38 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,36 @@
11
package com.cloudata.structured;
22

33
import java.io.File;
4+
import java.util.EnumSet;
45
import java.util.List;
56

7+
import javax.servlet.DispatcherType;
8+
9+
import org.eclipse.jetty.server.Server;
10+
import org.eclipse.jetty.servlet.FilterHolder;
11+
import org.eclipse.jetty.servlet.ServletContextHandler;
612
import org.robotninjas.barge.ClusterConfig;
713
import org.robotninjas.barge.RaftService;
814
import org.robotninjas.barge.Replica;
15+
import org.slf4j.Logger;
16+
import org.slf4j.LoggerFactory;
917

1018
import com.cloudata.structured.web.WebModule;
1119
import com.google.common.collect.Lists;
1220
import com.google.inject.Guice;
1321
import com.google.inject.Injector;
14-
import com.sun.grizzly.http.SelectorThread;
15-
import com.sun.jersey.api.container.grizzly.GrizzlyServerFactory;
16-
import com.sun.jersey.api.core.PackagesResourceConfig;
17-
import com.sun.jersey.api.core.ResourceConfig;
18-
import com.sun.jersey.core.spi.component.ioc.IoCComponentProviderFactory;
19-
import com.sun.jersey.guice.spi.container.GuiceComponentProviderFactory;
22+
import com.google.inject.servlet.GuiceFilter;
2023

2124
public class StructuredServer {
2225

26+
private static final Logger log = LoggerFactory.getLogger(StructuredServer.class);
27+
2328
final File baseDir;
2429
final int httpPort;
2530
private final Replica local;
2631
private final List<Replica> peers;
2732
private RaftService raft;
28-
private SelectorThread selector;
33+
private Server jetty;
2934

3035
public StructuredServer(File baseDir, Replica local, List<Replica> peers, int httpPort) {
3136
this.baseDir = baseDir;
@@ -35,7 +40,7 @@ public StructuredServer(File baseDir, Replica local, List<Replica> peers, int ht
3540
}
3641

3742
public synchronized void start() throws Exception {
38-
if (raft != null || selector != null) {
43+
if (raft != null || jetty != null) {
3944
throw new IllegalStateException();
4045
}
4146

@@ -58,10 +63,23 @@ public synchronized void start() throws Exception {
5863

5964
Injector injector = Guice.createInjector(new StructuredStoreModule(stateMachine), new WebModule());
6065

61-
ResourceConfig rc = new PackagesResourceConfig(WebModule.class.getPackage().getName());
62-
IoCComponentProviderFactory ioc = new GuiceComponentProviderFactory(rc, injector);
66+
// ResourceConfig rc = new PackagesResourceConfig(WebModule.class.getPackage().getName());
67+
// IoCComponentProviderFactory ioc = new GuiceComponentProviderFactory(rc, injector);
68+
//
69+
// this.selector = GrizzlyServerFactory.create(baseUri, rc, ioc);
70+
//
71+
72+
this.jetty = new Server(httpPort);
73+
74+
ServletContextHandler context = new ServletContextHandler();
75+
context.setContextPath("/");
76+
77+
FilterHolder filterHolder = new FilterHolder(injector.getInstance(GuiceFilter.class));
78+
context.addFilter(filterHolder, "*", EnumSet.of(DispatcherType.REQUEST));
79+
80+
jetty.setHandler(context);
6381

64-
this.selector = GrizzlyServerFactory.create(baseUri, rc, ioc);
82+
jetty.start();
6583
}
6684

6785
public String getHttpUrl() {
@@ -85,15 +103,19 @@ public static void main(String... args) throws Exception {
85103
Runtime.getRuntime().addShutdownHook(new Thread() {
86104
@Override
87105
public void run() {
88-
server.stop();
106+
try {
107+
server.stop();
108+
} catch (Exception e) {
109+
log.warn("Error shutting down HTTP server", e);
110+
}
89111
}
90112
});
91113
}
92114

93-
public synchronized void stop() {
94-
if (selector != null) {
95-
selector.stopEndpoint();
96-
selector = null;
115+
public synchronized void stop() throws Exception {
116+
if (jetty != null) {
117+
jetty.stop();
118+
jetty = null;
97119
}
98120

99121
if (raft != null) {

cloudata-structured/src/main/java/com/cloudata/structured/StructuredStateMachine.java

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,11 @@ public class StructuredStateMachine implements StateMachine {
3434

3535
private RaftService raft;
3636
private File baseDir;
37-
final LoadingCache<Long, StructuredStore> keyValueStoreCache;
37+
final LoadingCache<Long, StructuredStore> storeCache;
3838

3939
public StructuredStateMachine() {
40-
KeyValueStoreCacheLoader loader = new KeyValueStoreCacheLoader();
41-
this.keyValueStoreCache = CacheBuilder.newBuilder().recordStats().build(loader);
40+
StoreCacheLoader loader = new StoreCacheLoader();
41+
this.storeCache = CacheBuilder.newBuilder().recordStats().build(loader);
4242
}
4343

4444
public void init(RaftService raft, File stateDir) {
@@ -84,7 +84,7 @@ public Object applyOperation(@Nonnull ByteBuffer op) {
8484
ByteString key = entry.getKey();
8585
ByteString value = entry.getValue();
8686

87-
StructuredStore keyValueStore = getKeyValueStore(storeId);
87+
StructuredStore keyValueStore = getStructuredStore(storeId);
8888

8989
StructuredOperation<?> operation;
9090

@@ -115,16 +115,16 @@ public Object applyOperation(@Nonnull ByteBuffer op) {
115115
}
116116
}
117117

118-
private StructuredStore getKeyValueStore(long id) {
118+
public StructuredStore getStructuredStore(long id) {
119119
try {
120-
return keyValueStoreCache.get(id);
120+
return storeCache.get(id);
121121
} catch (ExecutionException e) {
122122
throw Throwables.propagate(e);
123123
}
124124
}
125125

126126
@Immutable
127-
final class KeyValueStoreCacheLoader extends CacheLoader<Long, StructuredStore> {
127+
final class StoreCacheLoader extends CacheLoader<Long, StructuredStore> {
128128

129129
@Override
130130
public StructuredStore load(@Nonnull Long id) throws Exception {
@@ -145,12 +145,12 @@ public StructuredStore load(@Nonnull Long id) throws Exception {
145145
}
146146

147147
public Value get(long storeId, Keyspace keyspace, ByteString key) {
148-
StructuredStore keyValueStore = getKeyValueStore(storeId);
148+
StructuredStore keyValueStore = getStructuredStore(storeId);
149149
return keyValueStore.get(keyspace.mapToKey(key).asReadOnlyByteBuffer());
150150
}
151151

152152
public BtreeQuery scan(long storeId, Keyspace keyspace) {
153-
StructuredStore keyValueStore = getKeyValueStore(storeId);
153+
StructuredStore keyValueStore = getStructuredStore(storeId);
154154
return keyValueStore.buildQuery(keyspace);
155155
}
156156

cloudata-structured/src/main/java/com/cloudata/structured/StructuredStore.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,4 +120,8 @@ private static byte[] encode(long id) {
120120
return data;
121121
}
122122

123+
public Btree getBtree() {
124+
return btree;
125+
}
126+
123127
}

0 commit comments

Comments
 (0)