]> WPIA git - gigi.git/commitdiff
Test+implement: object cache for email and domain.
authorFelix Dörre <felix@dogcraft.de>
Thu, 4 Sep 2014 12:23:38 +0000 (14:23 +0200)
committerFelix Dörre <felix@dogcraft.de>
Thu, 4 Sep 2014 12:23:38 +0000 (14:23 +0200)
src/org/cacert/gigi/Domain.java
src/org/cacert/gigi/EmailAddress.java
src/org/cacert/gigi/IdCachable.java [new file with mode: 0644]
src/org/cacert/gigi/ObjectCache.java [new file with mode: 0644]
src/org/cacert/gigi/User.java
tests/org/cacert/gigi/TestObjectCache.java [new file with mode: 0644]

index 21fe668edda1d638beb90287e769758c8b1f860e..5dbbdaf0203d52036a0b504c1c196c2304e94e82 100644 (file)
@@ -3,9 +3,10 @@ package org.cacert.gigi;
 import java.sql.PreparedStatement;
 import java.sql.ResultSet;
 import java.sql.SQLException;
+
 import org.cacert.gigi.database.DatabaseConnection;
 
-public class Domain {
+public class Domain implements IdCachable {
 
     private User owner;
 
@@ -62,6 +63,7 @@ public class Domain {
                 ps.setString(2, suffix);
                 ps.execute();
                 id = DatabaseConnection.lastInsertId(ps);
+                myCache.put(this);
             } catch (SQLException e) {
                 throw new GigiApiException(e);
             }
@@ -93,16 +95,6 @@ public class Domain {
         return suffix;
     }
 
-    public static Domain getById(int id) throws IllegalArgumentException {
-        // TODO cache
-        try {
-            Domain e = new Domain(id);
-            return e;
-        } catch (SQLException e) {
-            throw new IllegalArgumentException(e);
-        }
-    }
-
     public void addPing(String type, String config) throws GigiApiException {
         try {
             PreparedStatement ps = DatabaseConnection.getInstance().prepare("INSERT INTO pingconfig SET domainid=?, type=?, info=?");
@@ -157,4 +149,21 @@ public class Domain {
         }
 
     }
+
+    private static ObjectCache<Domain> myCache = new ObjectCache<>();
+
+    public static Domain getById(int id) throws IllegalArgumentException {
+        Domain em = myCache.get(id);
+        if (em == null) {
+            try {
+                synchronized (Domain.class) {
+                    myCache.put(em = new Domain(id));
+                }
+            } catch (SQLException e1) {
+                throw new IllegalArgumentException(e1);
+            }
+        }
+        return em;
+    }
+
 }
index 5259fbcdaf7aee47de93cb8627a139c29371e994..07ebfcc9a6258f53dc8146f100edd528a1a6037a 100644 (file)
@@ -11,7 +11,7 @@ import org.cacert.gigi.email.MailProbe;
 import org.cacert.gigi.localisation.Language;
 import org.cacert.gigi.util.RandomToken;
 
-public class EmailAddress {
+public class EmailAddress implements IdCachable {
 
     private String address;
 
@@ -54,8 +54,11 @@ public class EmailAddress {
             ps.setInt(1, owner.getId());
             ps.setString(2, hash);
             ps.setString(3, address);
-            ps.execute();
-            id = DatabaseConnection.lastInsertId(ps);
+            synchronized (EmailAddress.class) {
+                ps.execute();
+                id = DatabaseConnection.lastInsertId(ps);
+                myCache.put(this);
+            }
             MailProbe.sendMailProbe(l, "email", id, hash, address);
         } catch (SQLException e) {
             e.printStackTrace();
@@ -96,17 +99,23 @@ public class EmailAddress {
         }
     }
 
-    public static EmailAddress getById(int id) throws IllegalArgumentException {
-        // TODO cache
-        try {
-            EmailAddress e = new EmailAddress(id);
-            return e;
-        } catch (SQLException e) {
-            throw new IllegalArgumentException(e);
-        }
-    }
-
     public boolean isVerified() {
         return hash.isEmpty();
     }
+
+    private static ObjectCache<EmailAddress> myCache = new ObjectCache<>();
+
+    public static EmailAddress getById(int id) throws IllegalArgumentException {
+        EmailAddress em = myCache.get(id);
+        if (em == null) {
+            try {
+                synchronized (EmailAddress.class) {
+                    myCache.put(em = new EmailAddress(id));
+                }
+            } catch (SQLException e1) {
+                throw new IllegalArgumentException(e1);
+            }
+        }
+        return em;
+    }
 }
diff --git a/src/org/cacert/gigi/IdCachable.java b/src/org/cacert/gigi/IdCachable.java
new file mode 100644 (file)
index 0000000..0d218d5
--- /dev/null
@@ -0,0 +1,6 @@
+package org.cacert.gigi;
+
+public interface IdCachable {
+
+    public int getId();
+}
diff --git a/src/org/cacert/gigi/ObjectCache.java b/src/org/cacert/gigi/ObjectCache.java
new file mode 100644 (file)
index 0000000..9d8e936
--- /dev/null
@@ -0,0 +1,21 @@
+package org.cacert.gigi;
+
+import java.lang.ref.WeakReference;
+import java.util.HashMap;
+
+public class ObjectCache<T extends IdCachable> {
+
+    HashMap<Integer, WeakReference<T>> hashmap = new HashMap<>();
+
+    public void put(T c) {
+        hashmap.put(c.getId(), new WeakReference<T>(c));
+    }
+
+    public T get(int id) {
+        WeakReference<T> res = hashmap.get(id);
+        if (res != null) {
+            return res.get();
+        }
+        return null;
+    }
+}
index 842f2f20e11a071d2943aed124772d8119a95547..41396ae102e53ea121ad67364d764f78f3af6469 100644 (file)
@@ -13,7 +13,7 @@ import org.cacert.gigi.util.Notary;
 import org.cacert.gigi.util.PasswordHash;
 import org.cacert.gigi.util.PasswordStrengthChecker;
 
-public class User {
+public class User implements IdCachable {
 
     private int id;
 
@@ -129,8 +129,11 @@ public class User {
         query.setString(6, name.suffix);
         query.setDate(7, new java.sql.Date(dob.getTime()));
         query.setString(8, locale.toString());
-        query.execute();
-        id = DatabaseConnection.lastInsertId(query);
+        synchronized (User.class) {
+            query.execute();
+            id = DatabaseConnection.lastInsertId(query);
+            myCache.put(this);
+        }
     }
 
     public void changePassword(String oldPass, String newPass) throws GigiApiException {
@@ -253,10 +256,6 @@ public class User {
         return points;
     }
 
-    public static User getById(int id) {
-        return new User(id);
-    }
-
     public EmailAddress[] getEmails() {
         try {
             PreparedStatement ps = DatabaseConnection.getInstance().prepare("SELECT id FROM emails WHERE memid=? AND deleted=0");
@@ -495,4 +494,15 @@ public class User {
         update.executeUpdate();
     }
 
+    private static ObjectCache<User> myCache = new ObjectCache<>();
+
+    public static User getById(int id) {
+        User u = myCache.get(id);
+        if (u == null) {
+            synchronized (User.class) {
+                myCache.put(u = new User(id));
+            }
+        }
+        return u;
+    }
 }
diff --git a/tests/org/cacert/gigi/TestObjectCache.java b/tests/org/cacert/gigi/TestObjectCache.java
new file mode 100644 (file)
index 0000000..d361c16
--- /dev/null
@@ -0,0 +1,57 @@
+package org.cacert.gigi;
+
+import static org.hamcrest.CoreMatchers.*;
+import static org.junit.Assert.*;
+
+import java.sql.Date;
+import java.sql.SQLException;
+import java.util.Calendar;
+import java.util.Locale;
+
+import org.cacert.gigi.localisation.Language;
+import org.cacert.gigi.testUtils.ManagedTest;
+import org.junit.Test;
+
+public class TestObjectCache extends ManagedTest {
+
+    int uid = createVerifiedUser("fname", "lname", createUniqueName() + "@example.com", TEST_PASSWORD);
+
+    @Test
+    public void testUserCache() throws SQLException {
+        assertThat(User.getById(uid), is(sameInstance(User.getById(uid))));
+
+        User u = new User();
+        u.setFname("fname");
+        u.setMname("mname");
+        u.setSuffix("suffix");
+        u.setLname("lname");
+        u.setEmail(createUniqueName() + "@example.org");
+        Calendar c = Calendar.getInstance();
+        c.set(1950, 1, 1);
+        u.setDob(new Date(c.getTime().getTime()));
+        u.setPreferredLocale(Locale.ENGLISH);
+        u.insert(TEST_PASSWORD);
+
+        assertThat(u, is(sameInstance(User.getById(u.getId()))));
+        assertThat(User.getById(u.getId()), is(sameInstance(User.getById(u.getId()))));
+
+    }
+
+    @Test
+    public void testDomainCache() throws GigiApiException {
+        Domain d = new Domain(User.getById(uid), "example.org");
+        d.insert();
+
+        assertThat(d, is(sameInstance(Domain.getById(d.getId()))));
+        assertThat(Domain.getById(d.getId()), is(sameInstance(Domain.getById(d.getId()))));
+    }
+
+    @Test
+    public void testEmailCache() {
+        EmailAddress em = new EmailAddress(createUniqueName() + "@example.org", User.getById(uid));
+        em.insert(Language.getInstance(Locale.ENGLISH));
+
+        assertThat(em, is(sameInstance(EmailAddress.getById(em.getId()))));
+        assertThat(EmailAddress.getById(em.getId()), is(sameInstance(EmailAddress.getById(em.getId()))));
+    }
+}