Frequently Asked Questions

Programming Language Questions

Question: I know Java/C, but I have not programmed in C++ before. Where can I read up on C++?
Answer: Bjarne Stoustroupe's book on "The C++ Programming Language" is a good reference. You can also read the following online tutorial: http://www.cplusplus.com/doc/tutorial/.

Question: Can we use MFC (Microsoft Foundation Classes) or STL (Standard Template Libraries) in the programming assignments?
Answer: No.

Question: Since we are using Visual Studio .Net, can we use advanced features such as attribute programming and managed C++ classes?
Answer: No. We are using Visual Studio .Net as the reference platform because it is supported in the CSUGLAB. You should make sure that your code works in the reference platform, but you should avoid using vendor-specific features.

Question: Does our program have to be thread-safe?
Answer: No.

General Implementation Questions

Question: How do we access the DB object?
Answer: There is a global variable "minibase_globals" that points to an instance of the class SystemDefs. This instance contains all the global variables.

Question: In the project specification, it says that the constant NUMBUF determines the number of buffers in the buffer manager. However, in the interface, the constructor of the buffer manager, there's an argument for the size of "this" buffer manager. How should this interplay work?
Answer: NUFBUF is the default number of buffer frames. A user might not specify a buffer pool size, in which case NUMBUF frames are created. Else, the size of the buffer pool is the value specified in the constructor.

Question: When I run my program, it gives the error "Error creating MINIBASE.DB ...". This is not our code at all - so what is going wrong?
Answer: Check your pin/unpin code. When the database is first initialized (see db.cpp), it pins page 0, and then unpins it. If there is an error in either of these routines, you will get this error.

Question: If my implementation successfully passes all the test cases provided to us, will I get full points for my implementation?
Answer: Not necessarily. The test cases provided to you are only indicative of the actual test cases that the TAs will use to grade your assignment. So, the only way to ensure that you get full points is by making sure that your code meets all the desired specifications, and will work for *all possible* test cases. Of course, your coding style, documentation, and analysis of the replacement policies will also contribute to your overall grade.

Hash Table

Question: I was wondering about what data structure to use to implement the buffer.
Answer: For quick (constant time) lookup to check whether a PID exists in the buffer pool, you should implement a small hash table yourself. To handle overflows, you can use a technique such as chaining to store overflow buckets.

Question: How many regular (non-overflow) buckets should the hash table have?
Answer: In general, the number of buckets in your hash table should be greater than NUMBUF. Setting the number of buckets to 1.25 * NUMBUF will avoid collisions in most cases.

Question: What hash function should I use?
Answer: You can use any standard hash function described in any data structures textbook.

Replacement Policies

Question: Should I invoke the page replacement policy when the buffer pool has empty frames?
Answer: No. Keep a list of empty buffer frames, and invoke the replacement policy only when this list is empty.

Question: I was wondering if the MRU algorithm should compare the referenced time based on seconds or milliseconds.
Answer: For MRU, don't use a timestamp. Just keep a linked list, and whenever a page is unpinned (and its pin count is zero), put it at the front of the list. Then replace from the front of the list.

Question: About the Clock replacement policy... The book says that there is a "referenced" variable for each frame, which is set to "on" when pin# becomes 0, and this is to indicated that the frame is recently referenced. Then when the "current" hits that frame, it'll set "reference" to "off", and "current" will increment. Furthermore, it is declared that there are no frames available for replacement if "current" completes a cycle. So my question is, what if every frame has its pin>0 except one, but that frame was recently referenced (ie. "reference" = on)? Then when "current" reaches that frame, it'll turn its "reference" off and keep going. But since every other frame has pin>0, it'll loop back to its original position and declare that there is no available frame. BUT, there is an available frame, namely the one that just had its reference set to off. So it seems like "current" will have to loop through the clock twice. Is that true?
Answer: Yes, the "current" will loop around twice

Question: Should my statistics for the MRU replacement policy exactly match the statistics in the model solution?
Answer: Yes.

Question: Should my statistics for the CLOCK replacement policy exactly match the statistics in the model solution?
Answer: Not necessarily. The statistics for the CLOCK replacement policy may be implementation-dependent. However, it is your responsibility to ensure that your implementation is correct. To standardize your implementation somewhat, make sure that your CLOCK pointer points to buffer frame 0 on initialization.

FlushPage() and FlushAllPages()

Question: What does BufMgr::FlushPage() do if the page is unpinned (pincount = 0)?
Answer: It flushes the page to disk if the page is dirty. It then marks the corresponding buffer frame as empty.

Question: What does BufMgr::FlushPage do if the page is pinned (pincount >= 1)?
Answer: It still flushes the page to disk if the page is dirty. However, it *does not* mark the corresponding buffer frame as empty. The function also returns FAIL to signal an error.

Question: What does BufMgr::FlushAllPages do if there are some pages that are pinned?
Answer: It flushes *all* pages, and marks *all* buffer frames (including those containing pinned pages) as empty. It also returns FAIL to signal an error.

Question: Can I call FlushPage from within FlushAllPages?
Answer: Yes, and you probably should (to avoid replicating code).

PinPage() and UnpinPage()

Question: What is the "isEmpty" flag good for in BufMgr::PinPage?
Answer: If (isEmpty==true), then don't read the page from disk. Check whether it is in the buffer pool, if not, then just return a pointer to a page in a frame selected by your replacement policy.

Question: In the function BufMgr::PinPage(PageID pid, Page*& page, bool isEmpty), what exactly happens if isEmpty is true? 
Answer: If isEmpty is true, you do not have to read the page from the disk, just assign it a buffer frame, because you assume that the page is empty. If the PID is the same as the PID of a non-empty page, that is the problem of the upper layer, and it will be overwritten at the time of unpinning the page with the new content. You do not have to worry about how the upper layer gets the PIDs that it requests.

FreePage()

Question: BufMgr::FreePage. In the comments for this function, in PostCond, it says : "Also the page is deallocated from the database. " What exactly does that mean?
Answer: It means that if FreePage does not fail, you have to call the following in the function somewhere: MINIBASE_DB->DeallocatePage(pid)

Question: In the FreePage(pid) function, do I remove the space where the page resided from the buffer manager?
Answer: No, you never remove space from the buffer manager. In the constructor of the buffer manager, you allocate the space for all the buffer frames, and they survive until the destructor of the buffer manager is called.

Question: For FreePage(pid), what happens if the frame in the buffer is dirty? Do we just ignore the changes made? 
Answer: Even if the page is dirty, the corresponding buffer frame is just marked empty, and the page is deallocated from the database. Thus any changes that happened prior to FreePage are lost.

Question: I fail to see the reason why it is ok to free the page if pincount<=1 but not ok when the pincount>1. 
Answer: If pin<=1, then the current user is freeing that page; otherwise there might be another reader who is currently accessing the page. Thus it is ok to free a page with pincount <= 1, but not if pincount > 2.

NewPage()

Question: For NewPage, is PID an output for the function?
Answer: Yes. You get the first of the new PIDs from the call to MINIBASE_DB->AllocatePage(pid, howMany). This call happens inside NewPage.

Question: In NewPage(... ), should I only insert the first of all the allocated pages into the buffer pool, pin it, and leave the rest of the new pages lying around?
Answer: Yes.

GetNumOfUnpinnedBuffers() and GetNumOfBuffers()

Question: What does BufMgr::GetNumOfUnpinnedBuffers() return?
Answer: It returns the number of unpinned buffer *frames*. BufMgr::GetNumOfBuffers() returns the total number of buffer frames.

GetNumOfUnpinnedBuffers() and GetNumOfBuffers()

Question: What does BufMgr::GetNumOfUnpinnedBuffers() return?
Answer: It returns the number of unpinned buffer *frames*. BufMgr::GetNumOfBuffers() returns the total number of buffer frames.