private void addToMap(int id, int index) { id = unwrap(myFactory.getValue(id)).getID(); int[] classes = myIdToEqClassesIndices.get(id); if (classes == null) { classes = new int[] {index}; myIdToEqClassesIndices.put(id, classes); } else { classes = ArrayUtil.append(classes, index); myIdToEqClassesIndices.put(id, classes); } }
private void removeFromMap(int id, int index) { id = unwrap(myFactory.getValue(id)).getID(); int[] classes = myIdToEqClassesIndices.get(id); if (classes != null) { int i = ArrayUtil.indexOf(classes, index); if (i != -1) { classes = ArrayUtil.remove(classes, i); myIdToEqClassesIndices.put(id, classes); } } }
private boolean uniteClasses(int c1Index, int c2Index) { EqClass c1 = myEqClasses.get(c1Index); EqClass c2 = myEqClasses.get(c2Index); Set<DfaVariableValue> vars = ContainerUtil.newTroveSet(); Set<DfaVariableValue> negatedVars = ContainerUtil.newTroveSet(); int[] cs = new int[c1.size() + c2.size()]; c1.set(0, cs, 0, c1.size()); c2.set(0, cs, c1.size(), c2.size()); int nConst = 0; for (int c : cs) { DfaValue dfaValue = unwrap(myFactory.getValue(c)); if (dfaValue instanceof DfaConstValue) nConst++; if (dfaValue instanceof DfaVariableValue) { DfaVariableValue variableValue = (DfaVariableValue) dfaValue; if (variableValue.isNegated()) { negatedVars.add(variableValue.createNegated()); } else { vars.add(variableValue); } } if (nConst > 1) return false; } if (ContainerUtil.intersects(vars, negatedVars)) return false; TLongArrayList c2Pairs = new TLongArrayList(); long[] distincts = myDistinctClasses.toArray(); for (long distinct : distincts) { int pc1 = low(distinct); int pc2 = high(distinct); boolean addedToC1 = false; if (pc1 == c1Index || pc2 == c1Index) { addedToC1 = true; } if (pc1 == c2Index || pc2 == c2Index) { if (addedToC1) return false; c2Pairs.add(distinct); } } EqClass newClass = new EqClass(c1); myEqClasses.set(c1Index, newClass); for (int i = 0; i < c2.size(); i++) { int c = c2.get(i); newClass.add(c); removeFromMap(c, c2Index); addToMap(c, c1Index); } for (int i = 0; i < c2Pairs.size(); i++) { long c = c2Pairs.get(i); myDistinctClasses.remove(c); myDistinctClasses.add(createPair(c1Index, low(c) == c2Index ? high(c) : low(c))); } myEqClasses.set(c2Index, null); return true; }
private void removeAllFromMap(int id) { if (id < 0) return; id = unwrap(myFactory.getValue(id)).getID(); myIdToEqClassesIndices.remove(id); }
void doFlush(@NotNull DfaVariableValue varPlain, boolean markUnknown) { DfaVariableValue varNegated = varPlain.getNegatedValue(); final int idPlain = varPlain.getID(); final int idNegated = varNegated == null ? -1 : varNegated.getID(); int[] classes = myIdToEqClassesIndices.get(idPlain); int[] negatedClasses = myIdToEqClassesIndices.get(idNegated); int[] result = ArrayUtil.mergeArrays( ObjectUtils.notNull(classes, ArrayUtil.EMPTY_INT_ARRAY), ObjectUtils.notNull(negatedClasses, ArrayUtil.EMPTY_INT_ARRAY)); int interruptCount = 0; for (int varClassIndex : result) { EqClass varClass = myEqClasses.get(varClassIndex); if ((++interruptCount & 0xf) == 0) { ProgressManager.checkCanceled(); } varClass = new EqClass(varClass); myEqClasses.set(varClassIndex, varClass); for (int id : varClass.toNativeArray()) { int idUnwrapped; if (id == idPlain || id == idNegated || (idUnwrapped = unwrap(myFactory.getValue(id)).getID()) == idPlain || idUnwrapped == idNegated) { varClass.removeValue(id); } } if (varClass.isEmpty()) { myEqClasses.set(varClassIndex, null); for (TLongIterator iterator = myDistinctClasses.iterator(); iterator.hasNext(); ) { long pair = iterator.next(); if (low(pair) == varClassIndex || high(pair) == varClassIndex) { iterator.remove(); } } } else if (varClass.containsConstantsOnly()) { for (TLongIterator iterator = myDistinctClasses.iterator(); iterator.hasNext(); ) { long pair = iterator.next(); if (low(pair) == varClassIndex && myEqClasses.get(high(pair)).containsConstantsOnly() || high(pair) == varClassIndex && myEqClasses.get(low(pair)).containsConstantsOnly()) { iterator.remove(); } } } } removeAllFromMap(idPlain); removeAllFromMap(idNegated); myVariableStates.remove(varPlain); if (varNegated != null) { myVariableStates.remove(varNegated); } if (markUnknown) { myUnknownVariables.add(varPlain); } myCachedNonTrivialEqClasses = null; myCachedDistinctClassPairs = null; myCachedHash = null; }