package com.linkedin.databus.core.util; /* * * Copyright 2013 LinkedIn Corp. All rights reserved * * 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. * */ /** * A class representing a range of offsets from startOffset to endOffset * All elements from startOffset until endOffset-1 are included in the range. * Two ranges are comparable based on their startOffsets only. * * @author sdas * */ public class Range implements Comparable<Range> { public Range(long startOffset, long endOffset) { start = startOffset; end = endOffset; } public long start; public long end; public Range() { } public boolean contains(long someOffset) { return contains(start, end, someOffset); } /* * Method to check if the writer is going to overwrite the readerPosition * * Writer is expected to be ahead of the reader. * Assumes the input contains the GenId (Look at the edge-case below) * */ public static boolean containsReaderPosition(long writerStart, long writerEnd, long readerPosition, BufferPositionParser parser) { if (readerPosition < 0 ) return false; //empty //just make the reader look the same generation as the writer if (parser.bufferGenId(readerPosition) < parser.bufferGenId(writerStart)) { long fakeReaderPos = parser.setGenId(readerPosition, parser.bufferGenId(writerStart)); return writerStart <= fakeReaderPos && fakeReaderPos < writerEnd; } else { return writerStart <= readerPosition && readerPosition < writerEnd; } } public static boolean containsIgnoreGenId(long start, long end, long offset, BufferPositionParser parser) { return contains(parser.address(start), parser.address(end), parser.address(offset)); } public static boolean contains(long start, long end, long someOffset) { // Range is [start, end) , so the end position is not going to be written to. if (someOffset < 0) { return false; } if (start < end) // |------ start xxxxxxxxxxx end -------| { if ((start< someOffset) && (end <= someOffset)) { return false; } if ((start > someOffset) && (end > someOffset)) { return false; } return true; } if (start > end) // |-------end---------start----------| { if ((start > someOffset) && (end <= someOffset)) { return false; } return true; } return false; } public boolean intersects(Range intersectedRange) { if (contains(intersectedRange.start) || intersectedRange.contains(start)) { return true; } return false; } @Override public int compareTo(Range comparedRange) { if (start != comparedRange.start) { // Since GenIds/Index are more likely in the MSBs of long, type reduction to int will not work // when comparing entries differing in indexes/genIds //return (int) (start - comparedRange.start); return start > comparedRange.start ? 1 : -1; } else { // Since GenIds/Index are more likely in the MSBs of long, type reduction to int will not work // when comparing entries differing in indexes/genIds //return (int) (end - comparedRange.end); return end > comparedRange.end ? 1 : ((end == comparedRange.end) ? 0 : -1); } } public String toString(BufferPositionParser parser) { StringBuilder sb = new StringBuilder(); sb.append("{start:"); sb.append(parser.toString(start)); sb.append(" - end:"); sb.append(parser.toString(end)); sb.append("}"); return sb.toString(); } @Override public String toString() { return "Range [start=" + start + ", end=" + end + "]"; } public long getStart() { return start; } public void setStart(long start) { this.start = start; } public long getEnd() { return end; } public void setEnd(long end) { this.end = end; } @Override public boolean equals(Object obj) { if ( ! (obj instanceof Range)) return false; Range r = (Range)obj; if ((r.getStart() == start) && (r.getEnd() == end)) return true; return false; } @Override public int hashCode() { return (int)start; } }