Example #1
0
 private int scan() {
   int cnt = 0;
   for (int i = 0, len = _dataArray.length(); i < len; i++) {
     if (_dataArray.hasData(i)) cnt++;
   }
   return cnt;
 }
Example #2
0
  protected boolean putInternal(int index, byte[] key, byte[] value) throws Exception {
    byte[] existingData = _dataArray.get(index);
    if (existingData == null || existingData.length == 0) {
      _dataArray.set(index, _dataHandler.assemble(key, value), nextScn());
      _loadCount++;
    } else {
      try {
        _dataArray.set(index, _dataHandler.assemble(key, value, existingData), nextScn());
      } catch (Exception e) {
        _log.warn("Value reset at index=" + index + " key=\"" + new String(key) + "\"");
        _dataArray.set(index, _dataHandler.assemble(key, value), nextScn());
      }
    }

    return true;
  }
Example #3
0
  private void initLinearHashing() throws Exception {
    int unitCount = _dataArray.length() / getUnitCapacity();

    if (unitCount == 1) {
      _level = 0;
      _split = 0;
      _levelCapacity = getUnitCapacity();
      _levelThreshold = (int) (_levelCapacity * _loadThreshold);
    } else {
      // Determine level and split
      _level = 0;
      int remainder = (unitCount - 1) >> 1;
      while (remainder > 0) {
        _level++;
        remainder = remainder >> 1;
      }

      _split = (unitCount - (1 << _level) - 1) * getUnitCapacity();
      _levelCapacity = getUnitCapacity() * (1 << _level);
      _levelThreshold = (int) (_levelCapacity * _loadThreshold);

      // Need to re-populate the last unit
      for (int i = 0, cnt = getUnitCapacity(); i < cnt; i++) {
        split();
      }
    }
  }
Example #4
0
  @Override
  public byte[] get(byte[] key) {
    byte[] existingData;
    long hashCode = hash(key);

    /**
     * Need SPIN to retrieve data from the underlying array because the index might have changed
     * with the _split.
     */

    // Map key to an array index
    int index = getIndex(hashCode);

    do {
      // Read existing data at the index
      existingData = _dataArray.get(index);

      // Check that key is still mapped to the known index
      int indexNew = getIndex(hashCode);
      if (index == indexNew) break;
      else index = indexNew;
    } while (true);

    return existingData == null ? null : _dataHandler.extractByKey(key, existingData);
  }
Example #5
0
  protected synchronized void split() throws Exception {
    // Ensure address capacity
    _addrArray.expandCapacity(_split + _levelCapacity);

    // Read data from the _split index
    byte[] data = _dataArray.get(_split);

    // Process read data
    if (data != null && data.length > 0) {
      ByteBuffer bb = ByteBuffer.wrap(data);
      int newCapacity = _levelCapacity << 1;

      int cnt = bb.getInt();
      while (cnt > 0) {
        // Read key
        int len = bb.getInt();
        byte[] key = new byte[len];
        bb.get(key);

        int newIndex = (int) (hash(key) % newCapacity);
        if (newIndex < 0) newIndex = -newIndex;

        if (newIndex == _split) /* No need to split */ {
          // Pass value
          len = bb.getInt();
          bb.position(bb.position() + len);
        } else {
          // Read value
          len = bb.getInt();
          byte[] value = new byte[len];
          bb.get(value);

          // Remove at the old index
          deleteInternal(_split, key);

          // Update at the new index
          putInternal(newIndex, key, value);
        }

        cnt--;
      }
    }

    _split++;

    if (_split % _unitCapacity == 0) {
      _log.info("split " + getStatus());
    }

    if (_split == _levelCapacity) {
      _split = 0;
      _level++;
      _levelCapacity = getUnitCapacity() * (1 << _level);
      _levelThreshold = (int) (_levelCapacity * _loadThreshold);

      _log.info(getStatus());
    }
  }
Example #6
0
  private boolean deleteInternal(int index, byte[] key) throws Exception {
    try {
      byte[] existingData = _dataArray.get(index);
      if (existingData != null) {
        int newLength = _dataHandler.removeByKey(key, existingData);
        if (newLength == 0) {
          // entire data is removed
          _dataArray.set(index, null, nextScn());
          _loadCount--;
          return true;
        } else if (newLength < existingData.length) {
          // partial data is removed
          _dataArray.set(index, existingData, 0, newLength, nextScn());
          return true;
        }
      }
    } catch (Exception e) {
      _log.warn("Failed to delete key=\"" + new String(key) + "\" : " + e.getMessage());
      _dataArray.set(index, null, nextScn());
    }

    // no data is removed
    return false;
  }
Example #7
0
  private boolean putInternalNonColliding(int index, byte[] key, byte[] value) throws Exception {
    byte[] existingData = _dataArray.get(index);

    if (existingData == null) {
      return setInternal(index, key, value);
    }

    int collisionCnt = _dataHandler.countCollisions(key, existingData);
    if (collisionCnt == 0) {
      return setInternal(index, key, value);
    } else if (collisionCnt == 1) {
      return putReplace(index, key, value);
    } else {
      return false;
    }
  }
Example #8
0
  private byte[] getInternal(Tier tier, long hashCode) {
    byte[] existingData;

    /**
     * Need SPIN to retrieve data from the underlying array because the index might have changed
     * with the _split.
     */

    // Map key to an array index
    int index = tier.getMainIndex(hashCode, _level, _split);

    do {
      // Read existing data at the index
      existingData = _dataArray.get(index);

      // Check that key is still mapped to the known index
      int indexNew = tier.getMainIndex(hashCode, _level, _split);
      if (indexNew == index) break;
      index = indexNew;
    } while (true);

    return existingData;
  }
Example #9
0
  protected synchronized void split() throws Exception {
    // Ensure address capacity
    _addrArray.expandCapacity(_split + _levelCapacity);

    // Read data from the _split index
    byte[] data = _dataArray.get(_split);

    // Process read data
    if (data != null && data.length > 0) {
      // Get split tier
      Tier tier = getTier(_split);

      // Wrap data in byte buffer
      ByteBuffer bb = ByteBuffer.wrap(data);

      int cnt = bb.getInt();

      if (tier.isColliding()) {
        while (cnt > 0) {
          // Read key
          int len = bb.getInt();
          byte[] key = new byte[len];
          bb.get(key);

          int newIndex = tier.getSplitIndex(hash(key), _level, _split);
          if (newIndex == _split) /* No need to split */ {
            // Pass value
            len = bb.getInt();
            bb.position(bb.position() + len);
          } else {
            // Read value
            len = bb.getInt();
            byte[] value = new byte[len];
            bb.get(value);

            // Remove at the old index
            deleteInternal(_split, key);

            // Update at the new index
            putInternal(newIndex, key, value);
          }

          cnt--;
        }
      } else {
        // Read key
        int len = bb.getInt();
        byte[] key = new byte[len];
        bb.get(key);

        int newIndex = tier.getSplitIndex(hash(key), _level, _split);
        if (newIndex != _split) {
          long scn = nextScn();
          _addrArray.set(newIndex, _addrArray.get(_split), scn);
          _addrArray.set(_split, 0, scn);
        }
      }
    }

    _split++;

    if (_split % _unitCapacity == 0) {
      _log.info("split " + getStatus());
    }

    if (_split == _levelCapacity) {
      _split = 0;
      _level++;
      _levelCapacity = getUnitCapacity() * (1 << _level);
      _levelThreshold = (int) (_levelCapacity * _loadThreshold);

      _log.info(getStatus());
    }
  }
Example #10
0
 public final int getCapacity() {
   return _dataArray.length();
 }
Example #11
0
 private boolean putReplace(int index, byte[] key, byte[] value) throws Exception {
   _dataArray.set(index, _dataHandler.assemble(key, value), nextScn());
   return true;
 }
Example #12
0
 private boolean setInternal(int index, byte[] key, byte[] value) throws Exception {
   _dataArray.set(index, _dataHandler.assemble(key, value), nextScn());
   _loadCount++;
   return true;
 }
Example #13
0
 @Override
 public synchronized void clear() throws IOException {
   _dataArray.clear();
   _loadCount = 0;
 }
Example #14
0
 @Override
 public void persist() throws IOException {
   _dataArray.persist();
 }
Example #15
0
 @Override
 public void sync() throws IOException {
   _dataArray.sync();
 }