1 /**
2 * Copyright 2003-2006 Greg Luck
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 package net.sf.ehcache;
18
19 import org.apache.commons.logging.Log;
20 import org.apache.commons.logging.LogFactory;
21
22 import java.io.ByteArrayInputStream;
23 import java.io.ByteArrayOutputStream;
24 import java.io.IOException;
25 import java.io.ObjectInputStream;
26 import java.io.ObjectOutputStream;
27 import java.io.Serializable;
28 import java.util.HashMap;
29
30 /**
31 * Test cases for the Element.
32 *
33 * @author <a href="mailto:gluck@thoughtworks.com">Greg Luck</a>
34 * @version $Id: ElementTest.java 44 2006-04-22 06:03:33Z gregluck $
35 */
36 public class ElementTest extends AbstractCacheTest {
37 private static final Log LOG = LogFactory.getLog(ElementTest.class.getName());
38
39
40 /**
41 * Checks serialization performance.
42 * <p/>
43 * {@link Element#getSerializedSize()} measures size by serializing, so this
44 * can be used to measure JVM serialization speed.
45 * <p/>
46 * For 310232 bytes the average serialization time is 7 ms
47 */
48 public void testSerializationPerformanceByteArray() throws CacheException {
49 Serializable key = "key";
50
51 ByteArrayOutputStream bout = new ByteArrayOutputStream();
52 for (int j = 0; j < 10000; j++) {
53 try {
54 bout.write("abcdefghijklmnopqrstv1234567890".getBytes());
55 } catch (IOException e) {
56 LOG.error("This should not happen");
57 }
58 }
59 byte[] value = bout.toByteArray();
60
61 Element element = new Element(key, value);
62 StopWatch stopWatch = new StopWatch();
63 for (int i = 0; i < 100; i++) {
64 element.getSerializedSize();
65 }
66 long elapsed = stopWatch.getElapsedTime() / 100;
67 LOG.info("In-memory size in bytes: " + element.getSerializedSize()
68 + " time to serialize in ms: " + elapsed);
69 assertTrue("Large object clone takes more than than 100ms", elapsed < 100);
70 }
71
72
73 /**
74 * Checks the serialization time for a large compound Java object
75 * Serialization time was 126ms for a size of 349225
76 */
77 public void testSerializationPerformanceJavaObjects() throws Exception {
78
79 HashMap map = new HashMap(10000);
80 for (int j = 0; j < 10000; j++) {
81 map.put("key" + j, new String[]{"adfdafs", "asdfdsafa", "sdfasdf"});
82 }
83 Element element = new Element("key1", map);
84 StopWatch stopWatch = new StopWatch();
85 for (int i = 0; i < 100; i++) {
86 element.getSerializedSize();
87 }
88 long elapsed = stopWatch.getElapsedTime() / 100;
89 LOG.info("In-memory size in bytes: " + element.getSerializedSize()
90 + " time to serialize in ms: " + elapsed);
91 assertTrue("Large object clone took more than 500ms", elapsed < 500);
92 }
93
94
95 /**
96 * Checks the expense of cloning a large object
97 * Average clone time 175ms for a size of 349225
98 */
99 public void testCalculateClonePerformanceJavaObjects() throws Exception {
100
101 HashMap map = new HashMap(10000);
102 for (int j = 0; j < 10000; j++) {
103 map.put("key" + j, new String[]{"adfdafs", "asdfdsafa", "sdfasdf"});
104 }
105 Element element = new Element("key1", map);
106 StopWatch stopWatch = new StopWatch();
107 for (int i = 0; i < 100; i++) {
108 element.clone();
109 }
110 long elapsed = stopWatch.getElapsedTime() / 100;
111 LOG.info("Time to clone object in ms: " + elapsed);
112 LOG.info("In-memory size in bytes: " + element.getSerializedSize()
113 + " time to clone in ms: " + elapsed);
114 assertTrue("Large object clone takes less than 1 second", elapsed < 1000);
115 }
116
117 /**
118 * Checks serialization performance.
119 * <p/>
120 * {@link Element#getSerializedSize()} measures size by serializing, so this
121 * can be used to measure JVM serialization speed.
122 * <p/>
123 * For 310232 bytes the average clone time is 50 ms, but on Mac JDK 1.5 i seems to have blown out to 116ms. It looks
124 * like a performance regression.
125 * <p/>
126 */
127 public void testClonePerformanceByteArray() throws CacheException, CloneNotSupportedException {
128 Serializable key = "key";
129
130 byte[] value = getTestByteArray();
131
132 Element element = new Element(key, value);
133 StopWatch stopWatch = new StopWatch();
134 for (int i = 0; i < 100; i++) {
135 element.clone();
136 }
137 long elapsed = stopWatch.getElapsedTime() / 100;
138 LOG.info("In-memory size in bytes: " + element.getSerializedSize()
139 + " time to serialize in ms: " + elapsed);
140 assertTrue("Large object clone takes less than 130 milliseconds", elapsed < 180);
141 }
142
143
144 private byte[] getTestByteArray() {
145 ByteArrayOutputStream bout = new ByteArrayOutputStream();
146 for (int j = 0; j < 10000; j++) {
147 try {
148 bout.write("abcdefghijklmnopqrstv1234567890".getBytes());
149 } catch (IOException e) {
150 LOG.error("This should not happen");
151 }
152 }
153 return bout.toByteArray();
154
155 }
156
157 /**
158 * Tests the deserialization performance of an element containing a large byte[]
159 *
160 * @throws IOException
161 * @throws ClassNotFoundException
162 */
163 public void testDeserializationPerformance() throws IOException, ClassNotFoundException {
164
165 byte[] value = getTestByteArray();
166 Element element = new Element("test", value);
167
168 ByteArrayOutputStream bout = new ByteArrayOutputStream();
169 ObjectOutputStream oos = new ObjectOutputStream(bout);
170 oos.writeObject(element);
171 byte[] serializedValue = bout.toByteArray();
172 oos.close();
173 StopWatch stopWatch = new StopWatch();
174 for (int i = 0; i < 100; i++) {
175 ByteArrayInputStream bin = new ByteArrayInputStream(serializedValue);
176 ObjectInputStream ois = new ObjectInputStream(bin);
177 ois.readObject();
178 ois.close();
179 }
180 long elapsed = stopWatch.getElapsedTime() / 100;
181 LOG.info("In-memory size in bytes: " + serializedValue.length
182 + " time to deserialize in ms: " + elapsed);
183 assertTrue(elapsed < 30);
184 }
185
186
187 /**
188 * ehcache-1.2 adds support to Objects in addition to Serializable. Check that this works
189 */
190 public void testObjectAccess() {
191 Object key = new Object();
192 Object value = new Object();
193 Element element = new Element(key, value);
194
195 assertEquals(key, element.getObjectKey());
196 assertEquals(value, element.getObjectValue());
197
198
199 try {
200 element.getKey();
201 } catch (CacheException e) {
202
203 }
204 assertEquals(value, element.getObjectValue());
205
206 }
207
208 /**
209 * ehcache-1.1 and earllier exclusively uses Serializable keys and values. Check that this works
210 */
211 public void testSerializableAccess() {
212 Serializable key = "";
213 Serializable value = "";
214 Element element = new Element(key, value);
215
216
217 assertEquals(key, element.getObjectKey());
218 assertEquals(value, element.getObjectValue());
219
220
221 assertEquals(key, element.getObjectKey());
222 assertEquals(value, element.getObjectValue());
223
224
225 }
226
227 }