public String getLine(int lineNo) throws Exception {
    if (lineNo <= 0 || lineNo > mNumLines) {
      return null;
    }

    String line = null;
    Jedis jedis = pool_.getResource();
    try {
      String lineNoStr = Integer.toString(lineNo);
      line = jedis.hget(lineNoStr, LINE_KEY);
      if (line == null) {
        RecordId lineId = getRecordId(lineNo);

        byte[] buffer = new byte[BLOCK_SIZE];
        synchronized (mDataFile) {
          mDataFile.seek(lineId.pageNo() * BLOCK_SIZE);
          mDataFile.read(buffer);
        }
        ByteBuffer bb = ByteBuffer.wrap(buffer);

        int numRecords = bb.getInt(BLOCK_SIZE - INT_SIZE);
        int indexPos = BLOCK_SIZE - 3 * INT_SIZE;
        int curLineNo = lineNo - lineId.slotNo() + 1;
        String[] recordKeys = {PAGE_NO_KEY, SLOT_NO_KEY};
        for (int i = 1; i < numRecords; i++, curLineNo++) {
          int offset = bb.getInt(indexPos);
          int len = bb.getInt(indexPos + INT_SIZE);

          ByteBuffer linebb = ByteBuffer.wrap(buffer, offset, len);
          byte[] lineBuf = new byte[linebb.remaining()];
          linebb.get(lineBuf);
          String lineStr = new String(lineBuf);

          if (i == lineId.slotNo()) {
            line = lineStr;
          }

          // Store in cache
          lineNoStr = Integer.toString(curLineNo);
          jedis.hdel(lineNoStr, recordKeys);
          jedis.hset(lineNoStr, LINE_KEY, lineStr);
          indexPos -= 2 * INT_SIZE;
        }
      }

      if (line == null) {
        throw new Exception("LineServer: Could not find line on page");
      }
    } catch (IOException ioe) {
      System.err.println("LineServer: IOException on line retrieval");
      throw ioe;
    } finally {
      pool_.returnResource(jedis);
    }

    return line;
  }
 /**
  * Delete the specified tuple from the page; the tuple should be updated to reflect that it is no
  * longer stored on any page.
  *
  * @throws DbException if this tuple is not on this page, or tuple slot is already empty.
  * @param t The tuple to delete
  */
 public void deleteTuple(Tuple t) throws DbException {
   // some code goes here
   // not necessary for lab1
   RecordId targetrid = t.getRecordId();
   int tslotnum = targetrid.tupleno();
   if (!targetrid.getPageId().equals(pid) || !isSlotUsed(tslotnum)) {
     throw new DbException("Either wrong page number or requested tuple didn't exist");
   }
   markSlotUsed(tslotnum, false);
   tuples[tslotnum] = null;
 }
 // see DbFile.java for javadocs
 public Page deleteTuple(TransactionId tid, Tuple t)
     throws DbException, TransactionAbortedException {
   // some code goes here
   BufferPool bp = Database.getBufferPool();
   RecordId rid = t.getRecordId();
   if (rid == null) {
     throw new DbException("Tuple is not a member of this file");
   }
   HeapPage p = (HeapPage) bp.getPage(tid, rid.getPageId(), Permissions.READ_WRITE);
   p.deleteTuple(t);
   return p;
 }