Professional Documents
Culture Documents
Hoofdstuk 14 - Extern Geheugen
Hoofdstuk 14 - Extern Geheugen
λλ 1
Wat is data? Bits : 2 ≠ voltages
1.20
λλ
0.21
0.22
1.23
1.24
0.25
1.26
1.27
∑ = 217
λλ
> (mod number 256)
214
> (set! number (div number 256))
> number
18
a 00111100
λλ
01000010
00000010
00011110
01100010
01000010
01000110
00111011
λλ
1024 megabyte = 1 gigabyte (1G)
1024 gigabyte = 1 terabyte (1T) 22 = 4
1024 terabyte = 1 petabyte (1P) 23 = 8
1024 petabyte = 1 exabyte (1E) 24 = 16
1024 exabyte = 1 zettabyte (1Z) 25 = 32
1024 zettabyte = 1 yottabyte (1Y) 26 = 64
27 = 128
Computers Harddisks 28 = 256
≈
gigabytes
≈
terabytes
Hoofdstuk 14 : Extern Geheugen λλ
210
216
=
=
1024
65536
6
Scheme’s Bytevectoren
Nuttig om “rauwe”
data voor te stellen
a 00111100
01000010
00000010
00011110
λλ
01100010
01000010
01000110
00111011
(define letter-a
(let ((v (make-bytevector 8)))
(bytevector-u8-set! v 0 60)
(bytevector-u8-set! v 1 66) Veel efficiënter dan
(bytevector-u8-set! v 2 2)
(bytevector-u8-set! v 3 30) gewone vectoren
(bytevector-u8-set! v 4 98)
(bytevector-u8-set! v 5 66)
(bytevector-u8-set! v 6 70)
λλ
(bytevector-u8-set! v 7 59) > (bytevector-u8-ref letter-a 6)
v)) 70
λλ
signed bytevector startindex # bytes
(bytevector-sint-set! bytes indx nmbr 'big size)
λλ
(define real64 8)
(bytevector-ieee-single-ref bytes indx 'big)
λλ
6
λλ
(if (> rem 3)
(fill! (+ offset 3) (- rem 3))))))
(fill! 0 nmbr-byts)
> (string<? "д" (utf8-sentinel-for 2))
(utf8->string byts))
#t
> (string<? "д" (utf8-sentinel-for 1))
#f
Hoofdstuk 14 : Extern Geheugen 9
Waar zitten die bytes?
Centraal Geheugen Periferisch Geheugen
Duur Persistent
λλ
Volatiel Traag
Snel
Supergoedkoop
Volatiel
Zeer duur
Supersnel
Registers + Caches
λλ
Centraal geheugen
Flash Disk
Secundair Geheugen
Tapes
CD racks
λλ
Tertiair Geheugen
operators
λλ
Secundair Geheugen
Tertiair Geheugen
12
Disks
Een as met
schijven
λλ Een lees- en
schrijfkop
Magnetiseerbaar
13
Geformateerde Disk
Georganiseerd in tracks
en sectoren. Op elke
λλ
track ∩ sector bevindt
zich een blok.
λλ
Een blok is de lees- en
schrijfeenheid.
Hoofdstuk 14 : Extern Geheugen 14
Een blok lezen of schrijven
Fase 1: De kop bewegen
naar de juiste track.
λλ
Fase 2: Wachten tot de
juiste sector passeert.
λλ
disk-size
number
block-ptr-size block-size bytes
number
block-idx-size
number (define block-size 50)
new (define disk-size 200)
( string + disk ) (define block-ptr-size (natural-bytes disk-size))
mount (define block-idx-size (natural-bytes block-size))
( string + disk )
unmount
( disk + ∅ ) Elk bloknummer past in
disk?
( any + boolean ) block-ptr-size bytes
λλ
name
( disk + string
read-block
)
Elke blokindex past in
( disk number + block )
block-idx-size bytes
Hoofdstuk 14 : Extern Geheugen 16
Disk (image): Implementatie
(define-record-type disk
(make-disk n) Bezet een stuk
disk?
(n name)) van de echte disk
λλ
(define (new name)
(define port (open-file-output-port name
(file-options no-truncate no-fail)
(buffer-mode block)))
(define zeroes (make-bytevector block-size 0))
(let low-level-format
Maakt de
((block-nr 0))
(put-bytevector port zeroes)
blokken aan
(if (< (+ 1 block-nr) disk-size)
(low-level-format (+ 1 block-nr))))
(close-port port)
(make-disk name))
open-file-output-port,
λλ
(define (mount name) put-bytevector, close-port
(make-disk name))
∈ R6RS
(define (unmount dsk)
())
λλ
( any + boolean ) ( block number number + string )
disk encode-string!
( block + disk ) ( block number number string + ∅ )
position decode-fixed-natural
( block + number ) ( block number number + natural )
encode-fixed-natural!
( block number number natural + ∅ )
decode-arbitrary-integer
( block number + integer × number )
encode-arbitrary-integer!
( block number integer + number )
decode-real
( block number number + real )
encode-real!
λλ
( block number number real + number )
decode-bytes
( block bytevector number number number + ∅ )
encode-bytes!
( block bytevector number number number + ∅ )
λλ
(define-record-type block
(make-block d p b)
block?
(d disk)
(p position)
(b bytes))
λλ
(close-port port)
(make-block dsk bptr byts)))
van de output port
(define (write-block! blck)
(define bptr (position blck))
op de juiste byte
(define data-byts (bytes blck))
(define port (open-file-output-port (name (disk blck))
(file-options no-truncate no-fail)))
(set-port-position! port (* bptr block-size))
(put-bytevector port data-byts) Lees/schrijf de
(close-port port))
bytevector horend
open-file-output-port,
bij het blok
λλ
set-port-position!,
get-bytevector-n
put-bytevector, close-port
∈ R6RS
Hoofdstuk 14 : Extern Geheugen 20
En/De-coderen van data(1)
(define (encode-byte! blck offs byte)
(bytevector-u8-set! (bytes blck) offs byte))
λλ
(bytevector-u8-ref (bytes blck) offs))
λλ
(define (decode-arbitrary-integer blck offs)
(define size (decode-byte blck offs))
(define nmbr (bytevector-sint-ref (bytes blck) (+ offs 1) 'big size))
(cons nmbr (+ offs size 1)))
λλ
size)
((= size real32)
(bytevector-ieee-single-set! (bytes blck) offs nmbr 'big)
size)
(else
(error "illegal real size" size))))
22
En/De-coderen van data(3)
(define (encode-string! blck offs size strg) Kopieer alle
bytes en vul
(set! strg (string->utf8 strg))
(do ((indx 0 (+ indx 1)))
λλ
(let ((byte (if (< indx (bytevector-length strg))
(bytevector-u8-ref strg indx)
str-end-byte))) Padding
(encode-byte! blck (+ offs indx) byte))))
(define str-end-byte 0)
(define (decode-string blck offs size)
(let ((bytevector-u8-set!
(lambda (bv indx val)
(bytevector-u8-set! bv indx val)
bv)))
(utf8->string
(let loop
((indx 0))
(if (< indx size) Blijf uitlezen tot
λλ
je een 0 ziet
(let ((byte (decode-byte blck (+ offs indx))))
(if (eq? byte str-end-byte)
(make-bytevector indx 0)
(bytevector-u8-set! (loop (+ indx 1)) indx byte)))
(make-bytevector indx 0))))))
a 00111100
01000010
00000010
00011110
01100010
01000010
01000110
00111011
λλ
(define (encode-bytes! blck byts blck-offs u8-offs size)
(do ((indx 0 (+ indx 1))) Kopieer byts
((= indx size))
(encode-byte! blck in het blck
(+ blck-offs indx)
(bytevector-u8-ref byts (+ u8-offs indx)))))
λλ
(+ u8-offs indx)
(decode-byte blck (+ blck-offs indx)))))
λλ
ontstaan door blokken aan elkaar te linken. Dit
gebeurt door de blokpointer van het ene blok te
encoderen als bytes in het andere blok. Een reeks
aan elkaar gelinkte blokken noemen we een file.
Sommige blokken behoren tot De files geven we een
één of andere file; andere zijn naam. De directory is
vrij. De vrije blokken worden een lijst van filenamen
bijgehouden in een freelist.
Alles begint bij het metablok
λλ
met bloknummer van
het begin van de file
Hoofdstuk 14 : Extern Geheugen 25
Organisatie van de Disk
meta
λλ
blok
λλ
(substring name 0 filename-size)
name))
+∞
(define sentinel-filename (utf8-sentinel-for filename-size))
(define null-block 0)
(define meta-bptr null-block)
λλ
(disk:read-block disk meta-bptr))
λλ
(define next-offset 0)
λλ
(define available-offset (* 2 disk:block-ptr-size))
λλ
(define (blocks-free! meta free)
(disk:encode-fixed-natural! meta available-offset disk:block-ptr-size free))
λλ
()
()
() ()
()
λλ
(define (dir-name/bptr! blck slot name bptr)
(define offn (+ disk:block-ptr-size (* slot slot-size)) )
(define offp (+ disk:block-ptr-size (* slot slot-size) filename-size))
(disk:encode-string! blck offn filename-size name)
(disk:encode-fixed-natural! blck offp disk:block-ptr-size bptr))
λλ
(define (empty-slot? blck slot)
(string=? sentinel-filename (dir-name blck slot)))
directory, naar de
λλ
(directory! meta null-block)
(freelist! meta (+ meta-bptr 1))
λλ
disk)
λλ
(if (null-block? flst)
(error "disk full! (new-block)" disk)
(let* ((blck (disk:read-block disk flst)))
(blocks-free! meta (- (blocks-free meta) 1))
(freelist! meta (next-bptr blck))
(write-meta-block! meta)
blck)))
λλ
((at-end? next slot)
(next! next)
next)
(dir-name/bptr! next slot sentinel-filename null-block)))
λλ
(define disk (disk:disk blck))
(define meta (read-meta-block disk))
(next-bptr! blck (freelist meta))
(disk:write-block! blck)
(freelist! meta (disk:position blck))
(blocks-free! meta (+ (blocks-free meta) 1))
(write-meta-block! meta))
λλ
(delete-block blck)
(delete-chain! disk next))))
Een hele lijst van
blokken vrijgeven
Hoofdstuk 14 : Extern Geheugen 34
Filesysteem Operatie #1: mk
(define (mk disk name bptr)
(define meta (read-meta-block disk))
Een slot aanmaken
(let loop-dir
((dptr (directory meta))
in de directory
λλ
(new! (lambda (newb)
(let ((meta (read-meta-block disk)))
(directory! meta (disk:position newb)) outer loop:
(write-meta-block! meta)))))
(let ((blck (if (null-block? dptr) directory blokken
(fresh-block! disk new!)
(disk:read-block disk dptr))))
(let loop-block
((slot 0))
(cond ((at-end? blck slot)
(loop-dir (next-bptr blck)
(lambda (newb)
(next-bptr! blck (disk:position newb))
(disk:write-block! blck))))
λλ
((empty-slot? blck slot)
(dir-name/bptr! blck slot name bptr) inner loop: slot
(disk:write-block! blck))
(else zoeken in een blok
(loop-block (+ slot 1))))))))
λλ
(write-meta-block! meta))))
(let ((blck (if (null-block? bptr)
outer loop:
(error "file not found (rm)" name)
(disk:read-block disk bptr))))
directoryblokken
(let loop-block
((slot 0)
(seen #f))
inner loop: slot
(cond ((at-end? blck slot)
(loop-dir (next-bptr blck) (lambda (next)
zoeken in een blok
(next-bptr! blck next)
(disk:write-block! blck))))
((empty-slot? blck slot)
(loop-block (+ slot 1) seen))
((string=? name (dir-name blck slot))
λλ
(dir-name/bptr! blck slot sentinel-filename null-block)
(disk:write-block! blck)
(if (not seen)
(maybe-delete-block! blck slot nxt!)))
(else
(loop-block (+ slot 1) #t)))))))
Hoofdstuk 8 : Extern Geheugen 36
Filesysteem Operatie #2: rm (ctd)
(define (rm disk name)
(define meta (read-meta-block disk))
(set! name (cap-name name))
(let loop-dir
((bptr (directory meta))
(nxt! (lambda (next)
(directory! meta next)
λλ
(write-meta-block! meta))))
(let ((blck (if (null-block? bptr)
(error "file not found (rm)" name)
(disk:read-block disk bptr))))
(let loop-block
((slot 0) (define (maybe-delete-block! blck slot next!)
(seen #f)) (cond
(cond ((at-end? blck slot) ((at-end? blck slot)
(loop-dir (next-bptr blck)(next!
(lambda
(next-bptr
(next) blck))
(delete-block blck))
(next-bptr! blck next)
((empty-slot? blck slot) blck))))
(disk:write-block!
((empty-slot? blck slot) (maybe-delete-block! blck (+ slot 1) next!))))
(loop-block (+ slot 1) seen))
((string=? name (dir-name blck slot))
λλ
(dir-name/bptr! blck slot sentinel-filename null-block)
(disk:write-block! blck)
(if (not seen)
(maybe-delete-block! blck slot nxt!)))
(else
(loop-block (+ slot 1) #t)))))))
Hoofdstuk 14 : Extern Geheugen 37
Operaties #3&4: whereis, ls
(define (ls disk)
(define meta (read-meta-block disk))
(define bptr (directory meta))
De directory
(if (null-block? bptr)
()
opsommen als lijst
λλ
(let traverse-dir
((blck (disk:read-block disk bptr))
(define (whereis disk name)
(slot 0))
(define meta (read-meta-block disk))
(cond ((at-end? blck slot)
(define bptr (directory meta))
(if (has-next? blck)
(set! name (cap-name name))
(if (null-block? bptr)
()))
Een file opzoeken
(traverse-dir (disk:read-block disk (next-bptr blck)) 0)
0
((empty-slot? blck slot)
(let traverse-dir
(traverse-dir blck (+ slot 1)))
in de directory
((blck (disk:read-block disk bptr))
(else
(slot 0))
(cons (cons (dir-name blck slot) (dir-bptr blck slot))
(cond ((at-end? blck slot)
(traverse-dir blck (+ slot 1))))))))
(if (has-next? blck)
(traverse-dir (disk:read-block disk (next-bptr blck)) 0)
λλ
null-block))
((string=? name (dir-name blck slot))
(dir-bptr blck slot))
(else
(traverse-dir blck (+ slot 1)))))))
λλ
new name
( disk string + output-file ) ( input-file + string )
name open-read!
( output-file + string ) ( disk string + input-file )
open-write! rewrite!
( disk string + output-file ) ( input-file + output-file )
close-write! close-read!
( output-file + ∅ ) ( input-file + ∅ )
reread! has-more?
( output-file + input-file ) ( input-file + boolean )
write! read
( output-file any + ∅ ) ( input-file + any )
delete! peek
λλ
( output-file + ∅ ) ( input-file + any )
delete!
λλ
(out:write! f 3.14)
(out:write! f 42)
(out:write! f "Done!")
(out:close-write! f)
λλ
3.14
42
Done!
>
λλ
(h header header!)
(b buffer buffer!))
1ste blok v/d file. De buffer is een kopie
in centraal geheugen van één blok van de
file. Slechts 2 blokken in het geheugen!
λλ
(disk:encode-fixed-natural! hder frst-offs disk:block-ptr-size bptr))
(define (current hder)
(disk:decode-fixed-natural hder curr-offs disk:block-idx-size))
(define (current! hder offs)
(disk:encode-fixed-natural! hder curr-offs disk:block-idx-size offs))
λλ
(first! hder (disk:position bffr))
in de
(fs:next-bptr! bffr fs:null-block)
(current! hder disk:block-ptr-size)
(disk:write-block! hder)
file)
(define (open-write! disk name)
(define bptr (fs:whereis disk name))
directory
(define hder (disk:read-block disk bptr))
(define fptr (first hder))
(define bffr (disk:read-block disk fptr))
(define file (make disk name hder bffr))
(current! hder disk:block-ptr-size)
file)
(define (open-read! disk name)
(define bptr (fs:whereis disk name))
(define hder (disk:read-block disk bptr))
Current: next
λλ
(define fptr (first hder))
(define bffr (disk:read-block disk fptr))
pointer overslaan (define file (make disk name hder bffr))
(current! hder disk:block-ptr-size)
file)
λλ
(define hder (header file))
(define curr (current hder))
(- disk:block-size curr))
ongebruikte blokken op
(define (close-write! file)
(define hder (header file))
(define bffr (buffer file))
(define fdsk (disk file))
(disk:write-block! hder)
(if (> (block-bytes-free file) 0)
(disk:encode-byte! bffr (current hder) eof-tag))
(let ((rest-list (fs:next-bptr bffr)))
(fs:next-bptr! bffr fs:null-block) (define (delete! file)
(fs:delete-chain! fdsk rest-list)) (define fnam (name file))
λλ
(disk:write-block! bffr)) (define hder (header file))
(define fdsk (disk file))
(fs:delete-chain! fdsk (first hder))
(fs:delete-block hder)
(fs:rm fdsk fnam))
λλ
(define hder (header file))
(define fptr (first hder))
(close-write! file)
(buffer! file (disk:read-block dsk fptr))
(current! hder disk:block-pointer-size)
file)
λλ
(buffer! file (disk:read-block fdsk fptr))
(current! hder disk:block-ptr-size)
file)
λλ
(define (write! file sval)
(cond ((natural? sval)
(write-type-tag file natural-tag)
(write-natural file (exact sval)))
((integer? sval)
Schrijf de waarde
(write-type-tag file integer-tag)
(write-integer file (exact sval)))
achter die byte
((real? sval)
(write-type-tag file decimal-tag)
(write-real file sval))
((string? sval)
(write-type-tag file string-tag)
(write-string file sval)) (define natural-tag 0)
(error "unsupported type (write!)" sval))) (define integer-tag 1)
λλ
(define decimal-tag 2)
(define string-tag 3)
(define eof-tag 255)
(define eob-tag 254)
λλ
(disk:encode-byte! bffr curr ttag)
(current! hder (+ curr 1))))
λλ
(current! hder (+ curr (disk:encode-real! bffr curr disk:real64 nmbr)))))
(curr (current hder))
(bffr (buffer file))
(byts (string->utf8 strg)))
(disk:encode-byte! bffr curr (bytevector-length byts))
(current! hder (+ curr 1))
(rollout-bytes file byts 0)))
Hoofdstuk 14 : Extern Geheugen 46
Garanderen van Plaats
(define (claim-bytes! file nmbr)
(define bffr (buffer file))
(define hder (header file))
(define curr (current hder))
(when (< (block-bytes-free file) nmbr)
λλ
(if (not (= curr disk:block-size))
(disk:encode-byte! bffr curr eob-tag))
(provide-next-block! file)))
λλ
oud blok (else
(disk:write-block! bffr)
(disk:read-block fdsk (fs:next-bptr bffr)))))
(buffer! file next)
(current! hder disk:block-ptr-size))
λλ
(define hder(peek-natural
(header file))
file))
(let* ((bffr((=(buffer
ttag integer-tag)
(curr-offs
file))
(peek-integer
(currentfile))
hder))
hebben
(ttag
((=(read-type-tag
ttag decimal-tag)
file))
(res (peek-real
(car (cond file))
((= ttag natural-tag)
((= ttag string-tag)
(peek-natural file))
(peek-string((=
file))
ttag integer-tag)
((= ttag eof-tag)
(peek-integer file))
(cons () curr))
((= ttag decimal-tag)
(else (peek-real file))
(error "unsupported
((= ttag type
string-tag)
on file (read)" ttag)))))
(current! hder (cdr vcur)) (peek-string file))
(car vcur))) ((= ttag eof-tag)
(cons () curr-offs))
λλ
(else
(error "unsupported type on file (peek)" ttag))))))
(current! hder curr-offs)
(buffer! file bffr) peek reset
res))
de toestand
Hoofdstuk 8 : Extern Geheugen 48
Garanderen van Bytes
(define (supply-bytes! file)
(define bffr (buffer file))
(define hder (header file))
(define curr (current hder))
(if (not (more-on-buffer? file))
λλ
(read-next-block! file)))
λλ
(define bffr (buffer file))
(define next-bptr (fs:next-bptr bffr))
(define next-blck (disk:read-block fdsk next-bptr))
(buffer! file next-blck)
(current! hder disk:block-ptr-size))
λλ
Minimaliseren van het aantal bloktransferten
λλ
en het verschil in performantiegedrag
van die twee geheugens opvangt via
statistische technieken.
λλ
read-block
write-block!
Met cache
Applicatie Disk Abstractie
read-block
read-block
λλ
write-block! write-block!
λλ
de grootste kans om in de nabije
toekomst opnieuw gebruikt te worden.
Selection Sort
Hoofdstuk 14 : Extern Geheugen λλ
Quicksort
53
Caching Terminologie
Als een benodigde datawaarde tijdens het
lezen van de cache gevonden wordt, spreken
λλ
we van een cache hit. Anders van een cache
miss en is een evict nodig alvorens een nieuwe
datawaarde in de cache kan geladen worden.
λλ
meteen. In een write-back cache gebeurt dat bij een
evict. Een dirty-bit is dan nodig voor boekhouding.
λλ
First-In, First-Out (FIFO): De oudste
datawaarde wordt eruit gegooid.
λλ
Least Recently Used (LRU): Gooi de datawaarde
eruit die het langst niet meer gebruikt is.
λλ
( any + boolean ) ( block number number + string )( block boolean+ ∅ )
encode-string! locked?
disk
( block number number string + ∅( )block + boolean )
( block + disk )
position
read-block maakt
decode-fixed-natural
locked!
( block boolean+ ∅ )
het blok gelocked
( block + number ) ( block number number + natural )
time-stamp
encode-fixed-natural!
( block number number natural + (∅ block
) + time )
decode-arbitrary-integer time-stamp!
( block number + integer × number( )
block time + ∅ )
invalidate!
encode-arbitrary-integer!
Elk gebruikt (encode of decode)
( block number integer + number )
( block + ∅ )
valid?
decode-real
actualiseert de time-stamp
( block number number + real ) ( block + boolean )
encode-real!
λλ
( block number number real + number )
Encoders maken decode-bytes
Eens ge-evict uit de cache,
( block bytevector number number number + ∅ )
het blok “dirty” is het blok niet meer valid
encode-bytes!
( block bytevector number number number + ∅ )
λλ
block?
(d dirty? dirty-set!)
(l locked? locked!) locked: werd het block
(t time-stamp time-stamp!)
(i disk) door de applicatie nog niet
(b block block!))
logisch weggeschreven?
(define (make-block cdsk blck)
(make #f #t (current-time) cdsk blck))
λλ
(define (invalidate! blck)
(block! blck ()))
λλ
(if (not (valid? blck))
(error "invalidated cblock(cached version of encoder)" blck))
(time-stamp! blck (current-time))
(dirty! blck)
(apply proc (cons (block blck) (cdr args)))))
We maken het
(define encode-byte!
blok “jonger”
(make-cached-encoder disk:encode-byte!))
(define encode-fixed-natural!
(make-cached-encoder disk:encode-fixed-natural!)) Oorspronkelijke
(define encode-arbitrary-integer!
(make-cached-encoder disk:encode-arbitrary-integer!)) operatie wordt
(define encode-real!
(make-cached-encoder disk:encode-real!)) opgeroepen
λλ
(define encode-string!
(make-cached-encoder disk:encode-string!))
Operaties op invalid blokken
(define encode-bytes!
(make-cached-encoder disk:encode-bytes!))
worden tegengehouden
Hoofdstuk 14 : Extern Geheugen 58
Gecachete Decoders
(define (make-cached-decoder proc)
(lambda args
(define blck (car args))
λλ
(if (not (valid? blck))
(error "invalidated cblock(cached version of decoder)" blck))
(time-stamp! blck (current-time))
(apply proc (cons (block blck) (cdr args)))))
Ze
lfd
(define decode-byte
ei
(make-cached-decoder disk:decode-byte))
de
(define decode-fixed-natural
(make-cached-decoder disk:decode-fixed-natural))
e
(define decode-arbitrary-integer
(make-cached-decoder disk:decode-arbitrary-integer))
(define decode-real
(make-cached-decoder disk:decode-real))
(define decode-string
λλ
(make-cached-decoder disk:decode-string))
(define decode-bytes
(make-cached-decoder disk:decode-bytes))
λλ
number
block-ptr-size
number
block-idx-size
Implementatie
number
new
bevat echter een
( string + disk
mount
)
cache in het
( string + disk
unmount
) centraal geheugen
( disk + ∅ )
disk?
( any + boolean )
name
λλ
( file + string )
size
( file + number )
read-block
( disk number + block )
(define (cache:new)
Gewoon een
(make-vector cache-size ()))
vector van blokken
(define (cache:get cche indx)
λλ
(vector-ref cche indx))
λλ
((< (+ indx 1) cache-size)
(traverse (+ indx 1)
(cache:get cche (+ indx 1))))
(else
()))))
λλ
(define (traverse indx)
(if (< indx cache-size)
(let
((blck (cache:get cche indx)))
“oudste tot nu toe”
(if (null? blck)
indx
(let ((lckd (locked? blck)))
(if (not lckd) Gelockedte
Vrij slot is
(let
((stmp (time-stamp blck))) blokken
meteen goed
(when (time<? stmp oldest-time)
(set! oldest-time stmp) komen niet in
(set! oldest-indx indx))))
(traverse (+ indx 1))))) aanmerking
λλ voor evict
(if (negative? oldest-indx)
(error "cache full" cche)
oldest-indx)))
(traverse 0))
λλ
Gecachete disk (define (name cdsk)
(disk:name (real-disk cdsk)))
= disk + cache
Alle dirty blokken
(define (unmount disk)
(define vctr (cache:vector disk)) moeten geschreven
(define (traverse indx)
(if (< indx cache-size) worden
(let ((blck (cache:get vctr indx)))
Wandel de (cond
((not (null? blck))
volledige (if (dirty? blck)
λλ
(disk:write-block! (block blck)))
cache af (invalidate! blck)))
(traverse (+ indx 1)))))
(traverse 0)
(disk:unmount disk))
λλ
eventueel na een evict
((indx (cache:find-free-index cche))
(blck (cache:get cche indx)))
(when (not (null? blck))
(if (dirty? blck)
(disk:write-block! (block blck)))
(invalidate! blck))
(set! blck (make-block cdsk (disk:read-block (real-disk cdsk) bptr)))
(cache:put! cche indx blck)))
(locked! blck #t) Gelezen blokken
blck)
worden gelocket
(define (write-block! blck)
(define cche (disk-cache (disk blck)))
(if (not (valid? blck)) en worden
λλ
(error "invalidated block(write-block!)" blck))
λλ
14.1 Wat is Data? Bits, bytes, bytevectoren
14.5 Caching