public boolean hasNext() throws DbException, TransactionAbortedException, IOException {
    // System.out.println("hf has next: " + _currentPageId +_numPages);
    if (_tupleIterator == null) return false;
    if (_tupleIterator.hasNext()) return true;

    // If we have more pages
    // System.out.println(_currentPageId+"   llllll   "+_numPages);
    while (_currentPageId < (_numPages)) {
      _currentPage = readPage(_currentPageId++);
      _tupleIterator = _currentPage.iterator();
      if (_tupleIterator.hasNext()) {
        _pagesRead++;
        return true;
      }
    }

    return false;
  }
  public Tuple previous() throws DbException, TransactionAbortedException, IOException {
    //	System.out.println("previous ");
    if (_tupleIterator == null) {
      throw new NoSuchElementException("Tuple iterator not opened");
    }

    if (((HeapPageIterator) _tupleIterator).hasPrevious()) {
      return ((HeapPageIterator) _tupleIterator).previous();
    } else {
      if (_currentPageId > 1) {
        // System.out.println("CUURENT PAGEID "+_currentPageId);
        _currentPageId = _currentPageId - 2;
        _currentPage = readPage(_currentPageId++);
        // System.out.println("NOW "+_currentPageId);
        _pagesRead++;
        _tupleIterator = _currentPage.iterator();
        ((HeapPageIterator) _tupleIterator).setLast();
        if (((HeapPageIterator) _tupleIterator).hasPrevious()) {
          return ((HeapPageIterator) _tupleIterator).previous();
        }
      } else return null;
    }
    return null;
  }
  public void open() throws DbException, TransactionAbortedException, IOException {
    _currentPage = readPage(_currentPageId++);

    _pagesRead++;
    _tupleIterator = _currentPage.iterator();
  }