Commit 285d45ac authored by Per Cederqvist's avatar Per Cederqvist
Browse files

Incorporated into lyskomd.texi.

parent 89a66ba5
Local_to_global.doc
Inledning
=========
Den här filen beskriver en datastruktur som är lämplig för att lagra
en mappning från lokala textnummer till globala textnummer i servern.
Den används i varje Conference för att tala om vilka texter som finns
kvar med mötet som mottagare.
Den tidigare implementationen var följande (typ):
int first_text_no; /* Första numret i listan */
int num_texts; /* Antal Text_no i array */
Text_no * texts; /* Pekare till array */
Varje gång en ny text skapas i ett möte så läggs det globala
textnumret till i arrayen ovan, varvid hela arrayen omallokeras med
realloc(). Detta är naturligtvis fruktansvärt inneffektivt.
Ibland så tas texter bort, t ex när en person utplånar en text eller
när en garbning sker i servern. Då kan två saker hända:
- Den första texten som är kvar tas bort. I så fall ökas
first_text_no, som innehåller starten på arrayen.
- Något text inne i listan tas bort. Det globala textnumret ersätts
då med 0.
I det första fallet så omallokeras arrayen med realloc() igen och
krymper lite. I det andra fallet så händer ingenting alls med
storleken. Detta är det troligaste fallet eftersom det första numret
nästan alltid är en markerad text. Den här arrayen har alltså den
otrevliga egenskapen att den växer oavbrutet.
Analys
======
Det sätt som textnummer läggs till har ett antal egenskaper:
- Texter läggs hela tiden på bakifrån, aldrig i mitten eller i
början.
- Numren på de lokala textnumren är konsekutiva, dvs inga hål
finns. Sådana hål kan dock uppstå (och uppstår!) när texter tas
bort.
Lösning
=======
Det första man ser när man analyserar innehållet i en mapp, är att det
finns långa avsnitt av idel nollor, och långa avsnitt där det inte
finns några nollor alls, eller åtminstone väldigt få. Detta antyder
alltså att man bör ha en adaptiv datastruktur som anpassar sig till
det lokala förhållanden. Vi föreslår alltså följande.
Mappen lagras i block (små arrayer). Det finns två sorters block:
1. Glesa block. Glesa block består egentligen av två block. I det
ena blocket ligger nycklar (Local_text_no) och i det andra blocket
ligger data (Text_no). Inom ett block använder man binärsökning i det
ena blocket för att hitta just den Local_text_no man är ute efter.
2. Täta block. Täta block består av ett enda block som innehåller
data (Text_no). Man vet vilket lokalt textnummer det första entryt
svarar mot. Det kan finnas enstaka lokala nummer i ett tätt block som
inte finns -- då innehåller data 0.
Blockstorleken är fixerad till t ex 100 entries. (Det verkar som om
man tjänar nästan exakt samma antal bytes oavsett om man väljer
blockstorlek 50 eller 1000). Ett fullt tätt block innehåller alltid
exakt 100 lokala textnummer. Ett fullt glest block innehåller alltid
100 existerande globala textnummer. (Ett glest block tar dubbelt så
mycket plats som ett tätt block, eftersom ett glest block ju
egentligen består av både ett nyckelblock och ett värdeblock).
För att hålla reda på sina block har man en array av block_info:
typedef struct block_info {
int first_free;
int zeroes;
Local_text_no start;
Local_text_no * key_block;
Text_no * value_block;
} L2g_block_info;
Om key_block == NULL så är det ett tätt block.
first_free
Fältet first_free visar var i blocket som man kan fylla på med
fler värden. Det är 100 för fulla block. För block som inte är
fulla pekar det ut det entry i value_block som nästa värde ska
hamna i. Det gäller t ex det sista blocket, som fylls på allt
eftersom nya inlägg skickas till mötet eller block där texter har
tagits bort.
zeroes
Fältet zeroes används bara för täta block, och räknar antalet
nollor i blocket. Om zeroes blir större än 50% av blockstorleken
gör man om blocket till ett glest block. Fältet zeroes är en
optimering som troligtvis underlättar ihopslagning av block. Det
är möjligt att den inte behövs.
start
Fältet start innehåller numret på det första lokala textnumret i
blocket.
key_block
Fältet key_block är en pekare till blocket med Local_text_no, dvs
nycklarna i blocket. Detta fält är NULL om detta är ett tätt
block.
value_block
Fältet value_block är en pekare till blocket med Text_no, dvs
värdena i blocket.
Förutom detta behövs en struct per möte som håller reda på arrayen med
block:
typedef struct local_to_global {
int num_blocks;
int block_size;
L2g_block_info * blocks;
} Local_to_global;
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment