All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.eclipse.ditto.connectivity.service.messaging.monitoring.logs.DefaultEvictingQueue Maven / Gradle / Ivy

/*
 * Copyright (c) 2019 Contributors to the Eclipse Foundation
 *
 * See the NOTICE file(s) distributed with this work for additional
 * information regarding copyright ownership.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0
 *
 * SPDX-License-Identifier: EPL-2.0
 */

package org.eclipse.ditto.connectivity.service.messaging.monitoring.logs;

import java.util.AbstractQueue;
import java.util.Iterator;
import java.util.Objects;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.atomic.AtomicInteger;

import javax.annotation.Nullable;
import javax.annotation.concurrent.NotThreadSafe;

/**
 * Default implementation of {@link EvictingQueue}.
 * This implementation does not care about synchronization, as we don't care if there might be an element too much or
 * too little in the queue. We care about speed of the queue.
 *
 * @param  type of elements in the queue.
 */
@NotThreadSafe
final class DefaultEvictingQueue extends AbstractQueue implements EvictingQueue {

    private final int capacity;
    private final Queue elements;
    // keep track of queue size manually, because calling queue.size() is expensive
    private final AtomicInteger size;

    private DefaultEvictingQueue(final int capacity) {
        this.capacity = capacity;
        elements = new ConcurrentLinkedQueue<>();
        size = new AtomicInteger();
    }

    /**
     * Create a new synchronized evicting queue.
     *
     * @param capacity capacity of the queue.
     * @param  type of elements in the queue.
     * @return a new instance of {@code DefaultEvictingQueue}.
     */
    static  DefaultEvictingQueue withCapacity(final int capacity) {
        return new DefaultEvictingQueue<>(capacity);
    }

    @Override
    public Iterator iterator() {
        return elements.iterator();
    }

    @Override
    public boolean offer(@Nullable final E e) {
        final var result = elements.offer(e);
        if (size.getAndIncrement() >= capacity) {
            poll();
        }
        return result;
    }

    @Override
    @Nullable
    public E poll() {
        final E pollResult = elements.poll();
        if (pollResult != null) {
            size.decrementAndGet();
        }
        return pollResult;
    }

    @Override
    public E peek() {
        return elements.peek();
    }

    @Override
    public int size() {
        return size.get();
    }

    @Override
    public boolean equals(@Nullable final Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }
        final DefaultEvictingQueue that = (DefaultEvictingQueue) o;
        return capacity == that.capacity &&
                Objects.equals(elements, that.elements) &&
                Objects.equals(size, that.size);
    }

    @Override
    public int hashCode() {
        return Objects.hash(capacity, elements, size);
    }

    @Override
    public String toString() {
        return getClass().getSimpleName() + " [" +
                "capacity=" + capacity +
                ", elements=" + elements +
                ", size=" + size +
                "]";
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy