MessageQueue実装

5558 ワード

package me2.jojo.MessageQueue;

import me2.core.data.ResultMessage;

/**
 * Description: <br>
 * 
 * @author JOJO
 * @version 0.1
 */
public class ResultMsgQueue
{

    private int       size;

    private int       currCount;

    private int       dSize;

    private int       priority;

    private ResultMessage elements[];

    private int       next[];

    private int[]     previous;

    private int       p[][];

    private int       emptyP_Head;

    private int       emptyP_Tail;

    public ResultMsgQueue(int _size, int _priority)
    {
        size = _size;

        currCount = 0;

        priority = _priority;

        dSize = size / 4;

        elements = new ResultMessage[size];

        next = new int[size];

        previous = new int[size];

        p = new int[priority][2];

        for (int i = 0; i < priority; i++)
        {
            p[i][0] = -1;
            p[i][1] = -1;
        }

        for (int i = 0; i < size; i++)
        {
            next[i] = i + 1;
        }
        emptyP_Head = 0;
        emptyP_Tail = size - 1;
    }

    public ResultMsgQueue()
    {
        this(8, 3);
    }

    private/* synchronized */int allocate ()
    {

        int index = emptyP_Head;

        if (emptyP_Head != emptyP_Tail)
        {
            emptyP_Head = next[emptyP_Head];
        }
        else
        {
            emptyP_Tail = emptyP_Head = -1;
        }
        return index;
    }

    public synchronized int put (ResultMessage element)
    {
        int index = allocate();
        if (index == -1)
        {
            // printAll();
            this.distoryPolicy(dSize);
            return -1;
        }
        int priority = element.getPriority();
        elements[index] = element;
        currCount++;
        if (p[priority][0] == -1)
        {
            p[priority][0] = index;
            //  
            int[] previousP = this.getPreviousPointer(priority);
            if (previousP != null)
            {
                next[previousP[1]] = index;
                previous[index] = previousP[1];
            }
        }
        else
        {
            //  
            next[p[priority][1]] = index;
            previous[index] = p[priority][1];
        }
        //  
        int[] nextP = this.getNextPointer(priority);
        if (nextP != null)
        {
            next[index] = nextP[0];
            previous[nextP[0]] = index;
        }
        p[priority][1] = index;

        return index;
    }

    public synchronized ResultMessage get ()
    {
        ResultMessage element = null;
        for (int i = 0; i < priority; i++)
        {
            if (p[i][0] != -1)
            {
                int n = p[i][0];
                element = elements[n];
                elements[n] = null;
                currCount--;
                if (p[i][0] == p[i][1])
                {
                    p[i][0] = -1;
                    p[i][1] = -1;
                }
                else
                {
                    p[i][0] = next[n];
                }
                /** ************ */
                if (emptyP_Tail == -1)
                {
                    emptyP_Head = n;
                    emptyP_Tail = n;
                }
                else
                {
                    next[emptyP_Tail] = n;
                    emptyP_Tail = n;
                }
                /** ************ */
                return element;
            }
        }
        return element;
    }

    public void printAll ()
    {
        for (int i = 0; i < size; i++)
        {
            System.out.println(elements[i]);
        }
        System.out.println();
    }

    private synchronized void distoryPolicy (int size)
    {
        //System.out.println(" :" + currCount);
        int[] lastP = this.getLastPointer();
        if (lastP != null)
        {
            int index = lastP[1];
            emptyP_Tail = index;
            while (size > 0)
            {
                int n = elements[index].getPriority();
                elements[index] = null;
                if (p[n][0] == p[n][1])
                {
                    p[n][0] = -1;// .reset();
                    p[n][1] = -1;
                }
                else
                {
                    p[n][1] = previous[index];
                }
                emptyP_Head = index;
                index = previous[index];
                currCount--;
                size--;
            }
        }
        //System.out.println(" :" + currCount);
    }

    /**
     *  
     * 
     * @return  
     */
    public int size ()
    {
        return currCount;
    }

    public void printFormFirst ()
    {
        ResultMessage element = null;
        while ((element = get()) != null)
        {
            System.out.println(element);
        }
        System.out.println();
    }

    private int[] getFirstPointer ()
    {
        return this.getNextPointer(-1);
    }

    private int[] getLastPointer ()
    {
        return this.getPreviousPointer(priority);
    }

    private int[] getNextPointer (int _priority)
    {
        int n = this.priority - 1;
        while (_priority < n)
        {
            if (p[++_priority][0] != -1) return p[_priority];
        }
        return null;
    }

    private int[] getPreviousPointer (int priority)
    {
        while (priority > 0)
        {
            if (p[--priority][1] != -1) return p[priority];
        }
        return null;
    }
}