Skip to content

Commit e7a36c8

Browse files
committed
More efficient parsing of immutable maps
1 parent 75f2365 commit e7a36c8

File tree

2 files changed

+40
-13
lines changed

2 files changed

+40
-13
lines changed

jsoniter-scala-macros/shared/src/main/scala-2/com/github/plokhotnyuk/jsoniter_scala/macros/JsonCodecMaker.scala

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1773,6 +1773,18 @@ object JsonCodecMaker {
17731773
val readVal1 = genReadVal(tpe1 :: types, genNullValue(tpe1 :: types), isStringified, EmptyTree)
17741774
genReadMapAsArray(newBuilder, q"x.update($readVal1, { if (in.isNextToken(',')) $readVal2 else in.commaError() })")
17751775
} else genReadMap(newBuilder, q"x.update(${genReadKey(tpe1 :: types)}, $readVal2)")
1776+
} else if (tpe <:< typeOf[immutable.Map[_, _]]) withDecoderFor(methodKey, default) {
1777+
val tpe1 = typeArg1(tpe)
1778+
val tpe2 = typeArg2(tpe)
1779+
val newBuilder = q"var x = ${withNullValueFor(tpe)(q"${scalaCollectionCompanion(tpe)}.empty[$tpe1, $tpe2]")}"
1780+
val readVal2 = genReadVal(tpe2 :: types, genNullValue(tpe2 :: types), isStringified, EmptyTree)
1781+
if (cfg.mapAsArray) {
1782+
val readVal1 = genReadVal(tpe1 :: types, genNullValue(tpe1 :: types), isStringified, EmptyTree)
1783+
genReadMapAsArray(newBuilder, q"x = x.updated($readVal1, { if (in.isNextToken(',')) $readVal2 else in.commaError() })")
1784+
} else {
1785+
val readKey = genReadKey(tpe1 :: types)
1786+
genReadMap(newBuilder, q"x = x.updated($readKey, $readVal2)")
1787+
}
17761788
} else if (tpe <:< typeOf[collection.Map[_, _]]) withDecoderFor(methodKey, default) {
17771789
val tpe1 = typeArg1(tpe)
17781790
val tpe2 = typeArg2(tpe)

jsoniter-scala-macros/shared/src/main/scala-3/com/github/plokhotnyuk/jsoniter_scala/macros/JsonCodecMaker.scala

Lines changed: 28 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2477,9 +2477,7 @@ object JsonCodecMaker {
24772477
if ($tDefault.isEmpty) $tDefault
24782478
else $tEmpty
24792479
}.asExprOf[T & mutable.Map[t1, t2]]
2480-
2481-
def readVal2(using Quotes) = genReadVal(tpe2 :: types, genNullValue[t2](tpe2 :: types), isStringified, false, in)
2482-
2480+
val readVal2 = genReadVal(tpe2 :: types, genNullValue[t2](tpe2 :: types), isStringified, false, in)
24832481
if (cfg.mapAsArray) {
24842482
val readVal1 = genReadVal(tpe1 :: types, genNullValue[t1](tpe1 :: types), isStringified, false, in)
24852483
genReadMapAsArray(newBuilder,
@@ -2489,25 +2487,42 @@ object JsonCodecMaker {
24892487
genReadMap(newBuilder, x => '{ $x.update(${genReadKey[t1](tpe1 :: types, in)}, $readVal2) },
24902488
identity, in, tDefault).asExprOf[T]
24912489
}
2490+
} else if (tpe <:< TypeRepr.of[immutable.Map[?, ?]]) withDecoderFor(methodKey, default, in) { (in, default) =>
2491+
val tpe1 = typeArg1(tpe)
2492+
val tpe2 = typeArg2(tpe)
2493+
(tpe1.asType, tpe2.asType) match
2494+
case ('[t1], '[t2]) =>
2495+
lazy val readKey = genReadKey[t1](tpe1 :: types, in)
2496+
lazy val readVal1 = genReadVal(tpe1 :: types, genNullValue[t1](tpe1 :: types), isStringified, false, in)
2497+
val readVal2 = genReadVal(tpe2 :: types, genNullValue[t2](tpe2 :: types), isStringified, false, in)
2498+
val newBuilder =
2499+
(if (tpe <:< TypeRepr.of[immutable.SortedMap[?, ?]] || tpe <:< TypeRepr.of[immutable.TreeMap[?, ?]]) {
2500+
Apply(scalaMapEmptyNoArgs(tpe, tpe1, tpe2), List(summonOrdering(tpe1)))
2501+
} else if (tpe <:< TypeRepr.of[immutable.TreeSeqMap[?, ?]]) {
2502+
'{ immutable.TreeSeqMap.Empty.asInstanceOf[immutable.TreeSeqMap[t1, t2]] }.asTerm
2503+
} else withNullValueFor(tpe)(scalaMapEmptyNoArgs(tpe, tpe1, tpe2).asExprOf[T]).asTerm).asExprOf[T & immutable.Map[t1, t2]]
2504+
if (cfg.mapAsArray) {
2505+
genReadMapAsArray(newBuilder,
2506+
x => Assign(x.asTerm, '{ $x.updated($readVal1, { if ($in.isNextToken(',')) $readVal2 else $in.commaError() })}.asTerm).asExprOf[Unit],
2507+
identity, in, default.asExprOf[T & immutable.Map[t1, t2]]).asExprOf[T]
2508+
} else {
2509+
genReadMap(newBuilder,
2510+
x => Assign(x.asTerm, '{ $x.updated($readKey, $readVal2) }.asTerm).asExprOf[Unit],
2511+
identity, in, default.asExprOf[T & immutable.Map[t1, t2]]).asExprOf[T]
2512+
}
24922513
} else if (tpe <:< TypeRepr.of[collection.Map[?, ?]]) withDecoderFor(methodKey, default, in) { (in, default) =>
24932514
val tpe1 = typeArg1(tpe)
24942515
val tpe2 = typeArg2(tpe)
24952516
(tpe1.asType, tpe2.asType) match
24962517
case ('[t1], '[t2]) =>
2497-
def builderNoApply =
2518+
val builderNoApply =
24982519
TypeApply(Select.unique(scalaCollectionCompanion(tpe), "newBuilder"), List(TypeTree.of[t1], TypeTree.of[t2]))
2499-
2500-
def readKey(using Quotes) = genReadKey[t1](tpe1 :: types, in)
2501-
2502-
def readVal2(using Quotes) = genReadVal(tpe2 :: types, genNullValue[t2](tpe2 :: types), isStringified, false, in)
2503-
2504-
def readVal1(using Quotes) = genReadVal(tpe1 :: types, genNullValue[t1](tpe1 :: types), isStringified, false, in)
2505-
2520+
lazy val readKey = genReadKey[t1](tpe1 :: types, in)
2521+
lazy val readVal1 = genReadVal(tpe1 :: types, genNullValue[t1](tpe1 :: types), isStringified, false, in)
2522+
val readVal2 = genReadVal(tpe2 :: types, genNullValue[t2](tpe2 :: types), isStringified, false, in)
25062523
val newBuilder =
25072524
(if (tpe <:< TypeRepr.of[collection.SortedMap[?, ?]]) Apply(builderNoApply, List(summonOrdering(tpe1)))
2508-
else if (tpe <:< TypeRepr.of[immutable.TreeSeqMap[?, ?]]) '{ immutable.TreeSeqMap.newBuilder[t1, t2] }.asTerm
25092525
else builderNoApply).asExprOf[mutable.Builder[(t1, t2), T & collection.Map[t1, t2]]]
2510-
25112526
if (cfg.mapAsArray) {
25122527
genReadMapAsArray(newBuilder,
25132528
x => '{ $x.addOne(new Tuple2($readVal1, { if ($in.isNextToken(',')) $readVal2 else $in.commaError() })): Unit},

0 commit comments

Comments
 (0)