示例#1
0
    def read_page(self, range_type: str, page_index: int, column: int) -> Page:
        file, size = self.__open_file(column, range_type)

        # checks if the file needs to be enlarged
        if page_index >= size // PAGESIZE:
            file.seek(0, SEEK_END)
            new_page = Page(range_type=range_type)
            # doubles the size of the file
            new_bytes = new_page.data * (page_index + 1)
            file.write(new_bytes)

        # reads specified page
        file.seek(page_index * PAGESIZE)
        return Page(data=file.read(PAGESIZE))
示例#2
0
    def load_page_from_disk(self, table_name, address):
        if (self.bufferpool.is_full()):
            # evict page and flush it to disk if dirty
            evict_page = self.bufferpool.evict()
            while (len(evict_page) == 0):
                evict_page = self.bufferpool.evict()
            if (evict_page[1].dirty):
                self.flush_page(evict_page)

        # then locate page from disk and copy, save in Page() object, then add to buffer pool
        if table_name not in self.active_table_indexes:
            self.load_index_from_disk(
                table_name)  # load the table's index from file into memory
        table_index = self.active_table_indexes[table_name]
        file_offset = table_index[(address.pagerange,
                                   address.page)][FILE_OFFSET]
        num_records = table_index[(address.pagerange,
                                   address.page)][NUM_RECORDS]
        filename = self.directory_path + table_name + BIN_EXTENSION  # file for table data
        with open(filename, "rb") as file:
            file.seek(file_offset)
            page_bytes = file.read(PAGESIZE)
            page_copy = Page(page_bytes, num_records)
            #page_copy = Page(page_bytes)
            self.bufferpool.add_page(table_name, address, page_copy)
    def create_empty_pages_bp(self, num_cols, start_range, page_flag):
        list_page_ids = []
        for i in range(num_cols):
            if self.bp.size == self.bp_capacity:
                self.evict_page()
            if page_flag == BASE_FLAG:
                self.bp.appendleft(Page(init.CURR_BASE_PAGE_ID))
                list_page_ids.append(init.CURR_BASE_PAGE_ID)
                init.CURR_BASE_PAGE_ID += 1
            else:
                self.bp.appendleft(Page(init.CURR_TAIL_PAGE_ID))
                list_page_ids.append(init.CURR_TAIL_PAGE_ID)
                init.CURR_TAIL_PAGE_ID -= 1

        if page_flag == BASE_FLAG:
            self.page_directory[start_range][0][NUM_BASE] += 1
        else:
            self.page_directory[start_range][0][NUM_TAIL] += 1

        self.page_directory[start_range].append(list_page_ids)
示例#4
0
 def _convert_bytes_to_page(cls, columns, metadata_bytes, data_bytes):
     lst_page = []
     for i in range(columns):
         if i < METADATA_COLUMN_COUNT:
             bytes_of_page = cls._bytes_of_pages(i, metadata_bytes)
         else:
             bytes_of_page = cls._bytes_of_pages(i - METADATA_COLUMN_COUNT,
                                                 data_bytes)
         page = Page.new_page_from_bytes(bytes_of_page)
         lst_page.append(page)
     return lst_page
示例#5
0
    def new_page(self, table_name, address, column_index):
        lstore.globals.access.acquire()
        filename = self.directory_path + table_name + BIN_EXTENSION  # file for table data
        orig_filesize = os.path.getsize(filename)
        total_columns = int(self.active_table_metadata[table_name]
                            [COLUMNS]) + NUM_METADATA_COLUMNS
        column_set_size = COLUMN_BLOCK_BYTES * total_columns
        file_offset = orig_filesize - column_set_size + (COLUMN_BLOCK_BYTES *
                                                         column_index)

        with open(filename, "r+b") as file:
            block_full = True
            for i in range(COLUMN_BLOCK_PAGES):
                file.seek(file_offset)
                page_TPS = int.from_bytes(file.read(DATASIZE),
                                          byteorder='big',
                                          signed=False)
                if (page_TPS == 0):
                    block_full = False
                    break
                file_offset += PAGESIZE
            if (block_full):
                # append whitespace for new set of column blocks to end of file here
                file.seek(orig_filesize)
                file.write(bytearray(column_set_size))
                file_offset = orig_filesize + (
                    COLUMN_BLOCK_BYTES * column_index
                )  # reset file_offset to start of column block to modify
            # write the TPS = 2^64 - 1 for first entry in the new page, for each column block
            # at the same time, add page mapping to table index
            init_TPS = 2**64 - 1
            init_TPS_bytes = init_TPS.to_bytes(8, byteorder="big")
            table_index = self.active_table_indexes[table_name]
            file.seek(
                file_offset)  # reset file position to start of blank page slot
            file.write(init_TPS_bytes)  # write TPS number
            # add to table index the mapping from conceptual address to file offset + num_records
            # -- note that num_records is initially 1 because the TPS is first data entry
            table_index[(address.pagerange, address.page)] = [file_offset, 1]
            # also load the new page into bufferpool, checking first if bufferpool needs to evict a page
            if (self.bufferpool.is_full()):
                # evict page and flush it to disk if dirty
                evict_page = self.bufferpool.evict()
                while (len(evict_page) == 0):
                    evict_page = self.bufferpool.evict()
                if (evict_page[1].dirty):
                    self.flush_page(evict_page)
            in_memory_pg = Page()
            self.bufferpool.add_page(table_name, address, in_memory_pg)
        lstore.globals.access.release()
        return file_offset
    def add_range(self, name, page_slot):
        curr_table = self.db.get_table(name)
        new_range = []

        for column_index in range(lstore.config.Offset +
                                  curr_table.num_columns):
            new_page = Page()
            new_range.append(new_page)

        if self.must_evict(
        ):  #need to evict a page to add the new range from memory
            frame_num = self.evict(name)
            self.frame_map[page_slot] = frame_num
            self.page_map[frame_num] = new_range
            self.accesses[
                frame_num] += 1  #increase num accesses for this frame
        else:  #space in the buffer pool to add a new range from memory
            self.frame_map[page_slot] = len(self.page_map)
            self.page_map[self.frame_map[page_slot]] = new_range
            self.accesses[self.frame_map[
                page_slot]] += 1  #increase num accesses for this frame
示例#7
0
 def __init__(self, num_columns):
     self._pages = []
     self.num_columns = num_columns + METADATA_COLUMN_COUNT
     for i in range(self.num_columns):
         self._pages.append(Page())
     self.is_dirty = False