blob: 161bcc39f377717a9b930d2b0d84fb783752ad83 [file] [log] [blame]
/*
* Copyright 2000-2014 JetBrains s.r.o.
*
* 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.intellij.openapi.vcs;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.Ref;
import com.intellij.util.PairProcessor;
import java.util.Comparator;
import java.util.Iterator;
import java.util.ListIterator;
/**
* @author irengrig
*/
public class MembershipMap<Key, Val> extends AreaMap<Key, Val> {
public static<Key extends Comparable<Key>, Val> MembershipMap<Key, Val> createMembershipMap(final PairProcessor<Key, Key> keysResemblance) {
return new MembershipMap<Key,Val>(keysResemblance, new ComparableComparator<Key>());
}
public static<Key, Val> MembershipMap<Key, Val> createMembershipMap(final PairProcessor<Key, Key> keysResemblance, final Comparator<Key> comparator) {
return new MembershipMap<Key,Val>(keysResemblance, comparator);
}
private MembershipMap(final PairProcessor<Key, Key> keysResemblance, final Comparator<Key> comparator) {
super(keysResemblance, comparator);
}
public void putOptimal(final Key key, final Val val) {
final int idx = putIfNoParent(key, val);
if (idx < 0) return;
if (idx + 1 < myKeys.size()) {
for (final ListIterator<Key> listIterator = myKeys.listIterator(idx + 1); listIterator.hasNext();) {
final Key next = listIterator.next();
if (myKeysResemblance.process(key, next)) {
listIterator.remove();
myMap.remove(next);
} else {
break;
}
}
}
}
public void optimizeMap(final PairProcessor<Val, Val> valuesAreas) {
int i = 0;
for (Iterator<Key> iterator = myKeys.iterator(); iterator.hasNext();) {
final Key key = iterator.next();
final Val value = myMap.get(key);
// go for parents
for (int j = i - 1; j >= 0; -- j) {
final Key innerKey = myKeys.get(j);
if (myKeysResemblance.process(innerKey, key)) {
if (valuesAreas.process(myMap.get(innerKey), value)) {
-- i;
iterator.remove();
myMap.remove(key);
}
// otherwise we found a "parent", and do not remove the child
break;
}
}
++ i;
}
}
public Pair<Key, Val> getMapping(final Key key) {
final Ref<Pair<Key, Val>> result = new Ref<Pair<Key, Val>>();
getSimiliar(key, new PairProcessor<Key, Val>() {
@Override
public boolean process(final Key key, final Val val) {
result.set(Pair.create(key, val));
return true;
}
});
return result.get();
}
}