00001 00008 #pragma once 00009 00010 #include <cassert> 00011 #include "file.h" 00012 #include "page.h" 00013 #include "types.h" 00014 00015 namespace wiscdb { 00016 00023 class PageIterator { 00024 public: 00028 PageIterator() 00029 : page_(NULL) { 00030 current_record_ = {Page::INVALID_NUMBER, Page::INVALID_SLOT}; 00031 } 00032 00039 PageIterator(Page* page) 00040 : page_(page) { 00041 assert(page_ != NULL); 00042 const SlotId used_slot = getNextUsedSlot(Page::INVALID_SLOT /* start */); 00043 current_record_ = {page_->page_number(), used_slot}; 00044 } 00045 00053 PageIterator(Page* page, const RecordId& record_id) 00054 : page_(page), 00055 current_record_(record_id) { 00056 } 00057 00061 inline PageIterator& operator++() { 00062 assert(page_ != NULL); 00063 const SlotId used_slot = getNextUsedSlot(current_record_.slot_number); 00064 current_record_ = {page_->page_number(), used_slot}; 00065 00066 return *this; 00067 } 00068 00069 inline PageIterator operator++(int) { 00070 PageIterator tmp = *this; // copy ourselves 00071 00072 assert(page_ != NULL); 00073 const SlotId used_slot = getNextUsedSlot(current_record_.slot_number); 00074 current_record_ = {page_->page_number(), used_slot}; 00075 00076 return tmp; 00077 } 00084 inline bool operator==(const PageIterator& rhs) const { 00085 return page_->page_number() == rhs.page_->page_number() && 00086 current_record_ == rhs.current_record_; 00087 } 00088 00089 inline bool operator!=(const PageIterator& rhs) const { 00090 return (page_->page_number() != rhs.page_->page_number()) || 00091 (current_record_ != rhs.current_record_); 00092 } 00093 00100 inline std::string operator*() const { 00101 return page_->getRecord(current_record_); 00102 } 00103 00111 SlotId getNextUsedSlot(const SlotId start) const { 00112 SlotId slot_number = Page::INVALID_SLOT; 00113 for (SlotId i = start + 1; i <= page_->header_.num_slots; ++i) { 00114 const PageSlot* slot = page_->getSlot(i); 00115 if (slot->used) { 00116 slot_number = i; 00117 break; 00118 } 00119 } 00120 return slot_number; 00121 } 00122 00123 RecordId getCurrentRecord() 00124 { 00125 return current_record_; 00126 } 00127 00128 private: 00132 Page* page_; 00133 00137 RecordId current_record_; 00138 00139 //FRIEND_TEST(PageTest, GetNextUsedSlot); 00140 //FRIEND_TEST(BufferTest, GetNextUsedSlot); 00141 }; 00142 00143 }