ARTEMIS-1622 Reduce memory footprint of QueueImpl

LinkedListImpl is turned into an optionally intrusive linked list by allowing message references to extend Node.
This commit is contained in:
Francesco Nigro 2018-01-18 15:45:20 +01:00 committed by Michael Pearce
parent 71a49c4614
commit 3f646474c2
3 changed files with 34 additions and 12 deletions

View File

@ -18,6 +18,7 @@ package org.apache.activemq.artemis.utils.collections;
import java.lang.reflect.Array;
import java.util.NoSuchElementException;
import java.util.Objects;
/**
* A linked list implementation which allows multiple iterators to exist at the same time on the queue, and which see any
@ -48,7 +49,7 @@ public class LinkedListImpl<E> implements LinkedList<E> {
@Override
public void addHead(E e) {
Node<E> node = new Node<>(e);
Node<E> node = Node.with(e);
node.next = head.next;
@ -71,7 +72,7 @@ public class LinkedListImpl<E> implements LinkedList<E> {
if (size == 0) {
addHead(e);
} else {
Node<E> node = new Node<>(e);
Node<E> node = Node.with(e);
node.prev = tail;
@ -217,23 +218,43 @@ public class LinkedListImpl<E> implements LinkedList<E> {
throw new IllegalStateException("Cannot find iter to remove");
}
private static final class Node<E> {
public static class Node<T> {
Node<E> next;
private Node<T> next;
Node<E> prev;
private Node<T> prev;
final E val;
private final T val;
int iterCount;
private int iterCount;
Node(E e) {
@SuppressWarnings("unchecked")
protected Node() {
val = (T)this;
}
//only the head is allowed to hold a null
private Node(T e) {
val = e;
}
@Override
public String toString() {
return "Node, value = " + val;
return val == this ? "Intrusive Node" : "Node, value = " + val;
}
private static <T> Node<T> with(final T o) {
Objects.requireNonNull(o, "Only HEAD nodes are allowed to hold null values");
if (o instanceof Node) {
final Node node = (Node) o;
//only a node that not belong already to a list is allowed to be reused
if (node.prev == null && node.next == null) {
//reset the iterCount
node.iterCount = 0;
return node;
}
}
return new Node(o);
}
}

View File

@ -20,16 +20,16 @@ import java.lang.ref.WeakReference;
import java.util.concurrent.atomic.AtomicInteger;
import org.apache.activemq.artemis.api.core.Message;
import org.apache.activemq.artemis.core.paging.PagedMessage;
import org.apache.activemq.artemis.core.server.ActiveMQServerLogger;
import org.apache.activemq.artemis.core.server.MessageReference;
import org.apache.activemq.artemis.core.server.Queue;
import org.apache.activemq.artemis.core.server.impl.AckReason;
import org.apache.activemq.artemis.core.transaction.Transaction;
import org.apache.activemq.artemis.utils.collections.LinkedListImpl;
import org.jboss.logging.Logger;
public class PagedReferenceImpl implements PagedReference {
public class PagedReferenceImpl extends LinkedListImpl.Node<PagedReferenceImpl> implements PagedReference {
private static final Logger logger = Logger.getLogger(PagedReferenceImpl.class);

View File

@ -22,11 +22,12 @@ import org.apache.activemq.artemis.api.core.Message;
import org.apache.activemq.artemis.core.server.MessageReference;
import org.apache.activemq.artemis.core.server.Queue;
import org.apache.activemq.artemis.core.transaction.Transaction;
import org.apache.activemq.artemis.utils.collections.LinkedListImpl;
/**
* Implementation of a MessageReference
*/
public class MessageReferenceImpl implements MessageReference {
public class MessageReferenceImpl extends LinkedListImpl.Node<MessageReferenceImpl> implements MessageReference {
private final AtomicInteger deliveryCount = new AtomicInteger();