コード例 #1
0
  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;
  }
コード例 #2
0
  private RecordId getRecordId(int lineNo) throws IOException {
    RecordId id = null;
    Jedis jedis = pool_.getResource();
    try {
      int pageNo, slotNo;
      String lineNoStr = Integer.toString(lineNo);
      String pageNoStr = jedis.hget(lineNoStr, PAGE_NO_KEY);
      String slotNoStr = jedis.hget(lineNoStr, SLOT_NO_KEY);
      if (pageNoStr != null && slotNoStr != null) {
        id = new RecordId(Integer.parseInt(pageNoStr), Integer.parseInt(slotNoStr));
      } else { // Was not cached
        // Read directory page containing line in question
        byte[] buffer = new byte[BLOCK_SIZE];
        int absIndex = (lineNo - 1) * 2 * INT_SIZE;
        int relativeIndex = absIndex % BLOCK_SIZE;
        int bytesRead = 0;
        synchronized (mDirectoryFile) {
          mDirectoryFile.seek(absIndex - relativeIndex);
          bytesRead = mDirectoryFile.read(buffer);
        }
        ByteBuffer bb = ByteBuffer.wrap(buffer);

        // Cache all entries in the page
        int curLineNo = lineNo - relativeIndex / (2 * INT_SIZE);
        for (int i = 0; i < bytesRead / (2 * INT_SIZE); i++, curLineNo++) {
          pageNo = bb.getInt();
          slotNo = bb.getInt();
          if (curLineNo == lineNo) {
            id = new RecordId(pageNo, slotNo);
          }
          lineNoStr = Integer.toString(curLineNo);
          jedis.hset(lineNoStr, PAGE_NO_KEY, Integer.toString(pageNo));
          jedis.hset(lineNoStr, SLOT_NO_KEY, Integer.toString(slotNo));
        }
      }

      if (id == null) {
        throw new IOException("LineServer: Could not find record id in directory");
      }
    } finally {
      pool_.returnResource(jedis);
    }

    return id;
  }