Skip to content

Commit

Permalink
Use lazy inited regex expression for template extraction (btraceio#363)
Browse files Browse the repository at this point in the history
  • Loading branch information
yardus authored and jbachorik committed Aug 26, 2018
1 parent 527d86f commit d402274
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 54 deletions.
70 changes: 16 additions & 54 deletions src/share/classes/com/sun/btrace/ArgsMap.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,18 @@
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
* A simple argument map wrapper allowing indexed access
*/
public final class ArgsMap implements Iterable<Map.Entry<String, String>>{
public final class ArgsMap implements Iterable<Map.Entry<String, String>> {
private static final class PatternSingleton {
// lazy initialization trick
// do not compile the pattern until it is actually requested
private static final Pattern INSTANCE = Pattern.compile("\\$\\{(.*?)\\}");
}
private final LinkedHashMap<String, String> map;
private final DebugSupport debug;

Expand Down Expand Up @@ -138,60 +145,15 @@ public String template(String value) {
return value;
}

StringBuilder sb = new StringBuilder();
StringBuilder keySb = new StringBuilder();
int state = 0;

for (char c : value.toCharArray()) {
switch (c) {
case '$': {
if (state == 0) {
state = 1;
}
break;
}
case '{': {
if (state == 1) {
state = 2;
keySb.setLength(0);
}
break;
}
case '}': {
if (state == 2) {
String key = keySb.toString();
String val = get(key);
if (val != null) {
sb.append(val);
} else {
sb.append("${").append(key).append("}");
}
state = 0;
}
break;
}
default: {
switch (state) {
case 0: {
sb.append(c);
break;
}
case 2: {
keySb.append(c);
break;
}
default: {
// other states are invalid; ignore input
}
}
}
}
}
Matcher matcher = PatternSingleton.INSTANCE.matcher(value);
StringBuffer buffer = new StringBuffer(value.length());

String expanded = sb.toString();
if (debug.isDebug()) {
debug.debug("Template: " + value + " -> " + expanded);
while (matcher.find()) {
String val = get(matcher.group(1));
matcher.appendReplacement(buffer, val != null ? val : "$0");
}
return expanded;
matcher.appendTail(buffer);

return buffer.toString();
}
}
55 changes: 55 additions & 0 deletions src/test/java/com/sun/btrace/ArgsMapTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package com.sun.btrace;

import org.junit.Before;
import org.junit.Test;
import static org.junit.Assert.*;

public class ArgsMapTest {
private static final String KEY1 = "key1";
private static final String KEY2 = "key2";
private static final String VALUE1 = "value1";
private static final String VALUE2 = "value2";

private ArgsMap instance;

@Before
public void setUp() {
instance = new ArgsMap();
instance.put(KEY1, VALUE1);
instance.put(KEY2, VALUE2);
}

@Test
public void templateExisting() {
String value = instance.template(KEY1 + "=${" + KEY1 + "}");
assertEquals(KEY1 + "=" + VALUE1, value);
}

@Test
public void templateNonExisting() {
String orig = KEY1 + "=${key3}";
String value = instance.template(orig);
assertEquals(orig, value);
}

@Test
public void templateTrailing$() {
String orig = KEY1 + "$";
String value = instance.template(orig);
assertEquals(orig, value);
}

@Test
public void templateUnclosedPlaceholder() {
String orig = KEY1 + "${";
String value = instance.template(orig);
assertEquals(orig, value);
}

@Test
public void templateSingle$() {
String orig = KEY1 + "$" + KEY2;
String value = instance.template(orig);
assertEquals(orig, value);
}
}

0 comments on commit d402274

Please sign in to comment.