An in-memory implementation of state.
| 31 | * An in-memory implementation of state. |
| 32 | */ |
| 33 | public class InMemoryState implements State { |
| 34 | @Override |
| 35 | public Future<Variable> fetch(String name) { |
| 36 | Entry entry = entries.get(name); // Is null if doesn't exist. |
| 37 | |
| 38 | if (entry == null) { |
| 39 | entry = new Entry(); |
| 40 | entry.name = name; |
| 41 | entry.uuid = UUID.randomUUID(); |
| 42 | entry.value = new byte[0]; |
| 43 | |
| 44 | // We use 'putIfAbsent' because multiple threads might be |
| 45 | // attempting to fetch a "new" variable at the same time. |
| 46 | if (entries.putIfAbsent(name, entry) != null) { |
| 47 | return fetch(name); |
| 48 | } |
| 49 | } |
| 50 | |
| 51 | assert entry != null; |
| 52 | |
| 53 | return futureFrom((Variable) new InMemoryVariable(entry)); |
| 54 | } |
| 55 | |
| 56 | @Override |
| 57 | public Future<Variable> store(Variable v) { |
| 58 | InMemoryVariable variable = (InMemoryVariable) v; |
| 59 | |
| 60 | Entry entry = new Entry(); |
| 61 | entry.name = variable.entry.name; |
| 62 | entry.uuid = UUID.randomUUID(); |
| 63 | entry.value = variable.value; |
| 64 | |
| 65 | if (entries.replace(entry.name, variable.entry, entry)) { |
| 66 | return futureFrom((Variable) new InMemoryVariable(entry)); |
| 67 | } |
| 68 | |
| 69 | return futureFrom((Variable) null); |
| 70 | } |
| 71 | |
| 72 | @Override |
| 73 | public Future<Boolean> expunge(Variable v) { |
| 74 | InMemoryVariable variable = (InMemoryVariable) v; |
| 75 | |
| 76 | return futureFrom(entries.remove(variable.entry.name, variable.entry)); |
| 77 | } |
| 78 | |
| 79 | @Override |
| 80 | public Future<Iterator<String>> names() { |
| 81 | return futureFrom(entries.keySet().iterator()); |
| 82 | } |
| 83 | |
| 84 | private static class InMemoryVariable extends Variable { |
| 85 | private InMemoryVariable(Entry entry) { |
| 86 | this(entry, null); |
| 87 | } |
| 88 | |
| 89 | private InMemoryVariable(Entry entry, byte[] value) { |
| 90 | this.entry = entry; |
nothing calls this directly
no outgoing calls
no test coverage detected