ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/main/java/util/concurrent/Helpers.java
Revision: 1.1
Committed: Wed Mar 4 00:22:30 2015 UTC (9 years, 3 months ago) by jsr166
Branch: MAIN
Log Message:
optimize toString() methods; introduce Helpers

File Contents

# Content
1 /*
2 * Written by Martin Buchholz with assistance from members of JCP
3 * JSR-166 Expert Group and released to the public domain, as
4 * explained at http://creativecommons.org/publicdomain/zero/1.0/
5 */
6
7 package java.util.concurrent;
8
9 import java.util.Collection;
10
11 /** Shared implementation code for java.util.concurrent. */
12 class Helpers {
13 /**
14 * An implementation of Collection.toString() suitable for classes
15 * with locks. Instead of holding a lock for the entire duration of
16 * toString(), or acquiring a lock for each call to Iterator.next(),
17 * we hold the lock only during the call to toArray() (less
18 * disruptive to other threads accessing the collection) and follows
19 * the maxim "Never call foreign code while holding a lock".
20 */
21 static String collectionToString(Collection<?> c) {
22 final Object[] a = c.toArray();
23 final int size = a.length;
24 if (size == 0)
25 return "[]";
26 int charLength = 0;
27
28 // Replace every array element with its string representation
29 for (int i = 0; i < size; i++) {
30 Object e = a[i];
31 // Extreme compatibility with AbstractCollection.toString()
32 String s = (e == c) ? "(this Collection)" : objectToString(e);
33 a[i] = s;
34 charLength += s.length();
35 }
36
37 return toString(a, size, charLength);
38 }
39
40 /**
41 * Like Arrays.toString(), but caller guarantees that size > 0,
42 * each element with index 0 <= i < size is a non-null String,
43 * and charLength is the sum of the lengths of the input Strings.
44 */
45 static String toString(Object[] a, int size, int charLength) {
46 // assert a != null;
47 // assert size > 0;
48
49 // Copy each string into a perfectly sized char[]
50 // Length of [ , , , ] == 2 * size
51 final char[] chars = new char[charLength + 2 * size];
52 chars[0] = '[';
53 int j = 1;
54 for (int i = 0; i < size; i++) {
55 if (i > 0) {
56 chars[j++] = ',';
57 chars[j++] = ' ';
58 }
59 String s = (String) a[i];
60 int len = s.length();
61 s.getChars(0, len, chars, j);
62 j += len;
63 }
64 chars[j] = ']';
65 // assert j == chars.length - 1;
66 return newStringUnsafe(chars);
67 }
68
69 /** Optimized form of: key + "=" + val */
70 static String mapEntryToString(Object key, Object val) {
71 final String k, v;
72 final int klen, vlen;
73 final char[] chars =
74 new char[(klen = (k = objectToString(key)).length()) +
75 (vlen = (v = objectToString(val)).length()) + 1];
76 k.getChars(0, klen, chars, 0);
77 chars[klen] = '=';
78 v.getChars(0, vlen, chars, klen + 1);
79 return newStringUnsafe(chars);
80 }
81
82 private static String objectToString(Object x) {
83 // Extreme compatibility with StringBuilder.append(null)
84 String s;
85 return (x == null || (s = x.toString()) == null) ? "null" : s;
86 }
87
88 /**
89 * Returns a String containing the contents of chars, which caller
90 * promises will never be modified.
91 */
92 private static String newStringUnsafe(char[] chars) {
93 // If porting to a JDK where sun.misc.SharedSecrets is not
94 // available, modify the code below to simply:
95 // return new String(chars);
96 // TODO: Can we do this more portably?
97 return sun.misc.SharedSecrets.getJavaLangAccess().newStringUnsafe(chars);
98 }
99
100 }