/** * @return all the id Sequences that are missing from this set that are not in between the range * provided. */ public List<Sequence> getMissing(long first, long last) { ArrayList<Sequence> rc = new ArrayList<Sequence>(); if (first > last) { throw new IllegalArgumentException("First cannot be more than last"); } if (isEmpty()) { // We are missing all the messages. rc.add(new Sequence(first, last)); return rc; } Sequence sequence = getHead(); while (sequence != null && first <= last) { if (sequence.contains(first)) { first = sequence.last + 1; } else { if (first < sequence.first) { if (last < sequence.first) { rc.add(new Sequence(first, last)); return rc; } else { rc.add(new Sequence(first, sequence.first - 1)); first = sequence.last + 1; } } } sequence = sequence.getNext(); } if (first <= last) { rc.add(new Sequence(first, last)); } return rc; }
/** * Removes the given value from the Sequence set, splitting a contained sequence if necessary. * * @param value The value that should be removed from the SequenceSet. * @return true if the value was removed from the set, false if there was no sequence in the set * that contained the given value. */ public boolean remove(long value) { Sequence sequence = getHead(); while (sequence != null) { if (sequence.contains(value)) { if (sequence.range() == 1) { sequence.unlink(); return true; } else if (sequence.getFirst() == value) { sequence.setFirst(value + 1); return true; } else if (sequence.getLast() == value) { sequence.setLast(value - 1); return true; } else { sequence.linkBefore(new Sequence(sequence.first, value - 1)); sequence.linkAfter(new Sequence(value + 1, sequence.last)); sequence.unlink(); return true; } } sequence = sequence.getNext(); } return false; }
/** * checks if a list of sequences contain a sequence * * @param sequences - list of sequences * @param seq - sequence to be checked * @return true or false */ public static boolean ListContains(ArrayList<Sequence> sequences, Sequence seq) { boolean contains = false; for (Sequence s : sequences) { if (s.contains(seq)) { contains = true; break; } } return contains; }
/** * Returns true if the value given is contained within one of the sequences held in this set. * * @param value The value to search for in the set. * @return true if the value is contained in the set. */ public boolean contains(long value) { if (isEmpty()) { return false; } Sequence sequence = getHead(); while (sequence != null) { if (sequence.contains(value)) { return true; } sequence = sequence.getNext(); } return false; }
/** * @param value the value to add to the list * @return false if the value was a duplicate. */ public boolean add(long value) { if (isEmpty()) { addFirst(new Sequence(value)); return true; } // check for append Sequence sequence = getTail(); if (sequence.isAdjacentToLast(value)) { sequence.last = value; return true; } sequence = getHead(); while (sequence != null) { if (sequence.isAdjacentToLast(value)) { // grow the sequence... sequence.last = value; // it might connect us to the next sequence.. if (sequence.getNext() != null) { Sequence next = sequence.getNext(); if (next.isAdjacentToFirst(value)) { // Yep the sequence connected.. so join them. sequence.last = next.last; next.unlink(); } } return true; } if (sequence.isAdjacentToFirst(value)) { // grow the sequence... sequence.first = value; // it might connect us to the previous if (sequence.getPrevious() != null) { Sequence prev = sequence.getPrevious(); if (prev.isAdjacentToLast(value)) { // Yep the sequence connected.. so join them. sequence.first = prev.first; prev.unlink(); } } return true; } // Did that value land before this sequence? if (value < sequence.first) { // Then insert a new entry before this sequence item. sequence.linkBefore(new Sequence(value)); return true; } // Did that value land within the sequence? The it's a duplicate. if (sequence.contains(value)) { return false; } sequence = sequence.getNext(); } // Then the value is getting appended to the tail of the sequence. addLast(new Sequence(value)); return true; }