/*
* Sor.java
* Object-ekből álló, tetszőleges hosszúra növő FIFO megvalósítás
* by pts@fazekas.hu at Sat Apr 7 12:10:32 CEST 2001
* további doksi: a README-ben és e file legkülső class-ának fejkommentjében
*
* Kincskereső Kisgömböc (C) Early May 2001 by eNTitánok (Rév Szilvia,
* Szabó Péter <pts@inf.bme.hu>, Szurdi Miklós, Weizengruber Attila).
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package eNTitanok.util;
/**
* Egy generikus (Object-ekből álló), tetszőleges hosszúra növő sor (queue,
* FIFO) megvalósítás. A sor elejéről lehet olvasni és a végéhez lehet
* hozzáfűzni. Thread safe (nem teszteltük).
*/
public class Sor {
/**
* A minimális kapacitás.
*/
public static final int MIN_HOSSZ=16;
protected Object t[];
/**
* Az elsőként belerakott, kiolvasásra váró elem indexe.
*/
protected int elso;
/**
* Az index, ahová a következő beszúrás történhet.
*/
protected int uj;
/**
* Egy üres sort hoz létre, 16 kezdőkapacitással.
*/
public Sor() { this(16); }
/**
* Egy adott kezdőkapacitású, üres sort hoz létre.
*/
public Sor(int kezdomeret) {
t=new Object[Math.min(kezdomeret,MIN_HOSSZ)];
elso=uj=0;
}
public Sor klonoz() {
Sor masik=new Sor();
for (int i=elso;i<uj;i++) masik.vegehezFuz(t[i]);
return masik;
}
/**
* @return Pontosan akkor <code>true</code>, ha a sor üres, azaz nincs benne
* senki.
*/
public synchronized boolean isUres() { return elso==uj; }
/**
* @return a sorbanálló elemek száma.
*/
public synchronized int length() { return uj-elso; }
/**
* Ha a sor legfeljebb a kapacitás negyedét tölti ki, összenyomja a felére.
*/
protected synchronized void osszenyom() {
if ((uj-elso)<=t.length/4 && t.length>=MIN_HOSSZ*2) {
Object ujt[]=new Object[t.length/2];
System.arraycopy(t, elso, ujt, 0, uj-elso);
t=ujt; uj-=elso; elso=0;
}
}
/**
* Helyet csinál még <code>mennyinek</code> új elemnek.
*/
protected synchronized void helyetCsinal(int mennyinek) {
if (t.length-uj<mennyinek) {
int ujhossz=t.length;
while (ujhossz-(uj-elso)<mennyinek) ujhossz*=2;
Object ujt[]=ujhossz==t.length?t:new Object[ujhossz];
System.arraycopy(t, elso, ujt, 0, uj-elso);
t=ujt; uj-=elso; elso=0;
}
} /// helyetCsinal()
/**
* @return a sor elején álló elem
*/
public synchronized Object elso() { return uj==elso?null:t[elso]; }
/**
* Törli a sor elején álló elemet.
* @return az épp törölt elem
*/
public synchronized Object elsoTorol() {
if (uj==elso) return null;
Object o=t[elso++];
osszenyom();
return o;
}
/**
* @return a sor végén álló elem
*/
public synchronized Object utolso() { return uj==elso?null:t[uj-1]; }
/**
* Törli a sor végén álló elemet. Bár ezt a klasszikus <I>sor</I>
* adatszerkezettől nem követeljük meg, itt megvalósítottuk.
* @return az épp törölt elem
*/
public synchronized Object utolsoTorol() {
if (uj==elso) return null;
Object o=t[--uj];
osszenyom();
return o;
}
/**
* Paraméteret a sor végéhez fűzi új elemként.
*/
public synchronized void vegehezFuz(Object ujelem) {
helyetCsinal(1);
t[uj++]=ujelem;
}
/**
* Paraméteret a sor végéhez fűzi új elemként. Hibát okoz, ha `ujelem==null'.
*/
public synchronized void vegehezFuzNemNull(Object ujelem) {
if (ujelem==null) throw new NullPointerException();
helyetCsinal(1);
t[uj++]=ujelem;
}
} /// class Sor