blob: 55de05a306c8dd1fcdb97dfbef7251ab290f2249 [file] [log] [blame]
Yuta HIGUCHI1ef85c42014-01-29 17:23:21 -08001package net.onrc.onos.datastore;
2
3import java.util.concurrent.ConcurrentHashMap;
4
5import org.slf4j.Logger;
6import org.slf4j.LoggerFactory;
7
8import edu.stanford.ramcloud.JRamCloud;
9import edu.stanford.ramcloud.JRamCloud.ObjectDoesntExistException;
10import edu.stanford.ramcloud.JRamCloud.ObjectExistsException;
11import edu.stanford.ramcloud.JRamCloud.RejectRules;
12import edu.stanford.ramcloud.JRamCloud.WrongVersionException;
13
14/**
15 * Class to represent a Table in RAMCloud
16 *
17 */
18public class RCTable {
19 private static final Logger log = LoggerFactory.getLogger(RCTable.class);
20
21 private static final ConcurrentHashMap<String, RCTable> table_map = new ConcurrentHashMap<>();
22
23 /**
24 *
25 * @param table
26 * Table to drop.
27 * @note Instance passed must not be use after successful call.
28 *
29 */
30 public static void dropTable(RCTable table) {
31 JRamCloud rcClient = RCClient.getClient();
32 // TODO mark the table instance as dropped?
33 rcClient.dropTable(table.getTableName());
34 table_map.remove(table.getTableName());
35 }
36
37 public static RCTable getTable(String tableName) {
38 RCTable table = table_map.get(tableName);
39 if (table == null) {
40 RCTable new_table = new RCTable(tableName);
41 RCTable existing_table = table_map
42 .putIfAbsent(tableName, new_table);
43 if (existing_table != null) {
44 return existing_table;
45 } else {
46 return new_table;
47 }
48 }
49 return table;
50 }
51
52 public static class Entry {
53 public final byte[] key;
54 public byte[] value;
55 public long version;
56
57 public Entry(byte[] key, byte[] value, long version) {
58 this.key = key;
59 this.value = value;
60 this.version = version;
61 }
62 }
63
64 // finally the Table itself
65
66 private final long rcTableId;
67 private final String rcTableName;
68
69 // private boolean isDropped = false;
70
71 /**
72 *
73 * @note rcTableName must be unique cluster wide.
74 * @param rcTableName
75 */
76 private RCTable(String rcTableName) {
77 JRamCloud rcClient = RCClient.getClient();
78
79 this.rcTableName = rcTableName;
80
81 // FIXME Is it better to create table here or at getTable
82 this.rcTableId = rcClient.createTable(rcTableName);
83 }
84
85 public long getTableId() {
86 return this.rcTableId;
87 }
88
89 public String getTableName() {
90 return this.rcTableName;
91 }
92
93 // TODO: Enumerate whole table?
94
Yuta HIGUCHIc9ca4ac2014-01-31 19:48:31 -080095 /**
96 * Create a Key-Value entry on table.
97 *
98 * @param key
99 * @param value
100 * @return version of the created entry
101 * @throws ObjectExistsException
102 */
Yuta HIGUCHI1ef85c42014-01-29 17:23:21 -0800103 public long create(final byte[] key, final byte[] value)
104 throws ObjectExistsException {
105
106 JRamCloud rcClient = RCClient.getClient();
107
108 RejectRules rules = rcClient.new RejectRules();
109 rules.setExists();
110
111 long updated_version = rcClient.writeRule(this.rcTableId, key, value,
112 rules);
113 return updated_version;
114 }
115
Yuta HIGUCHIc9ca4ac2014-01-31 19:48:31 -0800116 /**
117 * Create a Key-Value entry on table, without existance checking.
118 *
119 * @param key
120 * @param value
121 * @return version of the created entry
122 */
123 public long forceCreate(final byte[] key, final byte[] value) {
124 JRamCloud rcClient = RCClient.getClient();
125
126 long updated_version = rcClient.write(this.rcTableId, key, value);
127 return updated_version;
128
129 }
130
131 /**
132 * Read a Key-Value entry from table.
133 *
134 * @param key
135 * @return Corresponding {@link Entry}
136 * @throws ObjectDoesntExistException
137 */
Yuta HIGUCHI1ef85c42014-01-29 17:23:21 -0800138 public Entry read(final byte[] key) throws ObjectDoesntExistException {
139
140 JRamCloud rcClient = RCClient.getClient();
141
142 // FIXME underlying JRamCloud cannot detect "not exist"
143 // RejectRules rules = rcClient.new RejectRules();
144 // rules.setDoesntExists();
145 // JRamCloud.Object rcObj = rcClient.read(this.rcTableId, key, rules);
146 JRamCloud.Object rcObj = rcClient.read(this.rcTableId, key);
147
148 return new Entry(rcObj.key, rcObj.value, rcObj.version);
149 }
150
Yuta HIGUCHIc9ca4ac2014-01-31 19:48:31 -0800151 /**
152 * Update an existing Key-Value entry in table.
153 *
154 * @param key
155 * @param value
156 * @param version
157 * expected version in the data store
158 * @return version after update
159 * @throws ObjectDoesntExistException
160 * @throws WrongVersionException
161 */
Yuta HIGUCHI1ef85c42014-01-29 17:23:21 -0800162 public long update(final byte[] key, final byte[] value, final long version)
163 throws ObjectDoesntExistException, WrongVersionException {
164
165 JRamCloud rcClient = RCClient.getClient();
166
167 RejectRules rules = rcClient.new RejectRules();
168 rules.setDoesntExists();
169 rules.setNeVersion(version);
170
171 long updated_version = rcClient.writeRule(this.rcTableId, key, value,
172 rules);
173 return updated_version;
174 }
175
Yuta HIGUCHIc9ca4ac2014-01-31 19:48:31 -0800176 /**
177 * Update an existing Key-Value entry in table, without checking version.
178 *
179 * @param key
180 * @param value
181 * @return version after update
182 * @throws ObjectDoesntExistException
183 */
Yuta HIGUCHI1ef85c42014-01-29 17:23:21 -0800184 public long update(final byte[] key, final byte[] value)
185 throws ObjectDoesntExistException {
186
187 JRamCloud rcClient = RCClient.getClient();
188
189 RejectRules rules = rcClient.new RejectRules();
190 rules.setDoesntExists();
191
192 long updated_version = rcClient.writeRule(this.rcTableId, key, value,
193 rules);
194 return updated_version;
195
196 }
197
Yuta HIGUCHIc9ca4ac2014-01-31 19:48:31 -0800198 /**
199 * Remove an existing Key-Value entry in table
200 *
201 * @param key
202 * @param version
203 * expected version in the data store
204 * @return version of removed object
205 * @throws ObjectDoesntExistException
206 * @throws WrongVersionException
207 */
208 public long delete(final byte[] key, final long version)
209 throws ObjectDoesntExistException, WrongVersionException {
Yuta HIGUCHI1ef85c42014-01-29 17:23:21 -0800210 JRamCloud rcClient = RCClient.getClient();
211
Yuta HIGUCHIc9ca4ac2014-01-31 19:48:31 -0800212 // FIXME underlying JRamCloud does not support cond. remove now
Yuta HIGUCHI1ef85c42014-01-29 17:23:21 -0800213 RejectRules rules = rcClient.new RejectRules();
214 rules.setDoesntExists();
Yuta HIGUCHIc9ca4ac2014-01-31 19:48:31 -0800215 rules.setNeVersion(version);
Yuta HIGUCHI1ef85c42014-01-29 17:23:21 -0800216
217 long removed_version = rcClient.remove(this.rcTableId, key, rules);
218 return removed_version;
219 }
220
Yuta HIGUCHIc9ca4ac2014-01-31 19:48:31 -0800221 /**
222 * Remove a Key-Value entry in table
223 *
224 * @param key
225 * @return version of removed object or -1, if it did not exist.
226 */
227 public long forceDelete(final byte[] key) {
228 JRamCloud rcClient = RCClient.getClient();
229 long removed_version = rcClient.remove(this.rcTableId, key);
230 return removed_version;
231 }
Yuta HIGUCHI1ef85c42014-01-29 17:23:21 -0800232}