vi er her !!!

02120

DifferentielGPS
home

Buffere

Der er to buffere i programmet. Den ene er CRWBuffer, som bruges til at opbevare de modtagne bytes i. Disse bytes læses fra CRW bufferen ind i en WordBuffer. Word bufferen bruger GPSWord til at omdanne bytene til GPS ord.
Da WordBuffer oprindeligt havde en anden form, extender klassen CRWBuffer. Dette er der ingen grund til i den nuværende kode, og det kunne passende ændres, så WordBuffer blot har en CRWBuffer variabel i sig.

Da vi havde problemer med WordBuffer, som vi tilskrev muligvis at kunne skyldes, at en tråd kan skrive til bufferne samtidigt med, at en anden tråd læser fra den. Forstået sådan, at skriveprocessen begynder mens læseprocessen endnu er i gang eller omvendt. Dette burde teoretisk kunne lade sig gøre, men vi fjernede alligevel denne mulighed, ved at sætte en blokeringsvariabel til, når der enten skrives eller læses fra bufferen. Hvis en anden tråd prøver at læse fra bufferen mens der skrives til den, vil en while-løkke sørge for, at der ikke bliver læst, før blokeringsvariablen slås fra igen. Vi kunne muligvis fjerne denne blokering, men har ikke udført nogen test af, om det rent faktisk er muligt. Der er en blokering i begge buffere.

CRWBuffer.java

Dette er implementeringen af den CRW buffer, som er beskrevet under Analyse. Den indeholder et integer array data, som der skrives til og læses fra. Metoden write bruges til at skrive til arrayet. Hvis buffere er fuld når der forsøges skrevet kastes en BufferoverrunException. Når man skal læse fra bufferen, kan man vælge følgende metoder:

  • read, som læser den første integer i bufferen.
    Hvis bufferen er tom, kastes en BufferunderrunException
  • readAll, som læser hele bufferen og returnerer den som et array.
    Hvis bufferen er tom returneres et array med længden 0.
  • pop, der virker som read samtidigt med, at den første integer fra bufferen fjernes.
  • popAll, der virker som readAll, samtidigt med, at hele bufferen tømmes.

For at finde ud af hvornår bufferen er tom, skal dens størrelse kendes. Dette gøres med metoden currentSize. Data kan ligge på to måder. Enten er skriveindekset efter læseindekset eller også er det omvendt. For at beregne størrelsen skal det først bestemmes hvilke af disse to indeks, der kommer først. Er det skriveindekset der kommer først beregnes størrelsen med denne formel:
størrelse = skriveindeks - læseindekset

Tabel 1
0 1 2 3 4 5 6 7 8
* * S D D D L * *

Denne formel kommer af, at dataene ligger mellem skrive- og læseindeks, som vist i tabel 1, hvor * er tomt felt, D er datafelt, S er skrivefelt (tomt) og L er læsefelt (med data). Således afhænger størrelsen antallet af pladser mellem dem. I den omvendte situation, skriveindekset kommer først, ligger dataene ikke mellem dem, men på hver sin side af dem. Her bruges denne formel til at udregne størrelsen:
størrelse = total længde + skriveindekset - læseindekset

Tabel 2
0 1 2 3 4 5 6 7 8
D D S * * * L D D

Tabel 3
0 1 2 3 4 5 6 7 8 9 10 11
D D S * * * L D D (0) (1) (2)

Man kan indse, at formlen er rigtig ved at betragte tabel 2 og 3. Vi ønsker at finde størrelsen af arrayet i tabel 2. total længde + skriveindeks + 1 vil give en størrelse, som svarer til at arrayet er fyldt og forlænget med de pladser, der er data på fra startindekset til og med læseindekset (her 0, 1 og 2). Denne størrelse svarer til, at arrayet i tabel 3 er helt fyldt. Men da der ikke mellem læseindekset og skriveindekset og heller ikke på de pladser, arrayet er udvidet med, skal dette trækkes fra:
størrelse = (total længde + skriveindeks + 1) - (skriveindeks + 1) – (læseindeks – skriveindeks) =
total længde + skriveindekset - læseindekset

Da skriveindekset peger på den plads, som skal til at skrive på næste gang og læseindekset på den plads, hvor den første integer skal læses fra, kan man ikke fylde data arrayet helt ud. For i så fald ville man ikke kunne se forskel på, om bufferen er helt fuld eller helt tom. Når skriveindekset og læseindekset er ens, er bufferen tom, og når (skriveindekset +1) mod total størrelse = læseindekset er bufferen fuld.

WordBuffer.java

Denne buffer, som extender CRWBuffer, bruges til at opbevarer de samlede GPS ord indtil de bliver læst og sendt til databasen. Ordene bliver læst direkte fra en CRWBuffer med metoden write, hvor det antages, at der er 6 bytes i CRWBuffer'en. Det undersøges om de 6 bytes former et gyldigt GPS ord og om det i så fald er det første ord af en ny besked. Når første ord i en besked er modtaget og det konstateres, at det er en type 1 besked, skrives det til den interne buffer i WordBufferen. Fra det næste ord, som også skrives til bufferen, læses beskedlængden. Herefter skrives ordene til den interne buffer indtil der er modtaget alle de ord, der skal være i beskeden. Når den fulde besked er modtaget, læses beskeden ind i en Vector, hvorfra den er klar til at blive læst af en Reciver. Beskeder læses med metoden readMessage.
Skematisk set, kan denne buffer kan befinde sig i tre stadier:

  1. De bytes der modtages former ikke et korrekt GPS ord, da pariteten fejler.
    Der startes ofte i dette stadie, da det ikke er sikkert, at den første byte man modtager er den første byte i et ord. Den kan også være den 2., 3. 4. eller 5. byte af et ord. Når først man har modtaget ét korrekt ord, vil man som regel ikke støde på flere paritetsfejl. Der vil kun opstå flere af dem, hvis der er huller i datastrømmen, så der bliver sprunget en eller flere bytes over.
  2. Man modtager korrekte ord, men har ikke modtaget første ord af en besked.
    Dette stadie vil man komme i umiddelbart efter 1. stadie, medmindre det korrekte ord man modtager, er første ord af en besked.
  3. Første ord af en besked er modtaget, og ord læses ind i bufferen. Når man har læst en hel besked ryger man formelt set tilbage til 2. stadie. Men med mindre der udsendes flere beskedtyper eller der opstår fejl, vil man komme tilbage til dette stadie lige så snart, man har læst de næste 5 bytes. Ser man bort fra dette lille hop, forlades det 3. stadie aldrig, hvis data er helt fejlfrie.

Vi genbruger CRWBufferen og konverterer, som nævnt under Valg af datastruktur til bits bittene til et heltal, når vi skriver dem til den interne buffer. Når de skal læses igen, skal, heltalene konverteres tilbage til GPSWords.
De 6 bytes, der modtages med write metoden "rulles" med rollByteToBits metoden i Bits.java. Herefter har man 6 bitstrenge med 6 bits i hver. Fra den første bitstreng bruges kun de sidste to bits, som bruges til paritetstjekket. De sidste 5 bitstrenge med i alt 30 bits i udgør muligvis tilsammen et GPS ord. De samles med GPSWord klassen, som udfører paritetstjek på dem. Hvis paritetstjekket fejler, smides den først modtagne byte ud af CRWBuffer'en. De resterende 5 bytes kan, som nævnt ovenfor, nemlig forme et GPS ord sammen med den næste byte, der modtages. Er pariteten i orden, gemmes ordet og de 5 første bytes i CRWBufferen smides væk.

BufferunderrunException

Denne exception kastes af CRWBuffer og WordBuffer, hvis der forsøges læst fra en tom buffer.

BufferoverrunException

Denne exception kastes af CRWBuffer, hvis der forsøges skrevet til en fuld buffer.
Hvis denne exception opstår, når WordBuffer skriver til sin egen interne CRWBuffer er der sket en fatal fejl, som højst sandsynligt er en programmeringsfejl (med mindre der er fejl på computerens hardware). WordBuffer kaster ikke fejlen videre, men nulstiller bufferen i forsøg på at rette op på fejlen. Denne fejl udskrives til kommandoprompten uanset hvilken Tetser der bruges (se Test af serveren for forklaring af Tester klassen), da dette er en meget alvorlig fejl.


home