Add permission_sort cache to remember sort orderings

Running the MostSpecificComparator on each access control request
to determine the order of AccessSections is expensive, especially
when regular expressions are used in sections and must be converted
to Automatons to evaulate their distance from the target.

Cache the order sections should be sorted in, making any future
sorting for the same reference name and same set of section patterns
cheaper.  Since the sorting is not project specific, the cache can
be more general and cover a lot of the server if most sections are
defined by parent projects.

We don't need to worry about flushing this cache, as it only sorts
the sort order, and the original input order is part of the cache
element key.  Any changes to access controls will still be reflected
in the result, and a change in inheritance or addition/removal
of sections will cause a new cache key to be used, discarding the
prior one via LRU when the cache is full.

Change-Id: Ied06561c9124f6ba8f5ea857a0eb17f47db2bc23
This commit is contained in:
Shawn O. Pearce
2011-06-24 11:01:25 -07:00
parent a429b1a2db
commit 0c1abdb2b7
7 changed files with 430 additions and 174 deletions

View File

@@ -0,0 +1,54 @@
// Copyright (C) 2011 The Android Open Source Project
//
// 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.server.git;
package com.google.gerrit.server.cache;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
/**
* An infinitely sized cache backed by java.util.ConcurrentHashMap.
* <p>
* This cache type is only suitable for unit tests, as it has no upper limit on
* number of items held in the cache. No upper limit can result in memory leaks
* in production servers.
*/
public class ConcurrentHashMapCache<K, V> implements Cache<K, V> {
private final ConcurrentHashMap<K, V> map = new ConcurrentHashMap<K, V>();
@Override
public V get(K key) {
return map.get(key);
}
@Override
public void put(K key, V value) {
map.put(key, value);
}
@Override
public void remove(K key) {
map.remove(key);
}
@Override
public void removeAll() {
map.clear();
}
@Override
public long getTimeToLive(TimeUnit unit) {
return 0;
}
}