summaryrefslogtreecommitdiffstats
path: root/src/main/java/com/google/gerrit/client/data/AccountCache.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/com/google/gerrit/client/data/AccountCache.java')
-rw-r--r--src/main/java/com/google/gerrit/client/data/AccountCache.java160
1 files changed, 160 insertions, 0 deletions
diff --git a/src/main/java/com/google/gerrit/client/data/AccountCache.java b/src/main/java/com/google/gerrit/client/data/AccountCache.java
new file mode 100644
index 0000000000..db2424f1c2
--- /dev/null
+++ b/src/main/java/com/google/gerrit/client/data/AccountCache.java
@@ -0,0 +1,160 @@
+// Copyright 2008 Google Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.gerrit.client.data;
+
+import com.google.gerrit.client.reviewdb.Account;
+import com.google.gerrit.client.reviewdb.ReviewDb;
+import com.google.gerrit.client.rpc.Common;
+import com.google.gwtorm.client.OrmException;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/** Cache of account information. */
+public class AccountCache {
+ private final LinkedHashMap<Account.Id, Account> byId =
+ new LinkedHashMap<Account.Id, Account>(16, 0.75f, true) {
+ @Override
+ protected boolean removeEldestEntry(
+ final Map.Entry<Account.Id, Account> eldest) {
+ return 4096 <= size();
+ }
+ };
+
+ /**
+ * Invalidate all cached information about a single user account.
+ *
+ * @param accountId the account to invalidate from the cache.
+ */
+ public void invalidate(final Account.Id accountId) {
+ synchronized (byId) {
+ byId.remove(accountId);
+ }
+ }
+
+ /**
+ * Get a single account.
+ *
+ * @param accountId the account to obtain.
+ * @return the cached account entity; null if the account is not in the
+ * database anymore.
+ */
+ public Account get(final Account.Id accountId) {
+ return get(accountId, null);
+ }
+
+ /**
+ * Get a single account.
+ *
+ * @param accountId the account to obtain.
+ * @param qd optional connection to reuse (if not null) when doing a lookup.
+ * @return the cached account entity; null if the account is not in the
+ * database anymore.
+ */
+ public Account get(final Account.Id accountId, final ReviewDb qd) {
+ if (accountId == null) {
+ return null;
+ }
+
+ Account m;
+ synchronized (byId) {
+ m = byId.get(accountId);
+ }
+ if (m != null) {
+ return m;
+ }
+
+ try {
+ final ReviewDb db = qd != null ? qd : Common.getSchemaFactory().open();
+ try {
+ m = db.accounts().get(accountId);
+ } finally {
+ if (qd == null) {
+ db.close();
+ }
+ }
+ } catch (OrmException e) {
+ m = null;
+ }
+ if (m != null) {
+ synchronized (byId) {
+ byId.put(m.getId(), m);
+ }
+ }
+ return m;
+ }
+
+ /**
+ * Lookup multiple account records.
+ *
+ * @param fetch set of all accounts to obtain.
+ * @param qd optional query handle to use if the account data is not in cache.
+ * @return records which match; if an account listed in <code>fetch</code> is
+ * not found it will not be returned.
+ */
+ public Collection<Account> get(final Set<Account.Id> fetch, final ReviewDb qd) {
+ final Set<Account.Id> toget = new HashSet<Account.Id>(fetch);
+ final Collection<Account> r = new ArrayList<Account>(toget.size());
+
+ synchronized (byId) {
+ for (final Iterator<Account.Id> i = toget.iterator(); i.hasNext();) {
+ final Account m = byId.get(i.next());
+ if (m != null) {
+ r.add(m);
+ i.remove();
+ }
+ }
+ }
+
+ if (!toget.isEmpty()) {
+ List<Account> found;
+ try {
+ final ReviewDb db = qd != null ? qd : Common.getSchemaFactory().open();
+ try {
+ found = qd.accounts().get(toget).toList();
+ } finally {
+ if (qd == null) {
+ db.close();
+ }
+ }
+ } catch (OrmException e) {
+ found = Collections.emptyList();
+ }
+ if (!found.isEmpty()) {
+ synchronized (byId) {
+ for (final Account a : found) {
+ byId.put(a.getId(), a);
+ }
+ }
+ r.addAll(found);
+ }
+ }
+ return r;
+ }
+
+ /** Force the entire cache to flush from memory and recompute. */
+ public void flush() {
+ synchronized (byId) {
+ byId.clear();
+ }
+ }
+}