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

# User Rev Content
1 jsr166 1.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     }