+
+ // Read the data from the disk.
+ Seek(ih, offset);
+ Read(ih, (long)buffer, length);
+#if CACHE_STATS
+ if (cache) gCacheMisses++;
+#endif
+
+ // Put the data from the disk in the cache if needed.
+ if (loadCache) {
+ // Find a free entry.
+ oldestTime = gCacheTime;
+ for (cnt = 0; cnt < gCacheNumEntries; cnt++) {
+ entry = &gCacheEntries[cnt];
+
+ // Found a free entry.
+ if (entry->ih == 0) break;
+
+ if (entry->time < oldestTime) {
+ oldestTime = entry->time;
+ oldestEntry = cnt;
+ }
+ }
+
+ // If no free entry was found, use the oldest.
+ if (cnt == gCacheNumEntries) {
+ cnt = oldestEntry;
+#if CACHE_STATS
+ gCacheEvicts++;
+#endif
+ }
+
+ // Copy the data from disk to the new entry.
+ entry = &gCacheEntries[cnt];
+ entry->ih = ih;
+ entry->time = ++gCacheTime;
+ entry->offset = offset;
+ bcopy(buffer, gCacheBuffer + cnt * gCacheBlockSize, gCacheBlockSize);
+ }
+
+ return length;