diff --git a/testcode/src/CompressionSizeTest/SizeTestMain.java b/testcode/src/CompressionSizeTest/SizeTestMain.java index 0336c9cc..289d4bfa 100644 --- a/testcode/src/CompressionSizeTest/SizeTestMain.java +++ b/testcode/src/CompressionSizeTest/SizeTestMain.java @@ -21,10 +21,10 @@ public class SizeTestMain { /** * DB Connection Configuration * */ - public static String url = "jdbc:postgresql://127.0.0.1:5432/dbtest"; + public static String url = "jdbc:postgresql://127.0.0.1:5432/SizeTest"; public static String dbDriver = "org.postgresql.Driver"; - public static String userName = "totemtang"; - public static String password = "1234"; + public static String userName = "dataspreaduser"; + public static String password = "password"; public static void main (String[] args) { @@ -95,8 +95,9 @@ public static void main (String[] args) { int patternIdx = precMeta.getEdgeMeta().patternType.ordinal(); compEdges[patternIdx] = compEdges[patternIdx] + 1; - int compressCount = - precMeta.getPatternType() == PatternType.TYPEFIVE ? (dep.getCellCount() + 1)/2 : dep.getCellCount(); + int compressCount = (dep.getCellCount() + precMeta.getEdgeMeta().gapLength) / + (precMeta.getEdgeMeta().gapLength + 1); + uncompEdges[patternIdx] = uncompEdges[patternIdx] + compressCount; }); }); diff --git a/zssmodel/src/org/zkoss/zss/model/impl/sys/DependencyTableComp.java b/zssmodel/src/org/zkoss/zss/model/impl/sys/DependencyTableComp.java index a53bc358..cd4e7d8f 100644 --- a/zssmodel/src/org/zkoss/zss/model/impl/sys/DependencyTableComp.java +++ b/zssmodel/src/org/zkoss/zss/model/impl/sys/DependencyTableComp.java @@ -47,6 +47,8 @@ public class DependencyTableComp extends DependencyTableAdv { private CompressInfoComparator compressInfoComparator = new CompressInfoComparator(); + private final int MAX_GAP = 4; + public DependencyTableComp() {} public Map> getAllEdges() { @@ -162,7 +164,8 @@ private void flushUpdateCache(LinkedList updateCache, try { deleteDBEntry(dbContext, edgeUpdate.oldPrec, edgeUpdate.oldDep, edgeUpdate.oldEdgeMeta); insertDBEntry(dbContext, edgeUpdate.newPrec, edgeUpdate.newDep, edgeUpdate.newEdgeMeta.patternType, - edgeUpdate.newEdgeMeta.startOffset, edgeUpdate.newEdgeMeta.endOffset); + edgeUpdate.newEdgeMeta.startOffset, edgeUpdate.newEdgeMeta.endOffset, + edgeUpdate.newEdgeMeta.gapLength); } catch (SQLException e) { e.printStackTrace(); } @@ -185,7 +188,7 @@ private void fastModify(Ref prec, Ref dep, boolean isInsert, Ref newDep = selectedInfo.dep.getBoundingBox(selectedInfo.candDep); Pair offsetPair = computeOffset(newPrec, newDep, selectedInfo.compType); updateMatch.updateEdge(newPrec, newDep, - new EdgeMeta(selectedInfo.compType, offsetPair.getX(), offsetPair.getY())); + new EdgeMeta(selectedInfo.compType, updatePair.getX().edgeMeta.gapLength, offsetPair.getX(), offsetPair.getY())); updateCache.addFirst(updateMatch); } } else { @@ -199,11 +202,12 @@ private void fastModify(Ref prec, Ref dep, boolean isInsert, Pair offsetPair = computeOffset(newPrec, newDep, selectedInfo.compType); EdgeUpdate evicted = addToUpdateCache(updateCache, newPrec, newDep, - new EdgeMeta(selectedInfo.compType, offsetPair.getX(), offsetPair.getY())); + new EdgeMeta(selectedInfo.compType, selectedInfo.edgeMeta.gapLength, offsetPair.getX(), offsetPair.getY())); if (evicted != null) { deleteDBEntry(dbContext, evicted.oldPrec, evicted.oldDep, evicted.oldEdgeMeta); insertDBEntry(dbContext, evicted.newPrec, evicted.newDep, evicted.newEdgeMeta.patternType, - evicted.newEdgeMeta.startOffset, evicted.newEdgeMeta.endOffset); + evicted.newEdgeMeta.startOffset, evicted.newEdgeMeta.endOffset, + evicted.newEdgeMeta.gapLength); } } else { EdgeMeta noTypeEdgeMeta = new EdgeMeta(PatternType.NOTYPE, @@ -212,7 +216,8 @@ private void fastModify(Ref prec, Ref dep, boolean isInsert, if (evicted != null) { deleteDBEntry(dbContext, evicted.oldPrec, evicted.oldDep, evicted.oldEdgeMeta); insertDBEntry(dbContext, evicted.newPrec, evicted.newDep, evicted.newEdgeMeta.patternType, - evicted.newEdgeMeta.startOffset, evicted.newEdgeMeta.endOffset); + evicted.newEdgeMeta.startOffset, evicted.newEdgeMeta.endOffset, + evicted.newEdgeMeta.gapLength); } } } catch (SQLException e) { @@ -269,7 +274,7 @@ public void refreshCache(String bookName, String sheetName) { private void loadEverything(String bookName, String sheetName) { _rectToRefCache = RTree.create(); String selectQuery = - " SELECT range::box, dep_range::box, pattern_type, offsetRange::box" + + " SELECT range::box, dep_range::box, pattern_type, offsetRange::box, gap_length" + " FROM " + dependencyTableName + " WHERE bookname = ?" + " AND sheetname = ?"; @@ -292,8 +297,9 @@ private void loadEverything(String bookName, String sheetName) { (int) offsetRange.point[0].y); Offset endOffset = new Offset((int) offsetRange.point[1].x, (int) offsetRange.point[1].y); + int gapLength = rs.getInt(5); EdgeMeta edgeMeta = - new EdgeMeta(patternType, startOffset, endOffset); + new EdgeMeta(patternType, gapLength, startOffset, endOffset); insertMemEntry(prec, dep, edgeMeta); } } catch (SQLException e) { @@ -415,7 +421,7 @@ private void performOneInsert(Ref prec, Ref dep) { DBContext dbContext = new DBContext(connection); if (compressInfoList.isEmpty()) { insertDBEntry(dbContext, prec, dep, PatternType.NOTYPE, - Offset.noOffset, Offset.noOffset); + Offset.noOffset, Offset.noOffset, 0); } else { CompressInfo selectedInfo = Collections.min(compressInfoList, compressInfoComparator); @@ -436,7 +442,7 @@ private void updateOneCompressEntry(DBContext dbContext, Ref newDep = selectedInfo.dep.getBoundingBox(selectedInfo.candDep); Pair offsetPair = computeOffset(newPrec, newDep, selectedInfo.compType); insertDBEntry(dbContext, newPrec, newDep, selectedInfo.compType, - offsetPair.x, offsetPair.y); + offsetPair.x, offsetPair.y, 0); } private Pair findCompressInfoInUpdateCache(Ref prec, Ref dep, @@ -455,8 +461,8 @@ private Pair findCompressInfoInUpdateCache(Ref prec, R if (updatePair == null) { for (EdgeUpdate oneUpdate: updateCache) { - CompressInfo compRes = findCompressionPatternGapOne(prec, dep, - oneUpdate.newPrec, oneUpdate.newDep, oneUpdate.newEdgeMeta); + CompressInfo compRes = findCompressionPatternGapOneToN(prec, dep, + oneUpdate.newPrec, oneUpdate.newDep, oneUpdate.newEdgeMeta, MAX_GAP); PatternType compType = compRes.compType; if (compType != PatternType.NOTYPE) { updatePair = new Pair<>(compRes, oneUpdate); @@ -532,13 +538,15 @@ private void deleteDBEntry(DBContext dbContext, " AND sheetname = ?" + " AND range ~= ?" + " AND dep_range ~= ?" + - " AND offsetRange ~= ?"; + " AND offsetRange ~= ?" + + " AND gap_length = ?"; PreparedStatement retStmt = dbContext.getConnection().prepareStatement(query); retStmt.setString(1, prec.getBookName()); retStmt.setString(2, prec.getSheetName()); retStmt.setObject(3, RefUtils.refToPGBox(prec), Types.OTHER); retStmt.setObject(4, RefUtils.refToPGBox(dep), Types.OTHER); retStmt.setObject(5, RefUtils.offsetToPGBox(edgeMeta.startOffset, edgeMeta.endOffset), Types.OTHER); + retStmt.setInt(6, edgeMeta.gapLength); retStmt.execute(); } @@ -551,12 +559,13 @@ private void insertDBEntry(DBContext dbContext, Ref newDep, PatternType patternType, Offset startOffset, - Offset endOffset) throws SQLException { - insertMemEntry(newPrec, newDep, new EdgeMeta(patternType, startOffset, endOffset)); + Offset endOffset, + int gapLength) throws SQLException { + insertMemEntry(newPrec, newDep, new EdgeMeta(patternType, gapLength, startOffset, endOffset)); if (!refreshCacheMode) { String query = "INSERT INTO " + dependencyTableName + - " VALUES (?,?,?,?,?,?,?,?,?)"; + " VALUES (?,?,?,?,?,?,?,?,?,?)"; PreparedStatement retStmt = dbContext.getConnection().prepareStatement(query); retStmt.setString(1, newPrec.getBookName()); retStmt.setString(2, newPrec.getSheetName()); @@ -567,6 +576,7 @@ private void insertDBEntry(DBContext dbContext, retStmt.setBoolean(7, true); retStmt.setInt(8, patternType.ordinal()); retStmt.setObject(9, RefUtils.offsetToPGBox(startOffset, endOffset)); + retStmt.setInt(10, gapLength); retStmt.execute(); } @@ -653,7 +663,7 @@ private void performOneDelete(Ref delDep) { } else { try { insertDBEntry(dbContext, newPrec, newDep, newEdgeMeta.patternType, - newEdgeMeta.startOffset, newEdgeMeta.endOffset); + newEdgeMeta.startOffset, newEdgeMeta.endOffset, newEdgeMeta.gapLength); } catch (SQLException e) { e.printStackTrace(); } @@ -772,59 +782,39 @@ private CompressInfo findCompressionPattern(Ref prec, Ref dep, prec, dep, candPrec, candDep, metaData); } - private CompressInfo findCompressionPatternGapOne(Ref prec, Ref dep, - Ref candPrec, Ref candDep, EdgeMeta metaData) { - if (dep.getColumn() == candDep.getColumn() && candDep.getLastRow() - dep.getRow() == -2) { - if (metaData.patternType == PatternType.NOTYPE) { - Offset offsetStartA = RefUtils.refToOffset(prec, dep, true); - Offset offsetStartB = RefUtils.refToOffset(candPrec, candDep, true); - - Offset offsetEndA = RefUtils.refToOffset(prec, dep, false); - Offset offsetEndB = RefUtils.refToOffset(candPrec, candDep, false); - - if (offsetStartA.equals(offsetStartB) && - offsetEndA.equals(offsetEndB)) { - return new CompressInfo(false, Direction.TODOWN, PatternType.TYPEFIVE, - prec, dep, candPrec, candDep, metaData); - } - } else if (metaData.patternType == PatternType.TYPEFIVE) { - Offset offsetStartA = RefUtils.refToOffset(prec, dep, true); - Offset offsetEndA = RefUtils.refToOffset(prec, dep, false); - - if (offsetStartA.equals(metaData.startOffset) && - offsetEndA.equals(metaData.endOffset)) { - return new CompressInfo(false, Direction.TODOWN, PatternType.TYPEFIVE, - prec, dep, candPrec, candDep, metaData); - } - } - } else if (dep.getRow() == candDep.getRow() && candDep.getLastColumn() - dep.getColumn() == -2) { - if (metaData.patternType == PatternType.NOTYPE) { - Offset offsetStartA = RefUtils.refToOffset(prec, dep, true); - Offset offsetStartB = RefUtils.refToOffset(candPrec, candDep, true); - - Offset offsetEndA = RefUtils.refToOffset(prec, dep, false); - Offset offsetEndB = RefUtils.refToOffset(candPrec, candDep, false); - - if (offsetStartA.equals(offsetStartB) && - offsetEndA.equals(offsetEndB)) { - return new CompressInfo(false, Direction.TORIGHT, PatternType.TYPEFIVE, - prec, dep, candPrec, candDep, metaData); - } - } else if (metaData.patternType == PatternType.TYPEFIVE) { - Offset offsetStartA = RefUtils.refToOffset(prec, dep, true); - Offset offsetEndA = RefUtils.refToOffset(prec, dep, false); - - if (offsetStartA.equals(metaData.startOffset) && - offsetEndA.equals(metaData.endOffset)) { - return new CompressInfo(false, Direction.TORIGHT, PatternType.TYPEFIVE, - prec, dep, candPrec, candDep, metaData); - } + private CompressInfo findCompressionPatternGapOneToN(Ref prec, Ref dep, + Ref candPrec, Ref candDep, EdgeMeta metaData, int N) { + Direction direction = Direction.NODIRECTION; + PatternType pattern = PatternType.NOTYPE; + // if (dep.getColumn() == candDep.getColumn() && dep.getRow() - candDep.getLastRow() == gapLength + 1) { + if (dep.getColumn() == candDep.getColumn() && dep.getRow() != candDep.getRow()) { + direction = Direction.TODOWN; + //} else if (dep.getRow() == candDep.getRow() && dep.getColumn() - candDep.getLastColumn() == gapLength + 1) { + } else if (dep.getColumn() != candDep.getColumn() && dep.getRow() == candDep.getRow()) { + direction = Direction.TORIGHT; + } + if (direction == Direction.NODIRECTION) { + return new CompressInfo(false, Direction.NODIRECTION, PatternType.NOTYPE, + prec, dep, candPrec, candDep, metaData); + } + for (int gapLength = 1; gapLength <= N; gapLength++) { + if (isCompressibleTypeFive(candPrec, candDep, prec, dep, direction, gapLength, metaData)) { + metaData.setGapLength(gapLength); + pattern = PatternType.TYPEFIVE; + break; + } else if (isCompressibleTypeSix(candPrec, candDep, prec, dep, direction, gapLength)) { + metaData.setGapLength(gapLength); + pattern = PatternType.TYPESIX; + break; } + } - return new CompressInfo(false, Direction.NODIRECTION, PatternType.NOTYPE, + + return new CompressInfo(false, direction, pattern, prec, dep, candPrec, candDep, metaData); } + private PatternType findCompPatternHelper(Direction direction, Ref prec, Ref dep, Ref candPrec, Ref candDep, @@ -855,7 +845,7 @@ private Iterable findOverlapAndAdjacency(Ref ref) { findOverlappingRefs(ref).forEachRemaining(res::addLast); Arrays.stream(Direction.values()).filter(direction -> direction != Direction.NODIRECTION) .forEach(direction -> - findOverlappingRefs(shiftRef(ref, direction)) + findOverlappingRefs(shiftRef(ref, direction, 1)) .forEachRemaining(adjRef -> { if (isValidAdjacency(adjRef, ref)) res.addLast(adjRef); // valid adjacency }) @@ -1099,7 +1089,8 @@ private class CompressInfo { Direction direction, PatternType compType, Ref prec, Ref dep, - Ref candPrec, Ref candDep, EdgeMeta edgeMeta) { + Ref candPrec, Ref candDep, + EdgeMeta edgeMeta) { this.isDuplicate = isDuplicate; this.direction = direction; this.compType = compType; diff --git a/zssmodel/src/org/zkoss/zss/model/impl/sys/utils/EdgeMeta.java b/zssmodel/src/org/zkoss/zss/model/impl/sys/utils/EdgeMeta.java index 91d2b6e1..5c46a4cf 100644 --- a/zssmodel/src/org/zkoss/zss/model/impl/sys/utils/EdgeMeta.java +++ b/zssmodel/src/org/zkoss/zss/model/impl/sys/utils/EdgeMeta.java @@ -7,10 +7,20 @@ public class EdgeMeta { public final PatternType patternType; public final Offset startOffset; public final Offset endOffset; + public int gapLength; public EdgeMeta(PatternType patternType, Offset startOffset, Offset endOffset) { this.patternType = patternType; + this.gapLength = 0; + this.startOffset = startOffset; + this.endOffset = endOffset; + } + + public EdgeMeta(PatternType patternType, int gapLength, + Offset startOffset, Offset endOffset) { + this.patternType = patternType; + this.gapLength = gapLength; this.startOffset = startOffset; this.endOffset = endOffset; } @@ -21,8 +31,13 @@ public boolean equals(Object o) { if (!(o instanceof EdgeMeta)) return false; EdgeMeta edgeMeta = (EdgeMeta) o; return patternType == edgeMeta.patternType && - Objects.equals(startOffset, edgeMeta.startOffset) && - Objects.equals(endOffset, edgeMeta.endOffset); + Objects.equals(this.startOffset, edgeMeta.startOffset) && + Objects.equals(this.endOffset, edgeMeta.endOffset) && + Objects.equals(this.gapLength, edgeMeta.gapLength); + } + + public void setGapLength(int gapLength) { + this.gapLength = gapLength; } @Override diff --git a/zssmodel/src/org/zkoss/zss/model/impl/sys/utils/PatternTools.java b/zssmodel/src/org/zkoss/zss/model/impl/sys/utils/PatternTools.java index 032aed94..8eacfad3 100644 --- a/zssmodel/src/org/zkoss/zss/model/impl/sys/utils/PatternTools.java +++ b/zssmodel/src/org/zkoss/zss/model/impl/sys/utils/PatternTools.java @@ -2,6 +2,7 @@ import org.zkoss.util.Pair; import org.zkoss.zss.model.impl.RefImpl; +import org.zkoss.zss.model.impl.sys.DependencyTableComp; import org.zkoss.zss.model.sys.dependency.Ref; import java.util.Arrays; @@ -14,7 +15,7 @@ public class PatternTools { public static boolean isCompressibleTypeOne(Ref lastCandPrec, Ref prec, Direction direction) { - Ref shiftedRef = shiftRef(lastCandPrec, direction); + Ref shiftedRef = shiftRef(lastCandPrec, direction, 1); return shiftedRef != null && shiftedRef.equals(prec); } @@ -24,9 +25,9 @@ public static boolean isCompressibleTypeZero(Ref prec, Ref dep, boolean isTypeZero = false; for (Direction direction: Direction.values()) { if (direction != Direction.NODIRECTION && !isTypeZero) { - Ref shiftedRef = shiftRef(prec, direction); + Ref shiftedRef = shiftRef(prec, direction, 1); if (shiftedRef != null && shiftedRef.equals(dep)) { // check adjacency - Ref lastCandDep = shiftRef(lastCandPrec, direction); + Ref lastCandDep = shiftRef(lastCandPrec, direction, 1); isTypeZero = (lastCandDep != null && lastCandDep.equals(prec)) || lastCandPrec.equals(dep); } @@ -52,6 +53,42 @@ public static boolean isCompressibleTypeThree(Ref lastCandPrec, Ref prec, return isExtendedStart(lastCandPrec, prec, direction); } + public static boolean isCompressibleTypeFour(Ref lastCandPrec, Ref prec) { + return lastCandPrec.equals(prec); + } + + public static boolean isCompressibleTypeFive(Ref candPrec, Ref candDep, + Ref prec, Ref dep, + Direction direction, int gapLength, EdgeMeta metaData) { + if (dep.getColumn() == candDep.getColumn() && dep.getRow() - candDep.getLastRow() == gapLength + 1 || + dep.getRow() == candDep.getRow() && dep.getColumn() - candDep.getLastColumn() == gapLength + 1) { + if (metaData.patternType == PatternType.NOTYPE) { + Offset offsetStartA = RefUtils.refToOffset(prec, dep, true); + Offset offsetStartB = RefUtils.refToOffset(candPrec, candDep, true); + + Offset offsetEndA = RefUtils.refToOffset(prec, dep, false); + Offset offsetEndB = RefUtils.refToOffset(candPrec, candDep, false); + + return offsetStartA.equals(offsetStartB) && + offsetEndA.equals(offsetEndB); + } else if (metaData.patternType == PatternType.TYPEFIVE) { + Offset offsetStartA = RefUtils.refToOffset(prec, dep, true); + Offset offsetEndA = RefUtils.refToOffset(prec, dep, false); + + return offsetStartA.equals(metaData.startOffset) && + offsetEndA.equals(metaData.endOffset); + } + } + return false; + } + + public static boolean isCompressibleTypeSix(Ref candPrec, Ref candDep, + Ref prec, Ref dep, + Direction direction, int gapLength) { + Ref shiftedRef = shiftRef(candDep, direction, gapLength + 1); + return candPrec.equals(prec) && shiftedRef != null && shiftedRef.equals(dep); + } + public static boolean isExtendedEnd(Ref lastCandPrec, Ref prec, Direction direction) { if (direction == Direction.TODOWN) { @@ -112,40 +149,36 @@ public static boolean isExtendedStart(Ref lastCandPrec, Ref prec, } else return false; } - public static boolean isCompressibleTypeFour(Ref lastCandPrec, Ref prec) { - return lastCandPrec.equals(prec); - } - - public static Ref shiftRef(Ref ref, Direction direction) { + public static Ref shiftRef(Ref ref, Direction direction, int step) { Ref res = null; switch (direction) { case TOLEFT: if (ref.getColumn() != FIRST_COL) { res = new RefImpl(ref.getBookName(), ref.getSheetName(), - ref.getRow(), ref.getColumn() - SHIFT_STEP, - ref.getLastRow(), ref.getLastColumn() - SHIFT_STEP); + ref.getRow(), ref.getColumn() - step, + ref.getLastRow(), ref.getLastColumn() - step); } break; case TORIGHT: res = new RefImpl(ref.getBookName(), ref.getSheetName(), - ref.getRow(), ref.getColumn() + SHIFT_STEP, - ref.getLastRow(), ref.getLastColumn() + SHIFT_STEP); + ref.getRow(), ref.getColumn() + step, + ref.getLastRow(), ref.getLastColumn() + step); break; case TOUP: if (ref.getRow() != FIRST_ROW) { res = new RefImpl(ref.getBookName(), ref.getSheetName(), - ref.getRow() - SHIFT_STEP, ref.getColumn(), - ref.getLastRow() - SHIFT_STEP, ref.getLastColumn()); + ref.getRow() - step, ref.getColumn(), + ref.getLastRow() - step, ref.getLastColumn()); } break; default: // TODOWN res = new RefImpl(ref.getBookName(), ref.getSheetName(), - ref.getRow() + SHIFT_STEP, ref.getColumn(), - ref.getLastRow() + SHIFT_STEP, ref.getLastColumn()); + ref.getRow() + step, ref.getColumn(), + ref.getLastRow() + step, ref.getLastColumn()); } return res; } diff --git a/zssmodel/src/org/zkoss/zss/model/impl/sys/utils/PatternType.java b/zssmodel/src/org/zkoss/zss/model/impl/sys/utils/PatternType.java index d6f22c5b..864708be 100644 --- a/zssmodel/src/org/zkoss/zss/model/impl/sys/utils/PatternType.java +++ b/zssmodel/src/org/zkoss/zss/model/impl/sys/utils/PatternType.java @@ -6,6 +6,7 @@ public enum PatternType { TYPETWO, // Relative start, Absolute end TYPETHREE, // Absolute start, Relative end TYPEFOUR, // Absolute start, Absolute end - TYPEFIVE, // Relative + Relative with gap 1 + TYPEFIVE, // Relative + Relative with gap 1-5 + TYPESIX, // Absolute + Absolute with gap 1-5 NOTYPE }