changeset 5580:9ca10ab155e3

7107613: scalability blocker in javax.crypto.CryptoPermissions Reviewed-by: valeriep
author coffeys
date Mon, 03 Sep 2012 14:28:00 +0100
parents 9853268a0a8d
children 265fd0f23c8e
files src/share/classes/javax/crypto/CryptoPermissions.java
diffstat 1 files changed, 52 insertions(+), 21 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/classes/javax/crypto/CryptoPermissions.java	Mon Sep 03 14:33:02 2012 +0100
+++ b/src/share/classes/javax/crypto/CryptoPermissions.java	Mon Sep 03 14:28:00 2012 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 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
@@ -30,10 +30,16 @@
 import java.util.Hashtable;
 import java.util.Vector;
 import java.util.NoSuchElementException;
+import java.util.concurrent.ConcurrentHashMap;
 import java.io.Serializable;
 import java.io.InputStream;
 import java.io.InputStreamReader;
 import java.io.BufferedReader;
+import java.io.ObjectStreamField;
+import java.io.ObjectInputStream;
+import java.io.ObjectInputStream.GetField;
+import java.io.ObjectOutputStream;
+import java.io.ObjectOutputStream.PutField;
 import java.io.IOException;
 
 /**
@@ -61,15 +67,24 @@
 
     private static final long serialVersionUID = 4946547168093391015L;
 
-    // This class is similar to java.security.Permissions
-    private Hashtable perms;
+    /**
+     * @serialField perms java.util.Hashtable
+     */
+    private static final ObjectStreamField[] serialPersistentFields = {
+        new ObjectStreamField("perms", Hashtable.class),
+    };
+
+    // Switched from Hashtable to ConcurrentHashMap to improve scalability.
+    // To maintain serialization compatibility, this field is made transient
+    // and custom readObject/writeObject methods are used.
+    private transient ConcurrentHashMap<String,PermissionCollection> perms;
 
     /**
      * Creates a new CryptoPermissions object containing
      * no CryptoPermissionCollections.
      */
     CryptoPermissions() {
-        perms = new Hashtable(7);
+        perms = new ConcurrentHashMap<>(7);
     }
 
     /**
@@ -132,9 +147,7 @@
                         getPermissionCollection(cryptoPerm);
         pc.add(cryptoPerm);
         String alg = cryptoPerm.getAlgorithm();
-        if (!perms.containsKey(alg)) {
-            perms.put(alg, pc);
-        }
+        perms.putIfAbsent(alg, pc);
     }
 
     /**
@@ -382,20 +395,17 @@
     PermissionCollection getPermissionCollection(String alg) {
         // If this CryptoPermissions includes CryptoAllPermission,
         // we should return CryptoAllPermission.
-        if (perms.containsKey(CryptoAllPermission.ALG_NAME)) {
-            return
-                (PermissionCollection)(perms.get(CryptoAllPermission.ALG_NAME));
-        }
+        PermissionCollection pc = perms.get(CryptoAllPermission.ALG_NAME);
+        if (pc == null) {
+            pc = perms.get(alg);
 
-        PermissionCollection pc = (PermissionCollection)perms.get(alg);
-
-        // If there isn't a PermissionCollection for
-        // the given algorithm,we should return the
-        // PermissionCollection for the wildcard
-        // if there is one.
-        if (pc == null) {
-            pc = (PermissionCollection)perms.get(
-                                       CryptoPermission.ALG_NAME_WILDCARD);
+            // If there isn't a PermissionCollection for
+            // the given algorithm,we should return the
+            // PermissionCollection for the wildcard
+            // if there is one.
+            if (pc == null) {
+                pc = perms.get(CryptoPermission.ALG_NAME_WILDCARD);
+            }
         }
         return pc;
     }
@@ -421,6 +431,28 @@
         }
         return pc;
     }
+
+    private void readObject(ObjectInputStream s)
+        throws IOException, ClassNotFoundException {
+        ObjectInputStream.GetField fields = s.readFields();
+        @SuppressWarnings("unchecked")
+        Hashtable<String,PermissionCollection> permTable =
+                (Hashtable<String,PermissionCollection>)
+                (fields.get("perms", null));
+        if (permTable != null) {
+            perms = new ConcurrentHashMap<>(permTable);
+        } else {
+            perms = new ConcurrentHashMap<>();
+        }
+    }
+
+    private void writeObject(ObjectOutputStream s) throws IOException {
+        Hashtable<String,PermissionCollection> permTable =
+                new Hashtable<>(perms);
+        ObjectOutputStream.PutField fields = s.putFields();
+        fields.put("perms", permTable);
+        s.writeFields();
+    }
 }
 
 final class PermissionsEnumerator implements Enumeration {
@@ -463,7 +495,6 @@
         } else {
             throw new NoSuchElementException("PermissionsEnumerator");
         }
-
     }
 
     private Enumeration getNextEnumWithMore() {