Skip to content

Commit 6f92cb3

Browse files
committed
optimized String deser by referencing buffer instead of copying
1 parent cf82e82 commit 6f92cb3

File tree

12 files changed

+145
-10
lines changed

12 files changed

+145
-10
lines changed
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
//
2+
// MessagePack for Java
3+
//
4+
// Copyright (C) 2009-2011 FURUHASHI Sadayuki
5+
//
6+
// Licensed under the Apache License, Version 2.0 (the "License");
7+
// you may not use this file except in compliance with the License.
8+
// You may obtain a copy of the License at
9+
//
10+
// http://www.apache.org/licenses/LICENSE-2.0
11+
//
12+
// Unless required by applicable law or agreed to in writing, software
13+
// distributed under the License is distributed on an "AS IS" BASIS,
14+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
// See the License for the specific language governing permissions and
16+
// limitations under the License.
17+
//
18+
package org.msgpack.io;
19+
20+
import java.io.IOException;
21+
22+
23+
public interface BufferReferer {
24+
public void refer(byte[] b, int off, int len, boolean gift) throws IOException;
25+
}
26+

src/main/java/org/msgpack/io/Input.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@
2525
public interface Input extends Closeable {
2626
public int read(byte[] b, int off, int len) throws IOException;
2727

28+
public boolean tryRefer(BufferReferer ref, int len) throws IOException;
29+
2830
public byte readByte() throws IOException;
2931

3032
public void advance();

src/main/java/org/msgpack/io/LinkedBufferInput.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
//
1818
package org.msgpack.io;
1919

20+
import java.io.IOException;
2021
import java.io.EOFException;
2122
import java.util.List;
2223
import java.util.LinkedList;
@@ -62,6 +63,20 @@ public int read(byte[] b, int off, int len) throws EOFException {
6263
return olen - len;
6364
}
6465

66+
public boolean tryRefer(BufferReferer ref, int len) throws IOException {
67+
ByteBuffer bb = link.peekFirst();
68+
if(bb == null) {
69+
throw new EndOfBufferException();
70+
} else if(bb.remaining() < len) {
71+
return false;
72+
} else if(!bb.hasArray()) {
73+
return false;
74+
}
75+
ref.refer(bb.array(), bb.arrayOffset()+bb.position(), len, true);
76+
bb.position(bb.position()+len);
77+
return true;
78+
}
79+
6580
public byte readByte() throws EOFException {
6681
ByteBuffer bb = link.peekFirst();
6782
if(bb == null || bb.remaining() == 0) {

src/main/java/org/msgpack/io/StreamInput.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,10 @@ public int read(byte[] b, int off, int len) throws IOException {
4949
return len;
5050
}
5151

52+
public boolean tryRefer(BufferReferer ref, int size) throws IOException {
53+
return false;
54+
}
55+
5256
public byte readByte() throws IOException {
5357
int n = in.read();
5458
if(n < 0) {

src/main/java/org/msgpack/template/builder/JavassistTemplateBuilder.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ public JavassistTemplateBuilder(TemplateRegistry registry) {
8383

8484
@Override
8585
public boolean matchType(Type targetType) {
86+
// TODO reject enum
8687
return AbstractTemplateBuilder.isAnnotated((Class<?>) targetType, Message.class)
8788
|| AbstractTemplateBuilder.isAnnotated((Class<?>) targetType, MessagePackMessage.class);
8889
}

src/main/java/org/msgpack/template/builder/ReflectionTemplateBuilder.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,7 @@ public ReflectionTemplateBuilder(TemplateRegistry registry) {
263263

264264
@Override
265265
public boolean matchType(Type targetType) {
266+
// TODO reject enum
266267
return AbstractTemplateBuilder.isAnnotated((Class<?>) targetType, Message.class)
267268
|| AbstractTemplateBuilder.isAnnotated((Class<?>) targetType, MessagePackMessage.class);
268269
}

src/main/java/org/msgpack/type/ByteArrayRawValueImpl.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ public static RawValue getEmptyInstance() {
4242
}
4343

4444
ByteArrayRawValueImpl(byte[] b, int off, int len) {
45+
// TODO reference
4546
this.bytes = new byte[len];
4647
System.arraycopy(b, off, this.bytes, 0, len);
4748
}

src/main/java/org/msgpack/unpacker/Accept.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,12 @@
1717
//
1818
package org.msgpack.unpacker;
1919

20+
import java.io.IOException;
21+
import org.msgpack.io.BufferReferer;
2022
import org.msgpack.MessageTypeException;
2123

22-
abstract class Accept {
24+
25+
abstract class Accept implements BufferReferer {
2326
void acceptBoolean(boolean v) {
2427
throw new MessageTypeException("Unexpected boolean value");
2528
}
@@ -95,5 +98,9 @@ void acceptFloat(float v) {
9598
void acceptDouble(double v) {
9699
throw new MessageTypeException("Unexpected float value");
97100
}
101+
102+
public void refer(byte[] b, int off, int size, boolean gift) throws IOException {
103+
throw new MessageTypeException("Unexpected raw value");
104+
}
98105
}
99106

src/main/java/org/msgpack/unpacker/ByteArrayAccept.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@
1717
//
1818
package org.msgpack.unpacker;
1919

20+
import java.io.IOException;
21+
22+
2023
final class ByteArrayAccept extends Accept {
2124
byte[] value;
2225

@@ -29,5 +32,12 @@ void acceptRaw(byte[] raw) {
2932
void acceptEmptyRaw() {
3033
this.value = new byte[0];
3134
}
35+
36+
@Override
37+
public void refer(byte[] b, int off, int len, boolean gift) throws IOException {
38+
// TODO gift
39+
this.value = new byte[len];
40+
System.arraycopy(b, off, value, 0, len);
41+
}
3242
}
3343

src/main/java/org/msgpack/unpacker/MessagePackUnpacker.java

Lines changed: 28 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import java.math.BigInteger;
2424
import org.msgpack.io.Input;
2525
import org.msgpack.io.StreamInput;
26+
import org.msgpack.io.BufferReferer;
2627
import org.msgpack.MessagePack;
2728
import org.msgpack.MessageTypeException;
2829
import org.msgpack.packer.Unconverter;
@@ -45,6 +46,7 @@ public class MessagePackUnpacker extends AbstractUnpacker {
4546
private final BigIntegerAccept bigIntegerAccept = new BigIntegerAccept();
4647
private final DoubleAccept doubleAccept = new DoubleAccept();
4748
private final ByteArrayAccept byteArrayAccept = new ByteArrayAccept();
49+
private final StringAccept stringAccept = new StringAccept();
4850
private final ArrayAccept arrayAccept = new ArrayAccept();
4951
private final MapAccept mapAccept = new MapAccept();
5052
private final ValueAccept valueAccept = new ValueAccept();
@@ -110,9 +112,11 @@ final boolean readOneWithoutStack(Accept a) throws IOException {
110112
headByte = REQUIRE_TO_READ_HEAD;
111113
return true;
112114
}
113-
readRawBody(count);
114-
a.acceptRaw(raw);
115-
raw = null;
115+
if(!tryReferRawBody(a, count)) {
116+
readRawBody(count);
117+
a.acceptRaw(raw);
118+
raw = null;
119+
}
116120
headByte = REQUIRE_TO_READ_HEAD;
117121
return true;
118122
}
@@ -210,9 +214,11 @@ final boolean readOneWithoutStack(Accept a) throws IOException {
210214
return true;
211215
}
212216
in.advance();
213-
readRawBody(count);
214-
a.acceptRaw(raw);
215-
raw = null;
217+
if(!tryReferRawBody(a, count)) {
218+
readRawBody(count);
219+
a.acceptRaw(raw);
220+
raw = null;
221+
}
216222
headByte = REQUIRE_TO_READ_HEAD;
217223
return true;
218224
}
@@ -229,9 +235,11 @@ final boolean readOneWithoutStack(Accept a) throws IOException {
229235
return true;
230236
}
231237
in.advance();
232-
readRawBody(count);
233-
a.acceptRaw(raw);
234-
raw = null;
238+
if(!tryReferRawBody(a, count)) {
239+
readRawBody(count);
240+
a.acceptRaw(raw);
241+
raw = null;
242+
}
235243
headByte = REQUIRE_TO_READ_HEAD;
236244
return true;
237245
}
@@ -289,6 +297,10 @@ final boolean readOneWithoutStack(Accept a) throws IOException {
289297
}
290298
}
291299

300+
private boolean tryReferRawBody(BufferReferer referer, int size) throws IOException {
301+
return in.tryRefer(referer, size);
302+
}
303+
292304
private void readRawBody(int size) throws IOException {
293305
raw = new byte[size];
294306
rawFilled = 0;
@@ -421,11 +433,18 @@ public double readDouble() throws IOException {
421433
return doubleAccept.value;
422434
}
423435

436+
@Override
424437
public byte[] readByteArray() throws IOException {
425438
readOne(byteArrayAccept);
426439
return byteArrayAccept.value;
427440
}
428441

442+
@Override
443+
public String readString() throws IOException {
444+
readOne(stringAccept);
445+
return stringAccept.value;
446+
}
447+
429448
@Override
430449
public int readArrayBegin() throws IOException {
431450
readOne(arrayAccept);

0 commit comments

Comments
 (0)