Re your disk hash questions ... 1) I intentionally did not talk about the standard IO library functions fopen(), fread(), fwrite(), fseek() etc in class because I want you to get some experience with the underlying system calls that do the real work. On Unix/Linux/MacOS the standard IO library just introduces an extra level of buffering and then calls the system calls read() write() etc to do the actual operations. For our disk hash there is no value to using that extra layer of functions and buffers. However, if you want to learn more about the stdio functions for your own information there are lots of online web resouces such as ... http://www.cplusplus.com/ref/cstdio/fopen.html 2) Although I told you all you really need to know about read(), write(), and lseek() if you want to read about it you might try this page ... http://developers.sun.com/solaris/articles/fileio.html You can also look at your system's online manual pages or web versions of the linux system call manuals at ... http://www.die.net/doc/linux/man/man2/ and select the specific functions like read() or lseek(). However I think these could make it seem much more complicated than it really is. If any of you want to try pread() and pwrite() be my guest. 3) I've seen several codes that are leaving out the & before the hentry argment in your read() and write() calls. This will fail on all systems that I know of except for Sun machines using the old cc compiler. You need to do it like I did in asn09hashwalk.c ... read(fd, &hentry, sizeof(struct hentry)) 4) There is still confusion about the return value of read() vs the contents of the data that was read in relation to the size of your file. When we write to a file using random access (ie. lseek) we can quite properly leave gaps in our file. Those gaps will read back as being full of null bytes (ie. zeros). These positions would be inside of the current file length which you can think of as the current "high water mark" for the hash records. This is a different situation than when we try to read() from a location that is past the current high water mark as may happen for some of your early records and certainly for the first one. In that case the return value from the read ... n = read(fd, &hentry, sizeof(struct hentry)); which is kept as n in the line above, indicates the number of bytes that were actually read into memory. If you are past the end of the file that result will be 0 which means that no bytes were actually read and that also the contents of the hentry structure are unchanged from what ever was already there prior to the read() call. Therefore, a record can be empty either because it was full of null bytes or because the read() did not actually read anything and returned 0. I suppose one way to avoid dealing with these two different types of empty records would be to initially seek out to the last possible record slot and write a record full of 0 bytes before you even start any of your actual hash insertions. If you do that then you would only have to consider the contents of the records you read rather than the read() return value as well. 5) Since the stuff I told you about disk sectors, tracks, cylinders speeds and so on is not in the book you can read about this online from ... http://www.jegsworks.com/Lessons/lesson6/lesson6-3.htm http://www.jegsworks.com/Lessons/lesson6/lesson6-4.htm http://www.jegsworks.com/Lessons/lesson6/lesson6-5.htm You probably don't care about the floppy disks anymore but you can clearly see that they work on exactly the same general principals as your new big 300Gbyte drive. Information about some real disks from a couple of years ago ... http://www.cse.psu.edu/~youkim/disk.html