blob: e74a5a4b013e8b6aa9b2293194c334dfd3e065f3 [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 {
Yuta HIGUCHI10eebea2014-02-03 10:41:41 -080019 @SuppressWarnings("unused")
Yuta HIGUCHI1ef85c42014-01-29 17:23:21 -080020 private static final Logger log = LoggerFactory.getLogger(RCTable.class);
21
22 private static final ConcurrentHashMap<String, RCTable> table_map = new ConcurrentHashMap<>();
23
24 /**
25 *
26 * @param table
27 * Table to drop.
28 * @note Instance passed must not be use after successful call.
29 *
30 */
31 public static void dropTable(RCTable table) {
32 JRamCloud rcClient = RCClient.getClient();
33 // TODO mark the table instance as dropped?
34 rcClient.dropTable(table.getTableName());
35 table_map.remove(table.getTableName());
36 }
37
38 public static RCTable getTable(String tableName) {
39 RCTable table = table_map.get(tableName);
40 if (table == null) {
41 RCTable new_table = new RCTable(tableName);
42 RCTable existing_table = table_map
43 .putIfAbsent(tableName, new_table);
44 if (existing_table != null) {
45 return existing_table;
46 } else {
47 return new_table;
48 }
49 }
50 return table;
51 }
52
53 public static class Entry {
54 public final byte[] key;
55 public byte[] value;
56 public long version;
57
58 public Entry(byte[] key, byte[] value, long version) {
59 this.key = key;
60 this.value = value;
61 this.version = version;
62 }
63 }
64
65 // finally the Table itself
66
67 private final long rcTableId;
68 private final String rcTableName;
69
70 // private boolean isDropped = false;
71
72 /**
73 *
74 * @note rcTableName must be unique cluster wide.
75 * @param rcTableName
76 */
77 private RCTable(String rcTableName) {
78 JRamCloud rcClient = RCClient.getClient();
79
80 this.rcTableName = rcTableName;
81
82 // FIXME Is it better to create table here or at getTable
83 this.rcTableId = rcClient.createTable(rcTableName);
84 }
85
86 public long getTableId() {
87 return this.rcTableId;
88 }
89
90 public String getTableName() {
91 return this.rcTableName;
92 }
93
94 // TODO: Enumerate whole table?
95
Yuta HIGUCHIc9ca4ac2014-01-31 19:48:31 -080096 /**
97 * Create a Key-Value entry on table.
98 *
99 * @param key
100 * @param value
101 * @return version of the created entry
102 * @throws ObjectExistsException
103 */
Yuta HIGUCHI1ef85c42014-01-29 17:23:21 -0800104 public long create(final byte[] key, final byte[] value)
105 throws ObjectExistsException {
106
107 JRamCloud rcClient = RCClient.getClient();
108
109 RejectRules rules = rcClient.new RejectRules();
110 rules.setExists();
111
112 long updated_version = rcClient.writeRule(this.rcTableId, key, value,
113 rules);
114 return updated_version;
115 }
116
Yuta HIGUCHIc9ca4ac2014-01-31 19:48:31 -0800117 /**
118 * Create a Key-Value entry on table, without existance checking.
119 *
120 * @param key
121 * @param value
122 * @return version of the created entry
123 */
124 public long forceCreate(final byte[] key, final byte[] value) {
125 JRamCloud rcClient = RCClient.getClient();
126
127 long updated_version = rcClient.write(this.rcTableId, key, value);
128 return updated_version;
129
130 }
131
132 /**
133 * Read a Key-Value entry from table.
134 *
135 * @param key
136 * @return Corresponding {@link Entry}
137 * @throws ObjectDoesntExistException
138 */
Yuta HIGUCHI1ef85c42014-01-29 17:23:21 -0800139 public Entry read(final byte[] key) throws ObjectDoesntExistException {
140
141 JRamCloud rcClient = RCClient.getClient();
142
143 // FIXME underlying JRamCloud cannot detect "not exist"
144 // RejectRules rules = rcClient.new RejectRules();
145 // rules.setDoesntExists();
146 // JRamCloud.Object rcObj = rcClient.read(this.rcTableId, key, rules);
147 JRamCloud.Object rcObj = rcClient.read(this.rcTableId, key);
148
149 return new Entry(rcObj.key, rcObj.value, rcObj.version);
150 }
151
Yuta HIGUCHIc9ca4ac2014-01-31 19:48:31 -0800152 /**
153 * Update an existing Key-Value entry in table.
154 *
155 * @param key
156 * @param value
157 * @param version
158 * expected version in the data store
159 * @return version after update
160 * @throws ObjectDoesntExistException
161 * @throws WrongVersionException
162 */
Yuta HIGUCHI1ef85c42014-01-29 17:23:21 -0800163 public long update(final byte[] key, final byte[] value, final long version)
164 throws ObjectDoesntExistException, WrongVersionException {
165
166 JRamCloud rcClient = RCClient.getClient();
167
168 RejectRules rules = rcClient.new RejectRules();
169 rules.setDoesntExists();
170 rules.setNeVersion(version);
171
172 long updated_version = rcClient.writeRule(this.rcTableId, key, value,
173 rules);
174 return updated_version;
175 }
176
Yuta HIGUCHIc9ca4ac2014-01-31 19:48:31 -0800177 /**
178 * Update an existing Key-Value entry in table, without checking version.
179 *
180 * @param key
181 * @param value
182 * @return version after update
183 * @throws ObjectDoesntExistException
184 */
Yuta HIGUCHI1ef85c42014-01-29 17:23:21 -0800185 public long update(final byte[] key, final byte[] value)
186 throws ObjectDoesntExistException {
187
188 JRamCloud rcClient = RCClient.getClient();
189
190 RejectRules rules = rcClient.new RejectRules();
191 rules.setDoesntExists();
192
193 long updated_version = rcClient.writeRule(this.rcTableId, key, value,
194 rules);
195 return updated_version;
196
197 }
198
Yuta HIGUCHIc9ca4ac2014-01-31 19:48:31 -0800199 /**
200 * Remove an existing Key-Value entry in table
201 *
202 * @param key
203 * @param version
204 * expected version in the data store
205 * @return version of removed object
206 * @throws ObjectDoesntExistException
207 * @throws WrongVersionException
208 */
209 public long delete(final byte[] key, final long version)
210 throws ObjectDoesntExistException, WrongVersionException {
Yuta HIGUCHI1ef85c42014-01-29 17:23:21 -0800211 JRamCloud rcClient = RCClient.getClient();
212
Yuta HIGUCHIc9ca4ac2014-01-31 19:48:31 -0800213 // FIXME underlying JRamCloud does not support cond. remove now
Yuta HIGUCHI1ef85c42014-01-29 17:23:21 -0800214 RejectRules rules = rcClient.new RejectRules();
215 rules.setDoesntExists();
Yuta HIGUCHIc9ca4ac2014-01-31 19:48:31 -0800216 rules.setNeVersion(version);
Yuta HIGUCHI1ef85c42014-01-29 17:23:21 -0800217
218 long removed_version = rcClient.remove(this.rcTableId, key, rules);
219 return removed_version;
220 }
221
Yuta HIGUCHIc9ca4ac2014-01-31 19:48:31 -0800222 /**
223 * Remove a Key-Value entry in table
224 *
225 * @param key
226 * @return version of removed object or -1, if it did not exist.
227 */
228 public long forceDelete(final byte[] key) {
229 JRamCloud rcClient = RCClient.getClient();
230 long removed_version = rcClient.remove(this.rcTableId, key);
231 return removed_version;
232 }
Yuta HIGUCHI1ef85c42014-01-29 17:23:21 -0800233}