/** * lookup the node containing the specified procId. * @param node cached node to check before doing a lookup * @param procId the procId to lookup * @return the node that may contains the procId or null */ private BitSetNode lookupClosestNode(final BitSetNode node, final long procId) { if (node != null && node.contains(procId)) return node; final Map.Entry<Long, BitSetNode> entry = map.floorEntry(procId); return entry != null ? entry.getValue() : null; }
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); }
/** * For the global tracker, we will use this method to build the holdingCleanupTracker, as the * modified flags will be cleared after rolling so we only need to test the deleted flags. * @see #setDeletedIfModifiedInBoth(ProcedureStoreTracker) */ public void setDeletedIfDeletedByThem(ProcedureStoreTracker tracker) { setDeleteIf(tracker, (node, procId) -> node == null || !node.contains(procId) || node.isDeleted(procId) == DeleteState.YES); }
/** * 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; }
/** * This method is used when restarting where we need to rebuild the ProcedureStoreTracker. The * {@link #delete(long)} method above assume that the {@link BitSetNode} exists, but when restart * this is not true, as we will read the wal files in reverse order so a delete may come first. */ public void setDeleted(long procId, boolean isDeleted) { BitSetNode node = getOrCreateNode(procId); assert node.contains(procId) : "expected procId=" + procId + " in the node=" + node; node.updateState(procId, isDeleted); trackProcIds(procId); }
private BitSetNode update(BitSetNode node, long procId) { node = lookupClosestNode(node, procId); assert node != null : "expected node to update procId=" + procId; assert node.contains(procId) : "expected procId=" + procId + " in the node"; node.insertOrUpdate(procId); trackProcIds(procId); return node; }
private BitSetNode insert(BitSetNode node, long procId) { if (node == null || !node.contains(procId)) { node = getOrCreateNode(procId); } node.insertOrUpdate(procId); trackProcIds(procId); return node; }
private BitSetNode delete(BitSetNode node, long procId) { node = lookupClosestNode(node, procId); if (node == null || !node.contains(procId)) { LOG.warn("The BitSetNode for procId={} does not exist, maybe a double deletion?", procId); return node; } node.delete(procId); if (!keepDeletes && node.isEmpty()) { // TODO: RESET if (map.size() == 1) map.remove(node.getStart()); } trackProcIds(procId); return node; }
if (leftEntry != null) { leftNode = leftEntry.getValue(); if (leftNode.contains(procId)) { return leftNode;
@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)); } } }
/** * lookup the node containing the specified procId. * @param node cached node to check before doing a lookup * @param procId the procId to lookup * @return the node that may contains the procId or null */ private BitSetNode lookupClosestNode(final BitSetNode node, final long procId) { if (node != null && node.contains(procId)) return node; final Map.Entry<Long, BitSetNode> entry = map.floorEntry(procId); return entry != null ? entry.getValue() : null; }
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); }
/** * For the global tracker, we will use this method to build the holdingCleanupTracker, as the * modified flags will be cleared after rolling so we only need to test the deleted flags. * @see #setDeletedIfModifiedInBoth(ProcedureStoreTracker) */ public void setDeletedIfDeletedByThem(ProcedureStoreTracker tracker) { setDeleteIf(tracker, (node, procId) -> node == null || !node.contains(procId) || node.isDeleted(procId) == DeleteState.YES); }
/** * 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; }
private BitSetNode insert(BitSetNode node, long procId) { if (node == null || !node.contains(procId)) { node = getOrCreateNode(procId); } node.insertOrUpdate(procId); trackProcIds(procId); return node; }
private BitSetNode update(BitSetNode node, long procId) { node = lookupClosestNode(node, procId); assert node != null : "expected node to update procId=" + procId; assert node.contains(procId) : "expected procId=" + procId + " in the node"; node.insertOrUpdate(procId); trackProcIds(procId); return node; }
/** * This method is used when restarting where we need to rebuild the ProcedureStoreTracker. The * {@link #delete(long)} method above assume that the {@link BitSetNode} exists, but when restart * this is not true, as we will read the wal files in reverse order so a delete may come first. */ public void setDeleted(long procId, boolean isDeleted) { BitSetNode node = getOrCreateNode(procId); assert node.contains(procId) : "expected procId=" + procId + " in the node=" + node; node.updateState(procId, isDeleted); trackProcIds(procId); }
private BitSetNode delete(BitSetNode node, long procId) { node = lookupClosestNode(node, procId); if (node == null || !node.contains(procId)) { LOG.warn("The BitSetNode for procId={} does not exist, maybe a double deletion?", procId); return node; } node.delete(procId); if (!keepDeletes && node.isEmpty()) { // TODO: RESET if (map.size() == 1) map.remove(node.getStart()); } trackProcIds(procId); return node; }
if (leftEntry != null) { leftNode = leftEntry.getValue(); if (leftNode.contains(procId)) { return leftNode;
@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)); } } }