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:
parent
71a49c4614
commit
3f646474c2
|
@ -18,6 +18,7 @@ package org.apache.activemq.artemis.utils.collections;
|
||||||
|
|
||||||
import java.lang.reflect.Array;
|
import java.lang.reflect.Array;
|
||||||
import java.util.NoSuchElementException;
|
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
|
* 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
|
@Override
|
||||||
public void addHead(E e) {
|
public void addHead(E e) {
|
||||||
Node<E> node = new Node<>(e);
|
Node<E> node = Node.with(e);
|
||||||
|
|
||||||
node.next = head.next;
|
node.next = head.next;
|
||||||
|
|
||||||
|
@ -71,7 +72,7 @@ public class LinkedListImpl<E> implements LinkedList<E> {
|
||||||
if (size == 0) {
|
if (size == 0) {
|
||||||
addHead(e);
|
addHead(e);
|
||||||
} else {
|
} else {
|
||||||
Node<E> node = new Node<>(e);
|
Node<E> node = Node.with(e);
|
||||||
|
|
||||||
node.prev = tail;
|
node.prev = tail;
|
||||||
|
|
||||||
|
@ -217,23 +218,43 @@ public class LinkedListImpl<E> implements LinkedList<E> {
|
||||||
throw new IllegalStateException("Cannot find iter to remove");
|
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;
|
val = e;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,16 +20,16 @@ import java.lang.ref.WeakReference;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
import org.apache.activemq.artemis.api.core.Message;
|
import org.apache.activemq.artemis.api.core.Message;
|
||||||
|
|
||||||
import org.apache.activemq.artemis.core.paging.PagedMessage;
|
import org.apache.activemq.artemis.core.paging.PagedMessage;
|
||||||
import org.apache.activemq.artemis.core.server.ActiveMQServerLogger;
|
import org.apache.activemq.artemis.core.server.ActiveMQServerLogger;
|
||||||
import org.apache.activemq.artemis.core.server.MessageReference;
|
import org.apache.activemq.artemis.core.server.MessageReference;
|
||||||
import org.apache.activemq.artemis.core.server.Queue;
|
import org.apache.activemq.artemis.core.server.Queue;
|
||||||
import org.apache.activemq.artemis.core.server.impl.AckReason;
|
import org.apache.activemq.artemis.core.server.impl.AckReason;
|
||||||
import org.apache.activemq.artemis.core.transaction.Transaction;
|
import org.apache.activemq.artemis.core.transaction.Transaction;
|
||||||
|
import org.apache.activemq.artemis.utils.collections.LinkedListImpl;
|
||||||
import org.jboss.logging.Logger;
|
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);
|
private static final Logger logger = Logger.getLogger(PagedReferenceImpl.class);
|
||||||
|
|
||||||
|
|
|
@ -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.MessageReference;
|
||||||
import org.apache.activemq.artemis.core.server.Queue;
|
import org.apache.activemq.artemis.core.server.Queue;
|
||||||
import org.apache.activemq.artemis.core.transaction.Transaction;
|
import org.apache.activemq.artemis.core.transaction.Transaction;
|
||||||
|
import org.apache.activemq.artemis.utils.collections.LinkedListImpl;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implementation of a MessageReference
|
* Implementation of a MessageReference
|
||||||
*/
|
*/
|
||||||
public class MessageReferenceImpl implements MessageReference {
|
public class MessageReferenceImpl extends LinkedListImpl.Node<MessageReferenceImpl> implements MessageReference {
|
||||||
|
|
||||||
private final AtomicInteger deliveryCount = new AtomicInteger();
|
private final AtomicInteger deliveryCount = new AtomicInteger();
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue