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

com.yahoo.sql4dclient.CircularBuffer Maven / Gradle / Ivy

/**
 * Copyright 2014 Yahoo! Inc. Licensed under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance with the License. 
 * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 
 * Unless required by applicable law or agreed to in writing, software distributed
 * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 
 * CONDITIONS OF ANY KIND, either express or implied. See the License for the 
 * specific language governing permissions and limitations under the License. 
 * See accompanying LICENSE file.
 */
package com.yahoo.sql4dclient;

import java.util.Arrays;


/**
 * A general purpose circular buffer whose size is fixed. Any item added will replace
 * the oldest (if any)item. It has utilities using which we can navigate up and down
 * in the list. Each time {@link #add(java.lang.Object)} or {@link #resetNavigator() }
 * is called the navigator is reset which again points to the most recent added 
 * element. There is no way to delete an element except it getting overriden during
 * overflow add. Utilities of this are numerous, for instance if you need to a history
 * tracker, this is very handy.
 * @author srikalyan
 */
public class CircularBuffer {
    
    private int emptyItemIndex = 0;
    private int size = 10;
    boolean wasFullAtleastOnce = false;// This will be set to true when size reaches 10.
    private Object[] items = null;// Because you cannot instantiate generic array.
    
    private int navigator = -1;
    private boolean hasElements = false;
    
    public CircularBuffer(int size) {
        this.size = size;
        items = new Object[size];
    }
    
    /**
     * To exactly get item at index.
     * @param index
     * @return 
     */
    public T get(int index) {
        if (index < 0 || index >= size) {
            return null;
        }
        if (!wasFullAtleastOnce && index >= emptyItemIndex) {
            return null;
        }
        return (T)(items[index]);
    }

    /**
     * Think of this method conceptually as navigating using down arrow in history 
     * list of commands.
     * @return 
     */
    public T getDown() {
        if (navigator < 0) {// This is true when there are no elements.
            return null;
        }
        if ((wasFullAtleastOnce && navigator == size - 1) || 
                (!wasFullAtleastOnce && navigator == emptyItemIndex - 1)) {
            try {
                return (T)(items[navigator]);
            } finally {
                navigator = 0;
            }
        }
        return (T)(items[navigator++]);
    }
    
    /**
     * Think of this method conceptually as navigating using down up in history 
     * list of commands.
     * @return 
     */
    public T getUp() {
        if (navigator < 0) {
            return null;
        }
        if (navigator == 0) {
            try {
                return (T)(items[navigator]);
            } finally {
                if (wasFullAtleastOnce) {
                    navigator = size - 1;
                } else {
                    navigator = emptyItemIndex - 1;
                }
            }
        }
        return (T)(items[navigator--]);
    }

    /**
     * Navigator should point to most recent added element.
     * @param item 
     */
    public void add(T item) {
        hasElements = true;
        navigator = emptyItemIndex;
        items[emptyItemIndex] = item;
        if (emptyItemIndex == size - 1) {
            wasFullAtleastOnce = true;
        }
        emptyItemIndex = (emptyItemIndex + 1) % size;
    }
    
    /**
     * Call this method if you want to start from the most recently added element.
     */
    public void resetNavigator() {
        if (wasFullAtleastOnce && emptyItemIndex == 0) {
            navigator = size - 1;
            return;
        }
        navigator = emptyItemIndex - 1;
    }
    
    public boolean isEmpty() {
        return !hasElements;
    }

    @Override
    public String toString() {
        StringBuilder buff = new StringBuilder();
        buff.append("Items: ");
        buff.append(Arrays.asList(items));
        
        buff.append("\n");
        
        buff.append("WasFullAtleastOnce: ");
        buff.append(wasFullAtleastOnce);
        
        buff.append("\n");

        buff.append("emptyItemIndex: ");
        buff.append(emptyItemIndex);

        buff.append("\n");

        buff.append("navigator: ");
        buff.append(navigator);
        
        return buff.toString();
    }
    
    
    public static void main(String[] args) {
        CircularBuffer cb = new CircularBuffer<>(4);
        cb.add(1);
        cb.add(2);
        cb.add(3);
        cb.add(4);
        System.out.println(cb);
        System.out.println(cb.getUp());
        System.out.println(cb.getUp());
        System.out.println(cb.getUp());
        System.out.println(cb.getUp());
        System.out.println(cb.getUp());
        System.out.println(cb);
        cb.resetNavigator();
        System.out.println(cb);
        System.out.println(cb.getDown());
        System.out.println(cb);
        System.out.println(cb.getDown());
        System.out.println(cb.getDown());
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy