/* * Copyright 2000-2010 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.*; /** * @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(new Pair<Key,Val>(key, val)); return true; } }); return result.get(); } }