/** * Similar with {@link #setDeletedIfModified(long...)}, but here the {@code procId} are given by * the {@code tracker}. If a procedure is modified by us, and also by the given {@code tracker}, * then we mark it as deleted. * @see #setDeletedIfModified(long...) */ public void setDeletedIfModifiedInBoth(ProcedureStoreTracker tracker) { setDeleteIf(tracker, (node, procId) -> node != null && node.isModified(procId)); }
public boolean isModified(long procId) { final Map.Entry<Long, BitSetNode> entry = map.floorEntry(procId); return entry != null && entry.getValue().contains(procId) && entry.getValue().isModified(procId); }
/** * If {@link #partial} is false, returns state from the bitmap. If no state is found for * {@code procId}, returns YES. * If partial is true, tracker doesn't have complete view of system state, so it returns MAYBE * if there is no update for the procedure or if it doesn't have a state in bitmap. Otherwise, * returns state from the bitmap. */ public DeleteState isDeleted(long procId) { Map.Entry<Long, BitSetNode> entry = map.floorEntry(procId); if (entry != null && entry.getValue().contains(procId)) { BitSetNode node = entry.getValue(); DeleteState state = node.isDeleted(procId); return partial && !node.isModified(procId) ? DeleteState.MAYBE : state; } return partial ? DeleteState.MAYBE : DeleteState.YES; }
/** * Set the given bit for the procId to delete if it was modified before. * <p/> * This method is used to test whether a procedure wal file can be safely deleted, as if all the * procedures in the given procedure wal file has been modified in the new procedure wal files, * then we can delete it. */ public void setDeletedIfModified(long... procId) { BitSetNode node = null; for (int i = 0; i < procId.length; ++i) { node = lookupClosestNode(node, procId[i]); if (node != null && node.isModified(procId[i])) { node.delete(procId[i]); } } }
private void setDeleteIf(ProcedureStoreTracker tracker, BiFunction<BitSetNode, Long, Boolean> func) { BitSetNode trackerNode = null; for (BitSetNode node : map.values()) { long minProcId = node.getStart(); long maxProcId = node.getEnd(); for (long procId = minProcId; procId <= maxProcId; ++procId) { if (!node.isModified(procId)) { continue; } trackerNode = tracker.lookupClosestNode(trackerNode, procId); if (func.apply(trackerNode, procId)) { node.delete(procId); } } } }
@Test public void testMerge() { BitSetNode node = new BitSetNode(1000, false); assertTrue(node.canMerge(new BitSetNode(1200, false))); assertFalse(node.canMerge(new BitSetNode(10000, false))); BitSetNode rightNode = new BitSetNode(1200, false); node.merge(rightNode); assertTrue(node.isModified(1000)); assertTrue(node.isModified(1200)); for (long i = node.getStart(); i <= node.getEnd(); i++) { if (i != 1000 && i != 1200) { assertEquals(DeleteState.YES, node.isDeleted(i)); } else { assertEquals(DeleteState.NO, node.isDeleted(i)); } } } }
@Test public void testGrow() { BitSetNode node = new BitSetNode(1000, false); // contains, do not need to grow but should not fail assertTrue(node.canGrow(1024)); assertTrue(node.canGrow(900)); assertTrue(node.canGrow(1100)); assertFalse(node.canGrow(100)); assertFalse(node.canGrow(10000)); // grow to right node.grow(1100); assertTrue(node.contains(1100)); assertTrue(node.isModified(1000)); // grow to left node.grow(900); assertTrue(node.contains(900)); assertTrue(node.isModified(1000)); for (long i = node.getStart(); i <= node.getEnd(); i++) { if (i != 1000) { assertEquals(DeleteState.YES, node.isDeleted(i)); } else { assertEquals(DeleteState.NO, node.isDeleted(i)); } } }
/** * Similar with {@link #setDeletedIfModified(long...)}, but here the {@code procId} are given by * the {@code tracker}. If a procedure is modified by us, and also by the given {@code tracker}, * then we mark it as deleted. * @see #setDeletedIfModified(long...) */ public void setDeletedIfModifiedInBoth(ProcedureStoreTracker tracker) { setDeleteIf(tracker, (node, procId) -> node != null && node.isModified(procId)); }
public boolean isModified(long procId) { final Map.Entry<Long, BitSetNode> entry = map.floorEntry(procId); return entry != null && entry.getValue().contains(procId) && entry.getValue().isModified(procId); }
/** * If {@link #partial} is false, returns state from the bitmap. If no state is found for * {@code procId}, returns YES. * If partial is true, tracker doesn't have complete view of system state, so it returns MAYBE * if there is no update for the procedure or if it doesn't have a state in bitmap. Otherwise, * returns state from the bitmap. */ public DeleteState isDeleted(long procId) { Map.Entry<Long, BitSetNode> entry = map.floorEntry(procId); if (entry != null && entry.getValue().contains(procId)) { BitSetNode node = entry.getValue(); DeleteState state = node.isDeleted(procId); return partial && !node.isModified(procId) ? DeleteState.MAYBE : state; } return partial ? DeleteState.MAYBE : DeleteState.YES; }
/** * Set the given bit for the procId to delete if it was modified before. * <p/> * This method is used to test whether a procedure wal file can be safely deleted, as if all the * procedures in the given procedure wal file has been modified in the new procedure wal files, * then we can delete it. */ public void setDeletedIfModified(long... procId) { BitSetNode node = null; for (int i = 0; i < procId.length; ++i) { node = lookupClosestNode(node, procId[i]); if (node != null && node.isModified(procId[i])) { node.delete(procId[i]); } } }
private void setDeleteIf(ProcedureStoreTracker tracker, BiFunction<BitSetNode, Long, Boolean> func) { BitSetNode trackerNode = null; for (BitSetNode node : map.values()) { long minProcId = node.getStart(); long maxProcId = node.getEnd(); for (long procId = minProcId; procId <= maxProcId; ++procId) { if (!node.isModified(procId)) { continue; } trackerNode = tracker.lookupClosestNode(trackerNode, procId); if (func.apply(trackerNode, procId)) { node.delete(procId); } } } }
@Test public void testMerge() { BitSetNode node = new BitSetNode(1000, false); assertTrue(node.canMerge(new BitSetNode(1200, false))); assertFalse(node.canMerge(new BitSetNode(10000, false))); BitSetNode rightNode = new BitSetNode(1200, false); node.merge(rightNode); assertTrue(node.isModified(1000)); assertTrue(node.isModified(1200)); for (long i = node.getStart(); i <= node.getEnd(); i++) { if (i != 1000 && i != 1200) { assertEquals(DeleteState.YES, node.isDeleted(i)); } else { assertEquals(DeleteState.NO, node.isDeleted(i)); } } } }
@Test public void testGrow() { BitSetNode node = new BitSetNode(1000, false); // contains, do not need to grow but should not fail assertTrue(node.canGrow(1024)); assertTrue(node.canGrow(900)); assertTrue(node.canGrow(1100)); assertFalse(node.canGrow(100)); assertFalse(node.canGrow(10000)); // grow to right node.grow(1100); assertTrue(node.contains(1100)); assertTrue(node.isModified(1000)); // grow to left node.grow(900); assertTrue(node.contains(900)); assertTrue(node.isModified(1000)); for (long i = node.getStart(); i <= node.getEnd(); i++) { if (i != 1000) { assertEquals(DeleteState.YES, node.isDeleted(i)); } else { assertEquals(DeleteState.NO, node.isDeleted(i)); } } }