Skip to content

Commit 591a840

Browse files
Mike Wiederholdingenthr
authored andcommitted
Refactored tap message classes.
These needed to be more readable and were horribly coded (by me). I started seeing issues with conversion from bytes on the wire to variables in spy so I changed how this was done. Change-Id: I583c43216643b111b6256f39ca475582b37267c6 Reviewed-on: http://review.couchbase.org/9712 Tested-by: Matt Ingenthron <[email protected]> Reviewed-by: Matt Ingenthron <[email protected]>
1 parent 48e7e62 commit 591a840

File tree

7 files changed

+370
-335
lines changed

7 files changed

+370
-335
lines changed

src/main/java/net/spy/memcached/protocol/binary/TapOperationImpl.java

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@
66
import net.spy.memcached.ops.OperationCallback;
77
import net.spy.memcached.ops.TapOperation;
88
import net.spy.memcached.tapmessage.BaseMessage;
9+
import net.spy.memcached.tapmessage.TapFlag;
910
import net.spy.memcached.tapmessage.TapOpcode;
1011
import net.spy.memcached.tapmessage.ResponseMessage;
11-
import net.spy.memcached.tapmessage.Util;
1212

1313
public abstract class TapOperationImpl extends OperationImpl implements TapOperation {
1414
private static final byte TAP_FLAG_ACK = 0x1;
@@ -36,7 +36,7 @@ public void readFromBuffer(ByteBuffer data) throws IOException {
3636
bytesProcessed++;
3737
} else {
3838
if (message == null) {
39-
bodylen = (int) Util.fieldToValue(header, BaseMessage.TOTAL_BODY_INDEX, BaseMessage.TOTAL_BODY_FIELD_LENGTH);
39+
bodylen = decodeInt(header, 8);
4040
message = new byte[BaseMessage.HEADER_LENGTH + bodylen];
4141
System.arraycopy(header, 0, message, 0, BaseMessage.HEADER_LENGTH);
4242
}
@@ -48,8 +48,10 @@ public void readFromBuffer(ByteBuffer data) throws IOException {
4848
if (bytesProcessed >= message.length) {
4949
ResponseMessage response = new ResponseMessage(message);
5050

51-
if (response.getFlags() == TAP_FLAG_ACK) {
52-
((Callback)getCallback()).gotAck(response.getOpcode(), response.getOpaque());
51+
for (TapFlag flag : response.getFlags()) {
52+
if (flag.flag == TAP_FLAG_ACK) {
53+
((Callback)getCallback()).gotAck(response.getOpcode(), response.getOpaque());
54+
}
5355
}
5456
if (response.getOpcode() != TapOpcode.OPAQUE && response.getOpcode() != TapOpcode.NOOP) {
5557
((Callback)getCallback()).gotData(response);

src/main/java/net/spy/memcached/tapmessage/BaseMessage.java

Lines changed: 82 additions & 144 deletions
Original file line numberDiff line numberDiff line change
@@ -5,263 +5,181 @@
55
import net.spy.memcached.compat.SpyObject;
66

77
/**
8-
* The HeaderMessage implements the header of a tap message. This class cannot be instantiated.
9-
* Tap stream messages are created with the RequestMessage and ResponseMessage classes. Users
10-
* who want to take advantage of customizing their own tap messages should use the
11-
* CustomTapStream class since it provides flexibility to create all valid tap messages.
8+
* The BaseMessage implements the header of a tap message. This class cannot be instantiated.
9+
* Tap stream messages are created with the RequestMessage and ResponseMessage classes.
1210
*/
13-
public class BaseMessage extends SpyObject {
14-
/**
15-
* The index of the magic field in a tap header.
16-
*/
17-
public static final int MAGIC_INDEX = 0;
18-
19-
/**
20-
* The length of the magic field in a tap header.
21-
*/
22-
public static final int MAGIC_FIELD_LENGTH = 1;
23-
24-
/**
25-
* The index of the opcode field in a tap header.
26-
*/
27-
public static final int OPCODE_INDEX = 1;
28-
29-
/**
30-
* The length of the opcode field in a tap header.
31-
*/
32-
public static final int OPCODE_FIELD_LENGTH = 1;
33-
34-
/**
35-
* The index of the key length field in a tap header.
36-
*/
37-
public static final int KEY_LENGTH_INDEX = 2;
38-
39-
/**
40-
* The length of the key length field in a tap header.
41-
*/
42-
public static final int KEY_LENGTH_FIELD_LENGTH = 2;
43-
44-
/**
45-
* The index of the extra length field in the tap header.
46-
*/
47-
public static final int EXTRA_LENGTH_INDEX = 4;
48-
49-
/**
50-
* The length of the extra length field in a tap header.
51-
*/
52-
public static final int EXTRA_LENGTH_FIELD_LENGTH = 1;
53-
54-
/**
55-
* The index of the data type field in the tap header.
56-
*/
57-
public static final int DATA_TYPE_INDEX = 5;
58-
59-
/**
60-
* The length of the data type field in a tap header.
61-
*/
62-
public static final int DATA_TYPE_FIELD_LENGTH = 1;
63-
64-
/**
65-
* The index of the vbucket field in the tap header.
66-
*/
67-
public static final int VBUCKET_INDEX = 6;
68-
69-
/**
70-
* The length of the vbucket field in a tap header.
71-
*/
72-
public static final int VBUCKET_FIELD_LENGTH = 2;
73-
74-
/**
75-
* The index of the total body field in the tap header.
76-
*/
77-
public static final int TOTAL_BODY_INDEX = 8;
78-
79-
/**
80-
* The length of the total body field in the tap header.
81-
*/
82-
public static final int TOTAL_BODY_FIELD_LENGTH = 4;
83-
84-
/**
85-
* The index of the opaque field in the tap header.
86-
*/
87-
public static final int OPAQUE_INDEX = 12;
88-
89-
/**
90-
* The length of the opaque field in the tap header.
91-
*/
92-
public static final int OPAQUE_FIELD_LENGTH = 4;
93-
94-
/**
95-
* The index of the cas field in the tap header.
96-
*/
97-
public static final int CAS_INDEX = 16;
98-
99-
/**
100-
* The length of the cas field in the tap header.
101-
*/
102-
public static final int CAS_FIELD_LENGTH = 8;
103-
104-
/**
105-
* The header length
106-
*/
11+
public abstract class BaseMessage extends SpyObject {
12+
private static final int MAGIC_OFFSET = 0;
13+
private static final int OPCODE_OFFSET = 1;
14+
private static final int KEYLENGTH_OFFSET = 2;
15+
private static final int EXTRALENGTH_OFFSET = 4;
16+
private static final int DATATYPE_OFFSET = 5;
17+
private static final int VBUCKET_OFFSET = 6;
18+
private static final int TOTALBODY_OFFSET = 8;
19+
private static final int OPAQUE_OFFSET = 12;
20+
private static final int CAS_OFFSET = 16;
10721
public static final int HEADER_LENGTH = 24;
10822

109-
/**
110-
* Holds the binary data for the header field.
111-
*/
23+
protected TapMagic magic;
24+
protected TapOpcode opcode;
25+
protected short keylength;
26+
protected byte extralength;
27+
protected byte datatype;
28+
protected short vbucket;
29+
protected int totalbody;
30+
protected int opaque;
31+
protected long cas;
11232

113-
protected byte[] mbytes;
114-
/**
115-
* Instantiates a tap header.
116-
*/
11733
protected BaseMessage() {
118-
mbytes = new byte[HEADER_LENGTH];
34+
// Empty
35+
}
36+
37+
protected BaseMessage(byte[] b) {
38+
magic = TapMagic.getMagicByByte(b[MAGIC_OFFSET]);
39+
opcode = TapOpcode.getOpcodeByByte(b[OPCODE_OFFSET]);
40+
keylength = decodeShort(b, KEYLENGTH_OFFSET);
41+
extralength = b[EXTRALENGTH_OFFSET];
42+
datatype = b[DATATYPE_OFFSET];
43+
vbucket = decodeShort(b, VBUCKET_OFFSET);
44+
totalbody = decodeInt(b, TOTALBODY_OFFSET);
45+
opaque = decodeInt(b, OPAQUE_OFFSET);
46+
cas = decodeLong(b, CAS_OFFSET);
11947
}
12048

12149
/**
12250
* Sets the value of the tap messages magic field.
12351
* @param m The new value for the magic field.
12452
*/
12553
public final void setMagic(TapMagic m) {
126-
mbytes[MAGIC_INDEX] = (byte) m.magic;
54+
magic = m;
12755
}
12856

12957
/**
13058
* Gets the value of the tap messages magic field.
13159
* @return The value of the magic field.
13260
*/
133-
public final int getMagic() {
134-
return mbytes[MAGIC_INDEX];
61+
public final TapMagic getMagic() {
62+
return magic;
13563
}
13664

13765
/**
13866
* Sets the value of the tap messages opcode field
13967
* @param o The new value of the opcode field.
14068
*/
14169
public final void setOpcode(TapOpcode o) {
142-
mbytes[OPCODE_INDEX] = (byte) o.opcode;
70+
opcode = o;
14371
}
14472

14573
/**
14674
* Gets the value of the tap messages opaque field.
14775
* @return The value of the opaque field.
14876
*/
14977
public final TapOpcode getOpcode() {
150-
return TapOpcode.getOpcodeByByte(mbytes[OPCODE_INDEX]);
151-
}
152-
153-
/**
154-
* Sets the key length for this message. This function should never be called by
155-
* the user since changes to fields that affect key length call this function
156-
* automatically.
157-
* @param l The new value for the key length field.
158-
*/
159-
protected final void setKeylength(long l) {
160-
Util.valueToFieldOffest(mbytes, KEY_LENGTH_INDEX, KEY_LENGTH_FIELD_LENGTH, l);
78+
return opcode;
16179
}
16280

16381
/**
16482
* Gets the value of the tap messages key length field.
16583
* @return The value of the key length field.
16684
*/
167-
public final int getKeylength() {
168-
return (int) Util.fieldToValue(mbytes, KEY_LENGTH_INDEX, KEY_LENGTH_FIELD_LENGTH);
85+
public final short getKeylength() {
86+
return keylength;
16987
}
17088

17189
/**
17290
* Sets the value of the tap messages data type field.
17391
* @param b The new value for the data type field.
17492
*/
175-
public final void setDatatype(byte b) {
176-
mbytes[DATA_TYPE_INDEX] = b;
93+
public final void setDatatype(byte d) {
94+
datatype = d;
17795
}
17896

17997
/**
18098
* Gets the value of the tap messages data type field.
18199
* @return The value of the data type field.
182100
*/
183101
public final byte getDatatype() {
184-
return mbytes[DATA_TYPE_INDEX];
102+
return datatype;
185103
}
186104

187105
/**
188106
* Sets the value of the tap messages extra length field.
189107
* @param i The new value for the extra length field.
190108
*/
191-
public final void setExtralength(int i) {
192-
mbytes[EXTRA_LENGTH_INDEX] = (byte) i;
109+
public final void setExtralength(byte e) {
110+
extralength = e;
193111
}
194112

195113
/**
196114
* Gets the value of the tap messages extra length field.
197115
* @return The value of the extra length field.
198116
*/
199-
public final int getExtralength() {
200-
return mbytes[EXTRA_LENGTH_INDEX];
117+
public final byte getExtralength() {
118+
return extralength;
201119
}
202120

203121
/**
204122
* Sets the value of the tap messages vbucket field.
205123
* @param vb The new value for the vbucket field.
206124
*/
207-
public final void setVbucket(int vb) {
208-
Util.valueToFieldOffest(mbytes, VBUCKET_INDEX, VBUCKET_FIELD_LENGTH, vb);
125+
public final void setVbucket(short vb) {
126+
vbucket = vb;
209127
}
210128

211129
/**
212130
* Gets the value of the tap messages vbucket field.
213131
* @return The value of the vbucket field.
214132
*/
215-
public final int getVbucket() {
216-
return (int) Util.fieldToValue(mbytes, VBUCKET_INDEX, VBUCKET_FIELD_LENGTH);
133+
public final short getVbucket() {
134+
return vbucket;
217135
}
218136

219137
/**
220138
* Sets the value of the tap messages total body field.
221139
* @param l The new value for the total body field.
222140
*/
223-
public final void setTotalbody(long l) {
224-
Util.valueToFieldOffest(mbytes, TOTAL_BODY_INDEX, TOTAL_BODY_FIELD_LENGTH, l);
141+
public final void setTotalbody(int t) {
142+
totalbody = t;
225143
}
226144

227145
/**
228146
* Gets the value of the tap messages total body field.
229147
* @return The value of the total body field.
230148
*/
231149
public final int getTotalbody() {
232-
return (int) Util.fieldToValue(mbytes, TOTAL_BODY_INDEX, TOTAL_BODY_FIELD_LENGTH);
150+
return totalbody;
233151
}
234152

235153
/**
236154
* Sets the value of the tap messages opaque field.
237155
* @param op The new value for the opaque field.
238156
*/
239157
public final void setOpaque(int op) {
240-
Util.valueToFieldOffest(mbytes, OPAQUE_INDEX, OPAQUE_FIELD_LENGTH, op);
158+
opaque = op;
241159
}
242160

243161
/**
244162
* Gets the value of the tap messages opaque field.
245163
* @return The value of the opaque field.
246164
*/
247165
public final int getOpaque() {
248-
return (int) Util.fieldToValue(mbytes, OPAQUE_INDEX, OPAQUE_FIELD_LENGTH);
166+
return opaque;
249167
}
250168

251169
/**
252170
* Sets the value of the tap messages cas field.
253171
* @param cas The new value for the cas field.
254172
*/
255-
public final void setCas(long cas) {
256-
Util.valueToFieldOffest(mbytes, CAS_INDEX, CAS_FIELD_LENGTH, cas);
173+
public final void setCas(long c) {
174+
cas = c;
257175
}
258176

259177
/**
260178
* Gets the value of the tap messages cas field.
261179
* @return The value of the cas field.
262180
*/
263181
public final long getCas() {
264-
return Util.fieldToValue(mbytes, CAS_INDEX, CAS_FIELD_LENGTH);
182+
return cas;
265183
}
266184

267185
/**
@@ -276,7 +194,27 @@ public final int getMessageLength() {
276194
* Creates a ByteBuffer representation of the message.
277195
* @return The ByteBuffer representation of the message.
278196
*/
279-
public final ByteBuffer getBytes() {
280-
return ByteBuffer.wrap(mbytes);
197+
public abstract ByteBuffer getBytes();
198+
199+
protected short decodeShort(byte[] data, int i) {
200+
return (short)((data[i] & 0xff) << 8 | (data[i + 1] & 0xff));
201+
}
202+
203+
protected int decodeInt(byte[] data, int i) {
204+
return (data[i] & 0xff) << 24
205+
| (data[i + 1] & 0xff) << 16
206+
| (data[i + 2] & 0xff) << 8
207+
| (data[i + 3] & 0xff);
208+
}
209+
210+
protected long decodeLong(byte[] data, int i) {
211+
return (data[i] & 0xffL) << 56
212+
| (data[i + 1] & 0xffL) << 48
213+
| (data[i + 2] & 0xffL) << 40
214+
| (data[i + 3] & 0xffL) << 32
215+
| (data[i + 4] & 0xffL) << 24
216+
| (data[i + 5] & 0xffL) << 16
217+
| (data[i + 6] & 0xffL) << 8
218+
| (data[i + 7] & 0xffL);
281219
}
282220
}

0 commit comments

Comments
 (0)