blob: cf5f06c13a7d55c4da14e6d0bf8ba0d136883007 [file] [log] [blame]
package accord.maelstrom;
import java.io.IOException;
import java.util.NavigableMap;
import java.util.TreeMap;
import accord.local.Node;
import accord.local.Node.Id;
import com.google.gson.TypeAdapter;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonToken;
import com.google.gson.stream.JsonWriter;
import accord.api.Key;
import accord.api.Result;
import accord.txn.Keys;
public class MaelstromResult implements Result
{
final Node.Id client;
final long requestId;
final Keys keys;
final Value[] read;
final MaelstromUpdate update;
public MaelstromResult(Id client, long requestId, Keys keys, Value[] read, MaelstromUpdate update)
{
this.client = client;
this.requestId = requestId;
this.keys = keys;
this.read = read;
this.update = update;
}
public static final TypeAdapter<Result> GSON_ADAPTER = new TypeAdapter<>()
{
@Override
public void write(JsonWriter out, Result value) throws IOException
{
if (value == null)
{
out.nullValue();
return;
}
MaelstromResult result = (MaelstromResult) value;
Keys keys = result.keys;
Value[] reads = result.read;
MaelstromUpdate update = result.update;
out.beginObject();
out.name("r");
out.beginArray();
for (int i = 0 ; i < keys.size() ; ++i)
{
MaelstromKey key = (MaelstromKey) keys.get(i);
if (reads[i] != null)
{
out.beginArray();
key.write(out);
reads[i].write(out);
out.endArray();
}
}
out.endArray();
out.name("append");
out.beginArray();
for (int i = 0 ; i < keys.size() ; ++i)
{
MaelstromKey key = (MaelstromKey) keys.get(i);
if (update != null && update.containsKey(key))
{
out.beginArray();
key.write(out);
update.get(key).write(out);
out.endArray();
}
}
out.endArray();
out.name("client");
out.value(result.client.id);
out.name("requestId");
out.value(result.requestId);
out.endObject();
}
@Override
public Result read(JsonReader in) throws IOException
{
if (in.peek() == JsonToken.NULL)
return null;
Node.Id client = null;
long requestId = Long.MIN_VALUE;
NavigableMap<Key, Value> reads = new TreeMap<>();
MaelstromUpdate update = new MaelstromUpdate();
in.beginObject();
while (in.hasNext())
{
String kind = in.nextName();
switch (kind)
{
default: throw new IllegalStateException("Invalid kind: " + kind);
case "r":
in.beginArray();
while (in.hasNext())
{
in.beginArray();
Key key = MaelstromKey.read(in);
Value value = Value.read(in);
reads.put(key, value);
in.endArray();
}
in.endArray();
break;
case "append":
in.beginArray();
while (in.hasNext())
{
in.beginArray();
Key key = MaelstromKey.read(in);
Value append = Value.read(in);
update.put(key, append);
in.endArray();
}
in.endArray();
break;
case "client":
client = Json.ID_ADAPTER.read(in);
break;
case "requestId":
requestId = in.nextLong();
break;
}
}
in.endObject();
if (client == null)
throw new IllegalStateException();
for (Key key : update.keySet())
reads.putIfAbsent(key, null);
Keys keys = new Keys(reads.keySet());
Value[] values = reads.values().toArray(new Value[0]);
return new MaelstromResult(client, requestId, keys, values, update);
}
};
}