Skip to content
This repository was archived by the owner on Jul 19, 2024. It is now read-only.

Commit b31dcab

Browse files
author
jofriedm-msft
authored
Merge pull request #154 from rajeshbalamohan/liststatus_opt
Minor CPU optimizations for listStatus
2 parents 05b44d7 + c253c74 commit b31dcab

File tree

2 files changed

+46
-17
lines changed

2 files changed

+46
-17
lines changed

microsoft-azure-storage/src/com/microsoft/azure/storage/core/Canonicalizer.java

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@
2525
import java.util.List;
2626
import java.util.Map;
2727
import java.util.Map.Entry;
28+
import java.util.regex.Matcher;
29+
import java.util.regex.Pattern;
2830

2931
import com.microsoft.azure.storage.Constants;
3032
import com.microsoft.azure.storage.StorageException;
@@ -45,6 +47,8 @@ abstract class Canonicalizer {
4547
*/
4648
private static final int ExpectedTableCanonicalizedStringLength = 200;
4749

50+
private static final Pattern CRLF = Pattern.compile("\r\n", Pattern.LITERAL);
51+
4852
/**
4953
* Add x-ms- prefixed headers in a fixed order.
5054
*
@@ -85,7 +89,8 @@ private static void addCanonicalizedHeaders(final HttpURLConnection conn, final
8589
}
8690

8791
// Unfolding is simply removal of CRLF.
88-
final String unfoldedValue = value.replace("\r\n", Constants.EMPTY_STRING);
92+
final String unfoldedValue = CRLF.matcher(value)
93+
.replaceAll(Matcher.quoteReplacement(Constants.EMPTY_STRING));
8994

9095
// Append it to the canonicalized element string.
9196
canonicalizedElement.append(delimiter);
@@ -251,6 +256,11 @@ protected static String getCanonicalizedResource(final java.net.URL address, fin
251256
final StringBuilder canonicalizedResource = new StringBuilder(resourcepath.toString());
252257

253258
// query parameters
259+
if (address.getQuery() == null || !address.getQuery().contains("=")) {
260+
//no query params.
261+
return canonicalizedResource.toString();
262+
}
263+
254264
final Map<String, String[]> queryVariables = PathUtility.parseQueryString(address.getQuery());
255265

256266
final Map<String, String> lowercasedKeyNameValue = new HashMap<String, String>();

microsoft-azure-storage/src/com/microsoft/azure/storage/core/Utility.java

Lines changed: 35 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,20 @@
7070
* RESERVED FOR INTERNAL USE. A class which provides utility methods.
7171
*/
7272
public final class Utility {
73+
74+
/**
75+
* Thread local for storing GMT date format.
76+
*/
77+
private static ThreadLocal<DateFormat>
78+
RFC1123_GMT_DATE_TIME_FORMATTER = new ThreadLocal<DateFormat>() {
79+
@Override
80+
protected DateFormat initialValue() {
81+
final DateFormat formatter = new SimpleDateFormat(RFC1123_PATTERN, LOCALE_US);
82+
formatter.setTimeZone(GMT_ZONE);
83+
return formatter;
84+
}
85+
};
86+
7387
/**
7488
* Stores a reference to the GMT time zone.
7589
*/
@@ -116,13 +130,22 @@ public final class Utility {
116130
* Used to create Json parsers and generators.
117131
*/
118132
private static final JsonFactory jsonFactory = new JsonFactory();
119-
133+
120134
/**
121-
* A factory to create SAXParser instances.
135+
* Thread local for SAXParser.
122136
*/
123-
private static final ThreadLocal<SAXParserFactory> saxParserFactory = new ThreadLocal<SAXParserFactory>() {
124-
@Override public SAXParserFactory initialValue() {
125-
return SAXParserFactory.newInstance();
137+
private static final ThreadLocal<SAXParser> saxParserThreadLocal = new ThreadLocal<SAXParser>() {
138+
SAXParserFactory factory;
139+
@Override public SAXParser initialValue() {
140+
factory = SAXParserFactory.newInstance();
141+
factory.setNamespaceAware(true);
142+
try {
143+
return factory.newSAXParser();
144+
} catch (SAXException e) {
145+
throw new RuntimeException("Unable to create SAXParser", e);
146+
} catch (ParserConfigurationException e) {
147+
throw new RuntimeException("Check parser configuration", e);
148+
}
126149
}
127150
};
128151

@@ -567,21 +590,18 @@ public static String getGMTTime() {
567590

568591
/**
569592
* Returns the GTM date/time String for the specified value using the RFC1123 pattern.
570-
*
593+
*
571594
* @param date
572595
* A <code>Date</code> object that represents the date to convert to GMT date/time in the RFC1123
573596
* pattern.
574-
*
597+
*
575598
* @return A <code>String</code> that represents the GMT date/time for the specified value using the RFC1123
576599
* pattern.
577600
*/
578601
public static String getGMTTime(final Date date) {
579-
final DateFormat formatter = new SimpleDateFormat(RFC1123_PATTERN, LOCALE_US);
580-
formatter.setTimeZone(GMT_ZONE);
581-
return formatter.format(date);
602+
return RFC1123_GMT_DATE_TIME_FORMATTER.get().format(date);
582603
}
583604

584-
585605
/**
586606
* Returns the UTC date/time String for the specified value using Java's version of the ISO8601 pattern,
587607
* which is limited to millisecond precision.
@@ -668,8 +688,9 @@ public static JsonParser getJsonParser(final InputStream inStream) throws JsonPa
668688
* @throws SAXException
669689
*/
670690
public static SAXParser getSAXParser() throws ParserConfigurationException, SAXException {
671-
saxParserFactory.get().setNamespaceAware(true);
672-
return saxParserFactory.get().newSAXParser();
691+
SAXParser parser = saxParserThreadLocal.get();
692+
parser.reset(); //reset to original config
693+
return parser;
673694
}
674695

675696
/**
@@ -811,9 +832,7 @@ public static HashMap<String, String> parseAccountString(final String parseStrin
811832
* If the specified string is invalid.
812833
*/
813834
public static Date parseRFC1123DateFromStringInGMT(final String value) throws ParseException {
814-
final DateFormat format = new SimpleDateFormat(RFC1123_PATTERN, Utility.LOCALE_US);
815-
format.setTimeZone(GMT_ZONE);
816-
return format.parse(value);
835+
return RFC1123_GMT_DATE_TIME_FORMATTER.get().parse(value);
817836
}
818837

819838
/**

0 commit comments

Comments
 (0)