vtLock(stats.lock);
stats.lumpReads++;
vtUnlock(stats.lock);
u = lookupLump(score, type);
if(u->data != nil){
n = packetSize(u->data);
if(n > size){
setErr(EOk, "read too small: asked for %d need at least %d", size, n);
putLump(u);
return nil;
}
p = packetDup(u->data, 0, n);
putLump(u);
return p;
}
if(!lookupScore(score, type, &ia)){
//ZZZ place to check for someone trying to guess scores
setErr(EOk, "no block with that score exists");
putLump(u);
return nil;
}
if(ia.size > size){
setErr(EOk, "read too small 1: asked for %d need at least %d", size, ia.size);
putLump(u);
return nil;
}
p = readILump(u, &ia, score);
putLump(u);
return p;
}
/*
* save away a lump, and return it's score.
* doesn't store duplicates, but checks that the data is really the same.
*/
int
writeLump(Packet *p, u8int *score, int type, u32int creator)
{
Lump *u;
int ok;
u = lookupLump(score, type);
if(u->data != nil){
ok = 1;
if(packetCmp(p, u->data) != 0){
setErr(EStrange, "score collision");
ok = 0;
}
packetFree(p);
putLump(u);
return ok;
}
if(queueWrites)
return queueWrite(u, p, creator);
ok = writeQLump(u, p, creator);
putLump(u);
return ok;
}
int
writeQLump(Lump *u, Packet *p, int creator)
{
ZBlock *flat;
Packet *old;
IAddr ia;
int ok;
if(lookupScore(u->score, u->type, &ia)){
/*
* if the read fails,
* assume it was corrupted data and store the block again
*/
old = readILump(u, &ia, u->score);
if(old != nil){
ok = 1;
if(packetCmp(p, old) != 0){
setErr(EStrange, "score collision");
ok = 0;
}
packetFree(p);
packetFree(old);