Skip to content

Commit dddb417

Browse files
committed
extract JsonIteratorPool
1 parent 9ff324d commit dddb417

11 files changed

Lines changed: 130 additions & 57 deletions

src/main/java/com/jsoniter/DefaultMapKeyDecoder.java

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,6 @@ public static MapKeyDecoder registerOrGetExisting(Type mapKeyType) {
1818
return mapKeyDecoder;
1919
}
2020

21-
// can not reuse the tlsIter in JsonIterator
22-
// as this will be invoked while tlsIter is in use
23-
private ThreadLocal<JsonIterator> tlsIter = new ThreadLocal<JsonIterator>() {
24-
@Override
25-
protected JsonIterator initialValue() {
26-
return new JsonIterator();
27-
}
28-
};
2921
private final TypeLiteral mapKeyTypeLiteral;
3022

3123
private DefaultMapKeyDecoder(TypeLiteral mapKeyTypeLiteral) {
@@ -34,12 +26,14 @@ private DefaultMapKeyDecoder(TypeLiteral mapKeyTypeLiteral) {
3426

3527
@Override
3628
public Object decode(Slice encodedMapKey) {
37-
JsonIterator iter = tlsIter.get();
29+
JsonIterator iter = JsonIteratorPool.borrowJsonIterator();
3830
iter.reset(encodedMapKey);
3931
try {
4032
return iter.read(mapKeyTypeLiteral);
4133
} catch (IOException e) {
4234
throw new JsonException(e);
35+
} finally {
36+
JsonIteratorPool.returnJsonIterator(iter);
4337
}
4438
}
4539
}

src/main/java/com/jsoniter/JsonIterator.java

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -356,13 +356,6 @@ public void skip() throws IOException {
356356
IterImplSkip.skip(this);
357357
}
358358

359-
private static ThreadLocal<JsonIterator> tlsIter = new ThreadLocal<JsonIterator>() {
360-
@Override
361-
protected JsonIterator initialValue() {
362-
return new JsonIterator();
363-
}
364-
};
365-
366359
public static final <T> T deserialize(Config config, String input, Class<T> clazz) {
367360
JsoniterSpi.setCurrentConfig(config);
368361
try {
@@ -398,7 +391,7 @@ public static final <T> T deserialize(Config config, byte[] input, Class<T> claz
398391
}
399392
public static final <T> T deserialize(byte[] input, Class<T> clazz) {
400393
int lastNotSpacePos = findLastNotSpacePos(input);
401-
JsonIterator iter = tlsIter.get();
394+
JsonIterator iter = JsonIteratorPool.borrowJsonIterator();
402395
iter.reset(input, 0, lastNotSpacePos);
403396
try {
404397
T val = iter.read(clazz);
@@ -410,6 +403,8 @@ public static final <T> T deserialize(byte[] input, Class<T> clazz) {
410403
throw iter.reportError("deserialize", "premature end");
411404
} catch (IOException e) {
412405
throw new JsonException(e);
406+
} finally {
407+
JsonIteratorPool.returnJsonIterator(iter);
413408
}
414409
}
415410

@@ -424,7 +419,7 @@ public static final <T> T deserialize(Config config, byte[] input, TypeLiteral<T
424419

425420
public static final <T> T deserialize(byte[] input, TypeLiteral<T> typeLiteral) {
426421
int lastNotSpacePos = findLastNotSpacePos(input);
427-
JsonIterator iter = tlsIter.get();
422+
JsonIterator iter = JsonIteratorPool.borrowJsonIterator();
428423
iter.reset(input, 0, lastNotSpacePos);
429424
try {
430425
T val = iter.read(typeLiteral);
@@ -436,6 +431,8 @@ public static final <T> T deserialize(byte[] input, TypeLiteral<T> typeLiteral)
436431
throw iter.reportError("deserialize", "premature end");
437432
} catch (IOException e) {
438433
throw new JsonException(e);
434+
} finally {
435+
JsonIteratorPool.returnJsonIterator(iter);
439436
}
440437
}
441438

@@ -463,7 +460,7 @@ public static final Any deserialize(Config config, byte[] input) {
463460

464461
public static final Any deserialize(byte[] input) {
465462
int lastNotSpacePos = findLastNotSpacePos(input);
466-
JsonIterator iter = tlsIter.get();
463+
JsonIterator iter = JsonIteratorPool.borrowJsonIterator();
467464
iter.reset(input, 0, lastNotSpacePos);
468465
try {
469466
Any val = iter.readAny();
@@ -475,6 +472,8 @@ public static final Any deserialize(byte[] input) {
475472
throw iter.reportError("deserialize", "premature end");
476473
} catch (IOException e) {
477474
throw new JsonException(e);
475+
} finally {
476+
JsonIteratorPool.returnJsonIterator(iter);
478477
}
479478
}
480479

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package com.jsoniter;
2+
3+
public class JsonIteratorPool {
4+
5+
private static ThreadLocal<JsonIterator> slot1 = new ThreadLocal<JsonIterator>();
6+
private static ThreadLocal<JsonIterator> slot2 = new ThreadLocal<JsonIterator>();
7+
8+
public static JsonIterator borrowJsonIterator() {
9+
JsonIterator iter = slot1.get();
10+
if (iter != null) {
11+
slot1.set(null);
12+
return iter;
13+
}
14+
iter = slot2.get();
15+
if (iter != null) {
16+
slot2.set(null);
17+
return iter;
18+
}
19+
return new JsonIterator();
20+
}
21+
22+
public static void returnJsonIterator(JsonIterator iter) {
23+
if (slot1.get() == null) {
24+
slot1.set(iter);
25+
return;
26+
}
27+
if (slot2.get() == null) {
28+
slot2.set(iter);
29+
return;
30+
}
31+
}
32+
}

src/main/java/com/jsoniter/any/Any.java

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -233,10 +233,6 @@ public Any set(String newVal) {
233233
return wrap(newVal);
234234
}
235235

236-
public JsonIterator parse() {
237-
throw new UnsupportedOperationException();
238-
}
239-
240236
public abstract void writeTo(JsonStream stream) throws IOException;
241237

242238
protected JsonException reportUnexpectedType(ValueType toType) {

src/main/java/com/jsoniter/any/ArrayLazyAny.java

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,13 @@ public Object object() {
3535

3636
@Override
3737
public boolean toBoolean() {
38+
JsonIterator iter = parse();
3839
try {
39-
return CodegenAccess.readArrayStart(parse());
40+
return CodegenAccess.readArrayStart(iter);
4041
} catch (IOException e) {
4142
throw new JsonException(e);
43+
} finally {
44+
JsonIteratorPool.returnJsonIterator(iter);
4245
}
4346
}
4447

@@ -119,8 +122,8 @@ private void fillCache() {
119122
if (cache == null) {
120123
cache = new ArrayList<Any>(4);
121124
}
125+
JsonIterator iter = JsonIteratorPool.borrowJsonIterator();
122126
try {
123-
JsonIterator iter = tlsIter.get();
124127
iter.reset(data, lastParsedPos, tail);
125128
if (lastParsedPos == head) {
126129
if (!CodegenAccess.readArrayStart(iter)) {
@@ -135,6 +138,8 @@ private void fillCache() {
135138
lastParsedPos = tail;
136139
} catch (IOException e) {
137140
throw new JsonException(e);
141+
} finally {
142+
JsonIteratorPool.returnJsonIterator(iter);
138143
}
139144
}
140145

@@ -149,8 +154,8 @@ private Any fillCacheUntil(int target) {
149154
if (target < i) {
150155
return cache.get(target);
151156
}
157+
JsonIterator iter = JsonIteratorPool.borrowJsonIterator();
152158
try {
153-
JsonIterator iter = tlsIter.get();
154159
iter.reset(data, lastParsedPos, tail);
155160
if (lastParsedPos == head) {
156161
if (!CodegenAccess.readArrayStart(iter)) {
@@ -176,6 +181,8 @@ private Any fillCacheUntil(int target) {
176181
lastParsedPos = tail;
177182
} catch (IOException e) {
178183
throw new JsonException(e);
184+
} finally {
185+
JsonIteratorPool.returnJsonIterator(iter);
179186
}
180187
throw new IndexOutOfBoundsException();
181188
}

src/main/java/com/jsoniter/any/DoubleLazyAny.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package com.jsoniter.any;
22

3+
import com.jsoniter.JsonIterator;
4+
import com.jsoniter.JsonIteratorPool;
35
import com.jsoniter.spi.JsonException;
46
import com.jsoniter.ValueType;
57

@@ -57,10 +59,13 @@ public double toDouble() {
5759

5860
private void fillCache() {
5961
if (!isCached) {
62+
JsonIterator iter = parse();
6063
try {
61-
cache = parse().readDouble();
64+
cache = iter.readDouble();
6265
} catch (IOException e) {
6366
throw new JsonException(e);
67+
} finally {
68+
JsonIteratorPool.returnJsonIterator(iter);
6469
}
6570
isCached = true;
6671
}

src/main/java/com/jsoniter/any/LazyAny.java

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.jsoniter.any;
22

3+
import com.jsoniter.JsonIteratorPool;
34
import com.jsoniter.spi.JsonException;
45
import com.jsoniter.JsonIterator;
56
import com.jsoniter.ValueType;
@@ -10,13 +11,6 @@
1011

1112
abstract class LazyAny extends Any {
1213

13-
protected static ThreadLocal<JsonIterator> tlsIter = new ThreadLocal<JsonIterator>() {
14-
@Override
15-
protected JsonIterator initialValue() {
16-
return new JsonIterator();
17-
}
18-
};
19-
2014
protected final byte[] data;
2115
protected final int head;
2216
protected final int tail;
@@ -30,43 +24,55 @@ public LazyAny(byte[] data, int head, int tail) {
3024
public abstract ValueType valueType();
3125

3226
public final <T> T bindTo(T obj) {
27+
JsonIterator iter = parse();
3328
try {
34-
return parse().read(obj);
29+
return iter.read(obj);
3530
} catch (IOException e) {
3631
throw new JsonException(e);
32+
} finally {
33+
JsonIteratorPool.returnJsonIterator(iter);
3734
}
3835
}
3936

4037
public final <T> T bindTo(TypeLiteral<T> typeLiteral, T obj) {
38+
JsonIterator iter = parse();
4139
try {
42-
return parse().read(typeLiteral, obj);
40+
return iter.read(typeLiteral, obj);
4341
} catch (IOException e) {
4442
throw new JsonException(e);
43+
} finally {
44+
JsonIteratorPool.returnJsonIterator(iter);
4545
}
4646
}
4747

4848
public final <T> T as(Class<T> clazz) {
49+
JsonIterator iter = parse();
4950
try {
50-
return parse().read(clazz);
51+
return iter.read(clazz);
5152
} catch (IOException e) {
5253
throw new JsonException(e);
54+
} finally {
55+
JsonIteratorPool.returnJsonIterator(iter);
5356
}
5457
}
5558

5659
public final <T> T as(TypeLiteral<T> typeLiteral) {
60+
JsonIterator iter = parse();
5761
try {
58-
return parse().read(typeLiteral);
62+
return iter.read(typeLiteral);
5963
} catch (IOException e) {
6064
throw new JsonException(e);
65+
} finally {
66+
JsonIteratorPool.returnJsonIterator(iter);
6167
}
6268
}
6369

6470
public String toString() {
6571
return new String(data, head, tail - head);
6672
}
6773

68-
public final JsonIterator parse() {
69-
JsonIterator iter = tlsIter.get();
74+
protected final JsonIterator parse() {
75+
JsonIterator iter = JsonIteratorPool.borrowJsonIterator();
7076
iter.reset(data, head, tail);
7177
return iter;
7278
}

src/main/java/com/jsoniter/any/LongLazyAny.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package com.jsoniter.any;
22

3+
import com.jsoniter.JsonIterator;
4+
import com.jsoniter.JsonIteratorPool;
35
import com.jsoniter.spi.JsonException;
46
import com.jsoniter.ValueType;
57

@@ -57,10 +59,13 @@ public double toDouble() {
5759

5860
private void fillCache() {
5961
if (!isCached) {
62+
JsonIterator iter = parse();
6063
try {
61-
cache = parse().readLong();
64+
cache = iter.readLong();
6265
} catch (IOException e) {
6366
throw new JsonException(e);
67+
} finally {
68+
JsonIteratorPool.returnJsonIterator(iter);
6469
}
6570
isCached = true;
6671
}

0 commit comments

Comments
 (0)