Skip to content

Commit 5e42940

Browse files
author
Sam Pullara
committed
fix field handling
1 parent 20167b4 commit 5e42940

File tree

2 files changed

+227
-2
lines changed

2 files changed

+227
-2
lines changed

indy/src/main/java/com/github/mustachejava/indy/IndyWrapper.java

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,11 @@ public static Object lookup(MutableCallSite callSite, IndyWrapper iw, Object sco
112112
Method method = iw.getMethod();
113113
if (method == null) {
114114
Field field = iw.getField();
115-
callSite.setTarget(MethodHandles.lookup().unreflectGetter(field));
115+
MethodHandle unreflect = MethodHandles.lookup().unreflectGetter(field);
116+
unreflect = MethodHandles.dropArguments(unreflect, 0, IndyWrapper.class);
117+
unreflect = MethodHandles.explicitCastArguments(unreflect,
118+
MethodType.methodType(Object.class, IndyWrapper.class, Object.class));
119+
callSite.setTarget(unreflect);
116120
return field.get(scope);
117121
} else {
118122
MethodHandle unreflect = MethodHandles.lookup().unreflect(method);
@@ -122,7 +126,8 @@ public static Object lookup(MutableCallSite callSite, IndyWrapper iw, Object sco
122126
unreflect = MethodHandles.insertArguments(unreflect, i + 2, iw.getArguments()[i]);
123127
}
124128
}
125-
unreflect = MethodHandles.explicitCastArguments(unreflect, MethodType.methodType(Object.class, IndyWrapper.class, Object.class));
129+
unreflect = MethodHandles.explicitCastArguments(unreflect,
130+
MethodType.methodType(Object.class, IndyWrapper.class, Object.class));
126131
callSite.setTarget(unreflect);
127132
return method.invoke(scope, iw.getArguments());
128133
}
Lines changed: 220 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,220 @@
1+
package com.github.mustachejava;
2+
3+
import java.io.File;
4+
import java.io.IOException;
5+
import java.io.InputStream;
6+
import java.io.StringWriter;
7+
import java.io.Writer;
8+
import java.util.ArrayList;
9+
import java.util.HashMap;
10+
import java.util.Iterator;
11+
import java.util.List;
12+
import java.util.Map;
13+
import java.util.concurrent.ExecutorService;
14+
import java.util.concurrent.Executors;
15+
import java.util.concurrent.Semaphore;
16+
import java.util.concurrent.atomic.AtomicInteger;
17+
18+
import com.github.mustachejava.indy.IndyObjectHandler;
19+
import junit.framework.TestCase;
20+
import org.codehaus.jackson.JsonNode;
21+
import org.codehaus.jackson.map.MappingJsonFactory;
22+
23+
/**
24+
* Tests for the compiler.
25+
* <p/>
26+
* User: sam
27+
* Date: May 3, 2010
28+
* Time: 10:23:54 AM
29+
*/
30+
public class JsonInterpreterTest extends TestCase {
31+
private static final int TIME = 2;
32+
33+
private File root;
34+
35+
public Object toObject(final JsonNode node) {
36+
if (node.isArray()) {
37+
return new ArrayList() {{
38+
for (JsonNode jsonNodes : node) {
39+
add(toObject(jsonNodes));
40+
}
41+
}};
42+
} else if (node.isObject()) {
43+
return new HashMap() {{
44+
for (Iterator<Map.Entry<String, JsonNode>> i = node.getFields(); i.hasNext(); ) {
45+
Map.Entry<String, JsonNode> next = i.next();
46+
Object o = toObject(next.getValue());
47+
put(next.getKey(), o);
48+
}
49+
}};
50+
} else if (node.isNull()) {
51+
return null;
52+
} else {
53+
return node.asText();
54+
}
55+
}
56+
57+
public void testSingleThreaded() throws MustacheException, IOException, InterruptedException {
58+
final Mustache parse = getMustache();
59+
final Object parent = getScope();
60+
61+
singlethreaded(parse, parent);
62+
}
63+
64+
public void testMultithreaded() throws IOException, InterruptedException {
65+
final Mustache parse = getMustache();
66+
final Object parent = getScope();
67+
68+
final AtomicInteger runs = new AtomicInteger(0);
69+
ExecutorService es = Executors.newCachedThreadPool();
70+
int range = (int) Math.round(Runtime.getRuntime().availableProcessors() * 1.5 + 1);
71+
for (int threads = 1; threads < range; threads++) {
72+
final Semaphore semaphore = new Semaphore(threads);
73+
{
74+
long start = System.currentTimeMillis();
75+
while (true) {
76+
semaphore.acquire();
77+
es.submit(new Runnable() {
78+
@Override
79+
public void run() {
80+
parse.execute(new NullWriter(), new Object[] { parent });
81+
runs.incrementAndGet();
82+
semaphore.release();
83+
}
84+
});
85+
if (System.currentTimeMillis() - start > TIME * 1000) {
86+
break;
87+
}
88+
}
89+
System.out.println("NullWriter Serial with " + threads + " threads: " + runs.intValue() / TIME + "/s " + " per thread: " + (runs.intValue() / TIME / threads));
90+
runs.set(0);
91+
Thread.sleep(100);
92+
}
93+
}
94+
}
95+
96+
private Object getScope() throws IOException {
97+
MappingJsonFactory jf = new MappingJsonFactory();
98+
InputStream json = getClass().getClassLoader().getResourceAsStream("hogan.json");
99+
final Map node = (Map) toObject(jf.createJsonParser(json).readValueAsTree());
100+
System.out.println(node);
101+
return new Object() {
102+
int uid = 0;
103+
List tweets = new ArrayList() {{
104+
for (int i = 0; i < 50; i++) {
105+
add(node);
106+
}
107+
}};
108+
};
109+
}
110+
111+
private Mustache getMustache() {
112+
DefaultMustacheFactory mb = new DefaultMustacheFactory(root);
113+
mb.setObjectHandler(new IndyObjectHandler());
114+
final Mustache parse = mb.compile("timeline.mustache");
115+
mb.compile("timeline.mustache");
116+
return parse;
117+
}
118+
119+
private void singlethreaded(Mustache parse, Object parent) {
120+
long start = System.currentTimeMillis();
121+
System.out.println(System.currentTimeMillis() - start);
122+
start = System.currentTimeMillis();
123+
StringWriter writer = new StringWriter();
124+
parse.execute(writer, parent);
125+
126+
start = System.currentTimeMillis();
127+
for (int i = 0; i < 500; i++) {
128+
parse.execute(new StringWriter(), parent);
129+
}
130+
System.out.println((System.currentTimeMillis() - start));
131+
132+
start = System.currentTimeMillis();
133+
for (int i = 0; i < 500; i++) {
134+
parse.execute(new StringWriter(), parent);
135+
}
136+
System.out.println((System.currentTimeMillis() - start));
137+
138+
start = System.currentTimeMillis();
139+
for (int i = 0; i < 500; i++) {
140+
parse.execute(new StringWriter(), parent);
141+
}
142+
System.out.println((System.currentTimeMillis() - start));
143+
144+
System.out.println("timeline.html evaluations per millisecond:");
145+
for (int i = 0; i < 2; i++) {
146+
{
147+
start = System.currentTimeMillis();
148+
int total = 0;
149+
while (true) {
150+
parse.execute(new NullWriter(), parent);
151+
total++;
152+
if (System.currentTimeMillis() - start > TIME * 1000) break;
153+
}
154+
System.out.println("NullWriter Serial: " + total / TIME + "/s");
155+
}
156+
{
157+
start = System.currentTimeMillis();
158+
int total = 0;
159+
while (true) {
160+
parse.execute(new StringWriter(), parent);
161+
total++;
162+
if (System.currentTimeMillis() - start > TIME * 1000) break;
163+
}
164+
System.out.println("StringWriter Serial: " + total / TIME + "/s");
165+
}
166+
}
167+
}
168+
169+
static class NullWriter extends Writer {
170+
@Override
171+
public void write(int c) throws IOException {
172+
}
173+
174+
@Override
175+
public void write(char[] cbuf) throws IOException {
176+
}
177+
178+
@Override
179+
public void write(String str) throws IOException {
180+
}
181+
182+
@Override
183+
public void write(String str, int off, int len) throws IOException {
184+
}
185+
186+
@Override
187+
public Writer append(CharSequence csq) throws IOException {
188+
return this;
189+
}
190+
191+
@Override
192+
public Writer append(CharSequence csq, int start, int end) throws IOException {
193+
return this;
194+
}
195+
196+
@Override
197+
public Writer append(char c) throws IOException {
198+
return this;
199+
}
200+
201+
@Override
202+
public void write(char[] cbuf, int off, int len) throws IOException {
203+
}
204+
205+
@Override
206+
public void flush() throws IOException {
207+
}
208+
209+
@Override
210+
public void close() throws IOException {
211+
}
212+
}
213+
214+
protected void setUp() throws Exception {
215+
super.setUp();
216+
File file = new File("src/test/resources");
217+
root = new File(file, "simple.html").exists() ? file : new File("../src/test/resources");
218+
}
219+
220+
}

0 commit comments

Comments
 (0)