blob: 4836f247c077749761af25a1efb4a12ccf4d2914 [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
95 // Reject if exist
96 public long create(final byte[] key, final byte[] value)
97 throws ObjectExistsException {
98
99 JRamCloud rcClient = RCClient.getClient();
100
101 RejectRules rules = rcClient.new RejectRules();
102 rules.setExists();
103
104 long updated_version = rcClient.writeRule(this.rcTableId, key, value,
105 rules);
106 return updated_version;
107 }
108
109 // read
110 public Entry read(final byte[] key) throws ObjectDoesntExistException {
111
112 JRamCloud rcClient = RCClient.getClient();
113
114 // FIXME underlying JRamCloud cannot detect "not exist"
115 // RejectRules rules = rcClient.new RejectRules();
116 // rules.setDoesntExists();
117 // JRamCloud.Object rcObj = rcClient.read(this.rcTableId, key, rules);
118 JRamCloud.Object rcObj = rcClient.read(this.rcTableId, key);
119
120 return new Entry(rcObj.key, rcObj.value, rcObj.version);
121 }
122
123 // Reject if version neq
124 public long update(final byte[] key, final byte[] value, final long version)
125 throws ObjectDoesntExistException, WrongVersionException {
126
127 JRamCloud rcClient = RCClient.getClient();
128
129 RejectRules rules = rcClient.new RejectRules();
130 rules.setDoesntExists();
131 rules.setNeVersion(version);
132
133 long updated_version = rcClient.writeRule(this.rcTableId, key, value,
134 rules);
135 return updated_version;
136 }
137
138 // Reject if not exist
139 public long update(final byte[] key, final byte[] value)
140 throws ObjectDoesntExistException {
141
142 JRamCloud rcClient = RCClient.getClient();
143
144 RejectRules rules = rcClient.new RejectRules();
145 rules.setDoesntExists();
146
147 long updated_version = rcClient.writeRule(this.rcTableId, key, value,
148 rules);
149 return updated_version;
150
151 }
152
153 // Reject if not exist
154 public long delete(final byte[] key) throws ObjectDoesntExistException {
155 JRamCloud rcClient = RCClient.getClient();
156
157 // FIXME underlying JRamCloud does not support cond remove
158 RejectRules rules = rcClient.new RejectRules();
159 rules.setDoesntExists();
160
161 long removed_version = rcClient.remove(this.rcTableId, key, rules);
162 return removed_version;
163 }
164
165}