/** * Removes the last element from the back of the index if its not empty. * @return True if the element was removed or false if the index was empty. */ public boolean removeLast() { // check if queue is empty if (isEmpty()) { return false; } // increment first item, rollver to beginning if needed next = calculateNewIndex(next, -1); //next = (next - 1) % capacity; // always decrement size size--; // check if we should reset checkReset(); return true; }
/** * Gets the index where the next first element will be put. This is the index * where the next "addFirst" operation would put the element. Will return -1 if * the index is full (i.e. no next space available). * @return The index of where the next first element will be put or -1 if the * the index is full. */ public long getNextFirst() { if (isFull()) { return -1; } else if (isEmpty()) { // interesting case, always the current first return first; } else { return calculateNewIndex(first, -1); } }
private void checkReset() { if (this.resetOnZero && this.size == 0) { reset(); } }
/** * Gets the index to the last element if it exists. * @return The index of the last element (tail) or -1 if no elements exist. */ public long getLast() { if (isEmpty()) { return -1; } // next points to current free space, so the one directly before it // would actually be the last item // NOTE: -1 mod 4 = 3 (isn't the modulus operator schweet?) //return ((next - 1) % capacity); return calculateNewIndex(next, -1); }
/** * Adds an element to the back of the index if its not full. * @return True if the element was added or false if the index was full. */ public boolean addLast() { // check if queue is full if (isFull()) { return false; } // increment next available space, rollover to beginning if needed next = calculateNewIndex(next, 1); //next = (next + 1) % capacity; // always increment size size++; return true; }
/** * Gets the index where the next last element will be put. This is the index * where the next "addLast" operation would put the element. Will return -1 if * the index is full (i.e. no next space available). * @return The index of where the next last element will be put or -1 if the * the index is full. */ public long getNextLast() { if (isFull()) { return -1; } else if (isEmpty()) { // interesting case, always the same as the first return first; } else { return next; } }
} else if (size > getMaxSize()) { throw new IllegalArgumentException("Index size element must be < getMaxSize [size=" + size + ", getMaxSize=" + getMaxSize() + "]"); this.next = this.calculateNewIndex(first, size); checkReset();
/** * Gets the index to the first element if it exists. * @return The index of the first element (head) or -1 if no elements exist. */ public long getFirst() { if (isEmpty()) { return -1; } return this.first; }
protected boolean doStore(E item, byte[] encoded) throws QueueIsFullException { // temporarily get the next index (but don't increment it yet) long itemId = this.index.getNextLast(); logger.trace("[{}] itemId={} in queue.put()", getName(), itemId); // is the queue full? if (itemId < 0) { throw new QueueIsFullException("Queue is full [method=add(), queue=" + getName() + ", size=" + index.getSize() + "]"); } // generate the composite key we'll use within the queue (queueId and itemId) byte[] key = keyUtil.encode(getId(), itemId); // put the value into the data store by key -- will throw an exception // if there was an error while storing it, this is the most likely // place that an error would occur try { ds.setRecord(key, encoded); } catch (DataStoreFatalException e) { // this should only happen if there was a serious error with // the underlying data store -- we'll ignore so that the system doesn't crash logger.error("Unable to permanently store key and value for queueId=" + getId() + ", itemId=" + itemId, e); this.errorCount.incrementAndGet(); return false; } queue.add(item); return true; }
protected E doTake() { long itemId = this.index.getFirst(); logger.trace("[{}] itemId={} in queue.take()", getName(), itemId);
protected void doActivate() throws Exception { if (firstItemId == -1) firstItemId = 0; this.index = new CircularIndex(keyUtil.getMaxItems(), firstItemId, queueSize, true); this.size.set(queueSize); this.putCount.set(queueSize); }
protected void afterStore(E item, byte[] encoded) { // if we got here, the item was added, increment the index index.addLast(); }
} else if (size > getMaxSize()) { throw new IllegalArgumentException("Index size element must be < getMaxSize [size=" + size + ", getMaxSize=" + getMaxSize() + "]"); this.next = this.calculateNewIndex(first, size); checkReset();
/** * Adds an element to the front of the index if its not full. * @return True if the element was added or false if the index was full. */ public boolean addFirst() { // check if queue is full if (isFull()) { return false; } // increment next available space, rollover to beginning if needed first = calculateNewIndex(first, -1); //first = (first - 1) % capacity; // always increment size size++; return true; }
/** * Gets the index to the last element if it exists. * @return The index of the last element (tail) or -1 if no elements exist. */ public long getLast() { if (isEmpty()) { return -1; } // next points to current free space, so the one directly before it // would actually be the last item // NOTE: -1 mod 4 = 3 (isn't the modulus operator schweet?) //return ((next - 1) % capacity); return calculateNewIndex(next, -1); }
/** * Gets the index where the next last element will be put. This is the index * where the next "addLast" operation would put the element. Will return -1 if * the index is full (i.e. no next space available). * @return The index of where the next last element will be put or -1 if the * the index is full. */ public long getNextLast() { if (isFull()) { return -1; } else if (isEmpty()) { // interesting case, always the same as the first return first; } else { return next; } }
/** * Gets the index to the first element if it exists. * @return The index of the first element (head) or -1 if no elements exist. */ public long getFirst() { if (isEmpty()) { return -1; } return this.first; }
protected boolean doStore(E item, byte[] encoded) throws QueueIsFullException { // temporarily get the next index (but don't increment it yet) long itemId = this.index.getNextLast(); logger.trace("[{}] itemId={} in queue.put()", getName(), itemId); // is the queue full? if (itemId < 0) { throw new QueueIsFullException("Queue is full [method=add(), queue=" + getName() + ", size=" + index.getSize() + "]"); } // generate the composite key we'll use within the queue (queueId and itemId) byte[] key = keyUtil.encode(getId(), itemId); // put the value into the data store by key -- will throw an exception // if there was an error while storing it, this is the most likely // place that an error would occur try { ds.setRecord(key, encoded); } catch (DataStoreFatalException e) { // this should only happen if there was a serious error with // the underlying data store -- we'll ignore so that the system doesn't crash logger.error("Unable to permanently store key and value for queueId=" + getId() + ", itemId=" + itemId, e); this.errorCount.incrementAndGet(); return false; } return true; }
protected E doTake() { long itemId = this.index.getFirst(); logger.trace("[{}] itemId={} in queue.take()", getName(), itemId);
protected void doActivate() throws Exception { // default the queue to the backQueue queue = backQueue; // do we need to merge the front and back queues together? if (frontQueue.size() > 0) { // add the front part of the list first queue = new LinkedList<E>(frontQueue); // then add the back list queue.addAll(backQueue); } if (firstItemId == -1) firstItemId = 0; this.index = new CircularIndex(keyUtil.getMaxItems(), firstItemId, queue.size(), true); this.size.set(queue.size()); this.putCount.set(queue.size()); }