]>
git.saurik.com Git - apple/bootx.git/blob - bootx.tproj/fs.subproj/cache.c
35af07201aae1d5c064eadc42302fd274f4a5e00
2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * The contents of this file constitute Original Code as defined in and
7 * are subject to the Apple Public Source License Version 1.1 (the
8 * "License"). You may not use this file except in compliance with the
9 * License. Please obtain a copy of the License at
10 * http://www.apple.com/publicsource and read it before using this file.
12 * This Original Code and all software distributed under the License are
13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17 * License for the specific language governing rights and limitations
20 * @APPLE_LICENSE_HEADER_END@
23 * cache.c - A simple cache for file systems meta-data.
25 * Copyright (c) 2000 Apple Computer, Inc.
38 typedef struct CacheEntry CacheEntry
;
40 #define kCacheSize (0x80000)
41 #define kCacheMinBlockSize (0x200)
42 #define kCacheMaxBlockSize (0x4000)
43 #define kCacheMaxEntries (kCacheSize / kCacheMinBlockSize)
45 static CICell gCacheIH
;
46 static long gCacheBlockSize
;
47 static long gCacheNumEntries
;
48 static long gCacheTime
;
49 static CacheEntry gCacheEntries
[kCacheMaxEntries
];
50 static char gCacheBuffer
[kCacheSize
];
52 unsigned long gCacheHits
;
53 unsigned long gCacheMisses
;
54 unsigned long gCacheEvicts
;
56 void CacheInit(CICell ih
, long blockSize
)
58 if ((blockSize
< kCacheMinBlockSize
) ||
59 (blockSize
>= kCacheMaxBlockSize
))
62 gCacheBlockSize
= blockSize
;
63 gCacheNumEntries
= kCacheSize
/ gCacheBlockSize
;
70 bzero(gCacheEntries
, sizeof(gCacheEntries
));
76 long CacheRead(CICell ih
, char *buffer
, long long offset
,
77 long length
, long cache
)
79 long cnt
, oldestEntry
, oldestTime
, loadCache
= 0;
82 // See if the data can be cached.
83 if (cache
&& (gCacheIH
== ih
) && (length
== gCacheBlockSize
)) {
84 // Look for the data in the cache.
85 for (cnt
= 0; cnt
< gCacheNumEntries
; cnt
++) {
86 entry
= &gCacheEntries
[cnt
];
87 if ((entry
->ih
== ih
) && (entry
->offset
== offset
)) {
88 entry
->time
= ++gCacheTime
;
93 // If the data was found copy it to the caller.
94 if (cnt
!= gCacheNumEntries
) {
95 bcopy(gCacheBuffer
+ cnt
* gCacheBlockSize
, buffer
, gCacheBlockSize
);
97 return gCacheBlockSize
;
100 // Could not find the data in the cache.
104 // Read the data from the disk.
106 Read(ih
, (CICell
)buffer
, length
);
107 if (cache
) gCacheMisses
++;
109 // Put the data from the disk in the cache if needed.
111 // Find a free entry.
112 oldestTime
= gCacheTime
;
113 for (cnt
= 0; cnt
< gCacheNumEntries
; cnt
++) {
114 entry
= &gCacheEntries
[cnt
];
116 // Found a free entry.
117 if (entry
->ih
== 0) break;
119 if (entry
->time
< oldestTime
) {
120 oldestTime
= entry
->time
;
125 // If no free entry was found, use the oldest.
126 if (cnt
== gCacheNumEntries
) {
131 // Copy the data from disk to the new entry.
132 entry
= &gCacheEntries
[cnt
];
134 entry
->time
= ++gCacheTime
;
135 entry
->offset
= offset
;
136 bcopy(buffer
, gCacheBuffer
+ cnt
* gCacheBlockSize
, gCacheBlockSize
);