7133138: Improve io performance around timezone lookups
authorcoffeys
Fri, 24 Feb 2012 09:10:27 +0000
changeset 11986 6f383069eb6d
parent 11914 d1311b0c757f
child 11987 a6dde4427e9d
7133138: Improve io performance around timezone lookups Reviewed-by: okutsu
jdk/make/tools/src/build/tools/javazic/Mappings.java
jdk/src/share/classes/sun/util/calendar/ZoneInfo.java
jdk/src/share/classes/sun/util/calendar/ZoneInfoFile.java
--- a/jdk/make/tools/src/build/tools/javazic/Mappings.java	Wed Feb 22 16:52:50 2012 -0800
+++ b/jdk/make/tools/src/build/tools/javazic/Mappings.java	Fri Feb 24 09:10:27 2012 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,6 +26,7 @@
 package build.tools.javazic;
 
 import  java.util.ArrayList;
+import  java.util.HashMap;
 import  java.util.LinkedList;
 import  java.util.List;
 import  java.util.Map;
@@ -162,6 +163,20 @@
         for (String key : toBeRemoved) {
             aliases.remove(key);
         }
+        // Eliminate any alias-to-alias mappings. For example, if
+        // there are A->B and B->C, A->B is changed to A->C.
+        Map<String, String> newMap = new HashMap<String, String>();
+        for (String key : aliases.keySet()) {
+            String realid = aliases.get(key);
+            String leaf = realid;
+            while (aliases.get(leaf) != null) {
+                leaf = aliases.get(leaf);
+            }
+            if (!realid.equals(leaf)) {
+                newMap.put(key, leaf);
+            }
+        }
+        aliases.putAll(newMap);
     }
 
     Map<String,String> getAliases() {
--- a/jdk/src/share/classes/sun/util/calendar/ZoneInfo.java	Wed Feb 22 16:52:50 2012 -0800
+++ b/jdk/src/share/classes/sun/util/calendar/ZoneInfo.java	Fri Feb 24 09:10:27 2012 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -79,13 +79,18 @@
     private static final int TRANSITION_NSHIFT = 12;
 
     // Flag for supporting JDK backward compatible IDs, such as "EST".
-    private static final boolean USE_OLDMAPPING;
+    static final boolean USE_OLDMAPPING;
     static {
       String oldmapping = AccessController.doPrivileged(
           new sun.security.action.GetPropertyAction("sun.timezone.ids.oldmapping", "false")).toLowerCase(Locale.ROOT);
       USE_OLDMAPPING = (oldmapping.equals("yes") || oldmapping.equals("true"));
     }
 
+    // IDs having conflicting data between Olson and JDK 1.1
+    static final String[] conflictingIDs = {
+        "EST", "MST", "HST"
+    };
+
     private static final CalendarSystem gcal = CalendarSystem.getGregorianCalendar();
 
     /**
@@ -808,6 +813,16 @@
 
     private static SoftReference<Map<String, String>> aliasTable;
 
+    static Map<String, String> getCachedAliasTable() {
+        Map<String, String> aliases = null;
+
+        SoftReference<Map<String, String>> cache = aliasTable;
+        if (cache != null) {
+            aliases = cache.get();
+        }
+        return aliases;
+    }
+
     /**
      * Returns a Map from alias time zone IDs to their standard
      * time zone IDs.
@@ -816,23 +831,22 @@
      *    to their standard time zone IDs, or null if
      *    <code>ZoneInfoMappings</code> file is not available.
      */
-    public synchronized static Map<String, String> getAliasTable() {
-        Map<String, String> aliases = null;
-
-        SoftReference<Map<String, String>> cache = aliasTable;
-        if (cache != null) {
-            aliases = cache.get();
-            if (aliases != null) {
-                return aliases;
-            }
-        }
-
-        aliases = ZoneInfoFile.getZoneAliases();
-        if (aliases != null) {
-            aliasTable = new SoftReference<>(aliases);
-        }
-        return aliases;
-    }
+     public synchronized static Map<String, String> getAliasTable() {
+         Map<String, String> aliases = getCachedAliasTable();
+         if (aliases == null) {
+             aliases = ZoneInfoFile.getZoneAliases();
+             if (aliases != null) {
+                 if (!USE_OLDMAPPING) {
+                     // Remove the conflicting IDs from the alias table.
+                     for (String key : conflictingIDs) {
+                         aliases.remove(key);
+                     }
+                 }
+                 aliasTable = new SoftReference<Map<String, String>>(aliases);
+             }
+         }
+         return aliases;
+     }
 
     private void readObject(ObjectInputStream stream)
             throws IOException, ClassNotFoundException {
--- a/jdk/src/share/classes/sun/util/calendar/ZoneInfoFile.java	Wed Feb 22 16:52:50 2012 -0800
+++ b/jdk/src/share/classes/sun/util/calendar/ZoneInfoFile.java	Fri Feb 24 09:10:27 2012 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -473,6 +473,8 @@
 
     private static Map<String, ZoneInfo> zoneInfoObjects = null;
 
+    private static final ZoneInfo GMT = new ZoneInfo("GMT", 0);
+
     private static final String ziDir = AccessController.doPrivileged(
         new PrivilegedAction<String>() {
             public String run() {
@@ -553,8 +555,15 @@
      * id.
      */
     public static ZoneInfo getZoneInfo(String id) {
+        //treat GMT zone as special
+        if ("GMT".equals(id))
+            return (ZoneInfo) GMT.clone();
         ZoneInfo zi = getFromCache(id);
         if (zi == null) {
+            Map<String, String> aliases = ZoneInfo.getCachedAliasTable();
+            if (aliases != null && aliases.get(id) != null) {
+                return null;
+            }
             zi = createZoneInfo(id);
             if (zi == null) {
                 return null;
@@ -1031,30 +1040,26 @@
      * @return the buffer, or null if any I/O error occurred.
      */
     private static byte[] readZoneInfoFile(final String fileName) {
+        if (fileName.indexOf("..") >= 0) {
+            return null;
+        }
         byte[] buffer = null;
 
         try {
             buffer = AccessController.doPrivileged(new PrivilegedExceptionAction<byte[]>() {
                 public byte[] run() throws IOException {
                     File file = new File(ziDir, fileName);
-                    if (!file.exists() || !file.isFile()) {
-                        return null;
-                    }
-                    file = file.getCanonicalFile();
-                    String path = file.getCanonicalPath();
                     byte[] buf = null;
-                    if (path != null && path.startsWith(ziDir)) {
-                        int filesize = (int)file.length();
-                        if (filesize > 0) {
-                            FileInputStream fis = new FileInputStream(file);
-                            buf = new byte[filesize];
-                            try {
-                                if (fis.read(buf) != filesize) {
-                                    throw new IOException("read error on " + fileName);
-                                }
-                            } finally {
-                                fis.close();
+                    int filesize = (int)file.length();
+                    if (filesize > 0) {
+                        FileInputStream fis = new FileInputStream(file);
+                        buf = new byte[filesize];
+                        try {
+                            if (fis.read(buf) != filesize) {
+                                throw new IOException("read error on " + fileName);
                             }
+                        } finally {
+                            fis.close();
                         }
                     }
                     return buf;