Τρίτη 19 Απριλίου 2022

java Queue array impl , avoid new () and System.arraycopy

 I am not sure !!!!...

Trying to avoid use some class that 

either creates too much Node Objects (calling new)  like java.util.LinkedList
either makes too much  calls to System.arraycopy like java.util.ArrayList

so......building and testing class Qar<E> and its tester....


---------------------------------------------------------

package jimakoskx.java.liba.dd;

/**

 * Purpose is to avoid

 * 

 * a)System.arraycopies

 * b)making new Node calls

 * 

 * @author jimakoskx

 */

public class Qar<E>{

    

    public static void main(String[] args) {

        Qar t=new Qar(4);

        t.add(0);

        int i=1;

        while(i<t.ar.length){

            t.add(i);

            ++i;

        }

        t.remove();

        t.remove();

        t.remove();


        //System.out.println("pops:"+t.remove());

        

        t.add(i++);

        t.add(i++);

        t.add(i++);

        //t.add(i++);

        t.remove();

        t.remove();

        t.remove();

        

        

        

        t.add(i++);

        t.add(i++);

        t.add(i++);

        //t.add(i++);

        t.remove();

        t.remove();

        t.remove();

        

        

    }

    

    

    int size;

    

    int indF[]=new int[2];

    int indL[]=new int[2];

    int indPrimary=0;

    int indSecondary=1;


    

    Object[] ar;

    boolean isLocking=false;

    private static int defInitArrayLength=10;

    

    int increasingDataMode;

    public Qar() {

        this(defInitArrayLength);

    }

    public Qar(int startingArrayLength) {

        this(startingArrayLength,true,-2);

    }

    public Qar(int startingArrayLength,boolean locking,int increasingAdderOrMultiplierOrCaller) {

        isLocking=locking;

        

        if(increasingAdderOrMultiplierOrCaller==-1){

            increasingAdderOrMultiplierOrCaller=-2;

        }

        increasingDataMode=increasingAdderOrMultiplierOrCaller;

        

        size=0;

        fi(0);

        li(0);

        fiSecondary(0);

        liSecondary(0);

        ar=new Object[startingArrayLength];

    }

    

    public void clear(){

        synchronized(locker){

            size=0;

            fi(0);

            li(0);

            fiSecondary(0);

            liSecondary(0);

            int i=0;

            while(i<ar.length){

                ar[i]=null;

                ++i;

            }

        }

    }

    

    public int getNewIncreasedLength(int oldLen){

        return oldLen*2;

    }

    public final int createNewLength(){

        int out=ar.length;

        if(increasingDataMode>0){

            out+=increasingDataMode;

        }

        else if(increasingDataMode<0){

            out*=(-increasingDataMode);

        }

        else{

            out=getNewIncreasedLength(out);

        }

        return out;

    }

    

    

    final Object locker=new Object();

    public void add(E e){

        if(isLocking){

            addLocked(e);

        }

        else{

            addUnlocked(e);

        }

    }

    public void addLocked(E e){

        synchronized(locker){

            addUnlocked(e);

        }

    }

    int debmod=0;

    public void addUnlocked(E e){

        //String deb=(debmod++)+":";

        int fi=fi();

        int li=li();

        if(li<ar.length){

            ar[li]=e;

            liss();

            ++size;

        }

        else{

            

            int lis=liSecondary();

            if(lis<fi){

                //deb+="will store on front "+lis;

                ar[lis]=e;

                liSecondaryss();

                ++size;

            }

            else{

                //deb+="will quick? increase array";

                Object newar[]=new Object[createNewLength()];

                int len=li-fi;

                int srcpos=0;

                int fis=fiSecondary();

                System.arraycopy(ar,fi, newar,0,len);

                System.arraycopy(ar,fis, newar,len,lis-fis);

                //System.arraycopy(ar, size, deb, debmod, li);

                fiSecondary(0);

                liSecondary(0);

                fi(0);

                li(size);

                

                ar=newar;

                ar[li]=e;

                liss();

                ++size;

            }

        }

        //System.out.println(deb);

        //System.out.println(toString());

        //System.out.println(getTheArrayDebugString());

        //System.out.println("");

        

    }

    public synchronized boolean hasItems(){

        return size>0;

    }

    public E remove(){

        if(isLocking){

            return removeLocked();

        }

        else{

            return removeUnlocked();

        }

    }

    public E removeLocked(){

        synchronized(locker){

            return removeUnlocked();

        }

    }

    public E removeUnlocked(){

        E out=null;

        int fi=fi();

        int li=li();

        if(fi<li){

            out=(E)ar[fi];

            ar[fi]=null;

            fiss();

            --size;

            if(size==0){

                fi(0);

                li(0);

                //System.out.println("zerowed fi-li");

            }

            else if(fi+1==li){

                //System.out.println("-------- exchanging --------");

                exchangeKeysAndMakeZeroSecondaries();

            }

        }

        else{

            int fis=fiSecondary();

            int lis=liSecondary();

            if(fis<lis){

                out=(E)ar[fis];

                ar[fis]=null;

                fiSecondaryss();

                --size;

                if(size==0){

                    fi(0);

                    li(0);

                    fiSecondary(0);

                    liSecondary(0);

                    System.out.println("zeroed all");

                }

            }

            else{

                throw new IllegalArgumentException("No item to be removed ");

            }

        }

        

        //System.out.println("pops: "+out);

        //System.out.println(toString());

        //System.out.println(getTheArrayDebugString());

        //System.out.println("");


        return out;

    }

    

    public E element(){

        return null;

    }

    

    

    

    

    

    int fi(){

        return indF[indPrimary];

    }

    void fiss(){

       ++indF[indPrimary];

    }

    void fi(int val){

       indF[indPrimary]=val;

    }

    int li(){

        return indL[indPrimary];

    }

    void liss(){

        ++indL[indPrimary];

    }

    void li(int val){

        indL[indPrimary]=val;

    }

    int fiSecondary(){

        return indF[indSecondary];

    }

    void fiSecondaryss(){

        ++indF[indSecondary];

    }

    void fiSecondary(int val){

        indF[indSecondary]=val;

    }

    int liSecondary(){

        return indL[indSecondary];

    }

    void liSecondaryss(){

        ++indL[indSecondary];

    }

    void liSecondary(int val){

        indL[indSecondary]=val;

    }

    void exchangeKeysAndMakeZeroSecondaries(){

        int temp=indPrimary;

        indPrimary=indSecondary;

        indSecondary=temp;

        indF[indSecondary]=0;

        indL[indSecondary]=0;

    } 

    

    public String getTheArrayDebugString(){

        String out="";

        int i=fiSecondary();

        int l=liSecondary();

        while(i<l){

            out+=ar[i]+",";

            ++i;

        }

        out+=",,";

        i=fi();

        l=li();

        while(i<l){

            out+=ar[i]+",";

            ++i;

        }

        

        return out;

    }

    public String toString(){

        String out="";

        synchronized(locker){

        int s=size;

        out="Q["+ar.length+"/"+s+"](";

        if(s>0){

            int i=fi();

            int l=li();

            out+=""+ar[i];//.toString();

            ++i;

            while(i<l){

                out+=",";

                out+=""+ar[i];//.toString();

                ++i;

            }

            

            i=fiSecondary();

            l=liSecondary();

            while(i<l){

                out+=",";

                out+=""+ar[i];//.toString();

                ++i;

            }

        }

        out+=")";

        }

        return out;

    }

}




/*

 * To change this license header, choose License Headers in Project Properties.

 * To change this template file, choose Tools | Templates

 * and open the template in the editor.

 */

package jimakoskx.java.liba.dd;


import java.util.ArrayList;

import java.util.LinkedList;

import java.util.Random;

import java.util.Vector;


/**

 *

 * @author jimakoskx

 */

public class QarTest {

    public static void main(String[] args) {

        new QarTest();

    }


    

    /**

     * A thread produces work adding numbers to a Queue

     * onother Thread process this queue poping the first

     * 

     * 

     * 

     * 

     */

    

    

    Thread producer=new Thread(){

        public void run(){

            runProducer();

        }

    };

    

    Thread worker=new Thread(){

        public void run(){

            runWorker();

        }

    };

    

    Thread printer=new Thread(){

        public void run(){

            runPrinter();

        }

    };

    

    

    Qar<Integer>tt=new Qar<>();

    

    QarTest(){

        //tt.isLocking=false;

        producer.setDaemon(true);

        worker.setDaemon(true);

        printer.setDaemon(false);

        

        printer.start();

        producer.start();

        worker.start();

    }

    Random r=new Random();

    

    long produced=0;

    long eachsl=10;

    boolean kpro=true;

    void runProducer(){

        while(kpro){

            

            if(produced-processed>10000){

                try{

                    producer.sleep(eachsl);

                }catch(InterruptedException inter){

                    

                }

            }

            else{

                ++produced;

                tt.add(r.nextInt(1000));

            }

        }

        System.out.println(" --- E N D     P R O D U C E R  ---");

    }

    long processed=0;

    boolean kw=true;

    void runWorker(){

        while(kw){

            if(tt.hasItems()){

                ++processed;

                tt.remove();

            }

            else{

                //try{

                    //worker.sleep(eachsl);

                //}catch(InterruptedException inter){}

            }

        }

        

        System.out.println(" --- E N D     W O R K E R  ---");

    }

    

    void runPrinter(){

        while(true){

            long prod=produced;

            long proc=processed;

            long remains=prod-proc;

            System.out.println(prod+" - "+proc+" = "+remains+"    , ["+tt.ar.length+"]");

            try{

                printer.sleep(1000);

            }catch(InterruptedException inter){


            }

        }

    }

    

}


Δεν υπάρχουν σχόλια: