changeset 4285:9f5cdfb282a0 HEAD

We were caching the EOF block wrongly in some situations.
author Timo Sirainen <tss@iki.fi>
date Tue, 30 May 2006 11:37:10 +0300
parents ae0d876d98f5
children b5b0e98b1d98
files src/lib/file-cache.c
diffstat 1 files changed, 18 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/src/lib/file-cache.c	Tue May 30 11:36:43 2006 +0300
+++ b/src/lib/file-cache.c	Tue May 30 11:37:10 2006 +0300
@@ -168,7 +168,12 @@
 			/* EOF. mark the last block as cached even if it
 			   isn't completely. read_highwater tells us how far
 			   we've actually made. */
-			bits[poffset / CHAR_BIT] |= 1 << (poffset % CHAR_BIT);
+			if (dest_offset == cache->read_highwater) {
+				i_assert(poffset ==
+					 cache->read_highwater / page_size);
+				bits[poffset / CHAR_BIT] |=
+					1 << (poffset % CHAR_BIT);
+			}
 			return dest_offset <= offset ? 0 :
 				dest_offset - offset < size ?
 				dest_offset - offset : size;
@@ -177,8 +182,17 @@
 		dest += ret;
 		dest_offset += ret;
 
-		if (cache->read_highwater < dest_offset)
+		if (cache->read_highwater < dest_offset) {
+			unsigned int high_poffset =
+				cache->read_highwater / page_size;
+
+			/* read_highwater needs to be updated. if we didn't
+			   just read that block, we can't trust anymore that
+			   we have it cached */
+			bits[high_poffset / CHAR_BIT] &=
+				~(1 << (high_poffset % CHAR_BIT));
 			cache->read_highwater = dest_offset;
+		}
 
 		if ((size_t)ret != dest_size) {
 			/* partial read - probably EOF but make sure. */
@@ -247,7 +261,7 @@
 	unsigned char *bits, mask;
 	unsigned int i;
 
-	if (offset >= cache->read_highwater)
+	if (offset >= cache->read_highwater || size == 0)
 		return;
 
 	if (size > cache->read_highwater - offset)
@@ -255,6 +269,7 @@
 
 	size = (offset + size + page_size-1) / page_size;
 	offset /= page_size;
+	i_assert(size > offset);
 	size -= offset;
 
 	if (size != 1) {