The buffer pool is a collection of frames (page-sized sequence of main memory bytes) that is managed by the Buffer Manager. Conceptually, it should be stored as an array bufPool[numbuf] of Page objects. However, due to the limitation of Java language, it is not feasible to declare an array of Page objects and later on writing string (or other primitive values) to the defined Page. To get around the problem, we have defined our Page as an array of bytes and deal with buffer pool at the byte array level. Therefore, when implement your constructor for the BufMgr class, you should declare the buffer pool as bufpool[numbuf][page_size]. Note that the size of minibase pages is defined in the interface GlobalConst of the global package. Before jump into coding, please make sure that you understand how Page object is defined and manipulated in Java minibase.
In addition, you should maintain an array bufDescr[numbuf] of descriptors, one per frame. Each descriptor is a record with the following fields:
page number, pin_count, dirtybit.
The pin_count field is an integer, page number is a PageId object, and dirtybit is a boolean. This describes the page that is stored in the corresponding frame. A page is identified by a page number that is generated by the DB class when the page is allocated, and is unique over all pages in the database. The PageId type is defined as an integer type in minirel.h.
A simple hash table should be used to figure out what frame a given disk page occupies. The hash table should be implemented (entirely in main memory) by using an array of pointers to lists of page number, frame number pairs. The array is called the directory and each list of pairs is called a bucket. Given a page number, you should apply a hash function to find the directory entry pointing to the bucket that contains the frame number for this page, if the page is in the buffer pool. If you search the bucket and don't find a pair containing this page number, the page is not in the pool. If you find such a pair, it will tell you the frame in which the page resides. This is illustrated in Figure 1.
The hash function must distribute values in the domain of the search field uniformly over the collection of buckets. If we have HTSIZE buckets, numbered 0 through M-1, a hash function of the form works well in practice. HTSIZE should be chosen to be a prime number.
When a page is requested the buffer manager should do the following:
To implement the Clock replacement policy, maintain a queue of frame numbers. When a frame is to be chosen for replacement, you should pick the first frame in this list. A frame number is added to the end of the queue when the pin_count for the frame is decremented to 0. A frame number is removed from the queue if the pin_count becomes non-zero: this could happen if there is a request for the page currently in the frame!