예제 #1
0
 public static String getVersionKeysFromMap(Map<Number640, Data> dataMap) {
   String result = "";
   for (Number640 key : dataMap.keySet()) {
     result += key.versionKey() + " ";
   }
   return result;
 }
예제 #2
0
 public void checkTimeout() {
   long time = System.currentTimeMillis();
   Collection<Number640> toRemove = backend.subMapTimeout(time);
   for (Number640 key : toRemove) {
     RangeLock<Number640>.Range lock = lock(key);
     try {
       Data oldData = backend.remove(key, false);
       if (oldData != null) {
         oldData.release();
       }
       backend.removeTimeout(key);
       // remove responsibility if we don't have any data stored under
       // locationkey
       Number160 locationKey = key.locationKey();
       RangeLock<Number640>.Range lockResp = lockResponsibility(locationKey);
       try {
         if (isEmpty(locationKey)) {
           backend.removeResponsibility(locationKey);
         }
       } finally {
         lockResp.unlock();
       }
     } finally {
       lock.unlock();
     }
   }
 }
예제 #3
0
  public NavigableMap<Number640, Data> removeReturnData(
      Number640 from, Number640 to, PublicKey publicKey) {
    RangeLock<Number640>.Range lock = rangeLock.lock(from, to);
    try {
      Map<Number640, Data> tmp = backend.subMap(from, to);
      NavigableMap<Number640, Data> result = new TreeMap<Number640, Data>();

      for (Number640 key : tmp.keySet()) {
        // fail fast, as soon as we want to remove 1 domain that we
        // cannot, abort
        if (!canClaimDomain(key.locationAndDomainKey(), publicKey)) {
          result.put(key, null);
        } else if (!canClaimEntry(key.locationAndDomainAndContentKey(), publicKey)) {
          result.put(key, null);
        } else {
          Data toRemove = backend.get(key);
          if (toRemove != null
              && (toRemove.publicKey() == null || toRemove.publicKey().equals(publicKey))) {
            backend.removeTimeout(key);
            Data removed = backend.remove(key, true);
            result.put(key, removed);
          }
        }
      }
      return result;
    } finally {
      lock.unlock();
    }
  }
예제 #4
0
 public NavigableMap<Number640, Data> getLatestVersion(Number640 key) {
   RangeLock<Number640>.Range lock = lock(key.locationAndDomainAndContentKey());
   try {
     NavigableMap<Number640, Data> tmp = backend.subMap(key.minVersionKey(), key.maxVersionKey());
     tmp = filterCopyOrig(tmp, -1, true);
     return getLatestInternal(tmp);
   } finally {
     lock.unlock();
   }
 }
예제 #5
0
  public Enum<?> putConfirm(PublicKey publicKey, Number640 key, Data newData) {
    RangeLock<Number640>.Range lock = lock(key);
    try {
      if (!securityEntryCheck(
          key.locationAndDomainAndContentKey(),
          publicKey,
          newData.publicKey(),
          newData.isProtectedEntry())) {
        return PutStatus.FAILED_SECURITY;
      }

      final Data data = backend.get(key);
      if (data != null) {
        // remove prepare flag
        data.prepareFlag(false);

        data.validFromMillis(newData.validFromMillis());
        data.ttlSeconds(newData.ttlSeconds());

        long expiration = data.expirationMillis();
        // handle timeout
        backend.addTimeout(key, expiration);
        backend.put(key, data);
        // don't release data as we just update
        return PutStatus.OK;
      } else {
        return PutStatus.NOT_FOUND;
      }
    } finally {
      newData.release();
      lock.unlock();
    }
    // TODO: check for FORKS!
  }
예제 #6
0
  public boolean remove(Number640 key) {
    long startTime = System.currentTimeMillis();
    FutureRemove remove =
        peerDHT
            .remove(key.locationKey())
            .contentKey(key.contentKey())
            .domainKey(key.domainKey())
            .versionKey(key.versionKey())
            .routingConfiguration(routingConfig)
            .requestP2PConfiguration(requestConfig)
            .start()
            .awaitUninterruptibly();
    putStats.report(System.currentTimeMillis() - startTime, remove.isSuccess());
    LOG.debug("Remove is success {}. Reason: {}", remove.isSuccess(), remove.failedReason());

    return remove.isSuccess();
  }
예제 #7
0
  public Data get(Number640 key) {
    long startTime = System.currentTimeMillis();
    FutureGet futureGet =
        peerDHT
            .get(key.locationKey())
            .contentKey(key.contentKey())
            .domainKey(key.domainKey())
            .versionKey(key.versionKey())
            .routingConfiguration(routingConfig)
            .requestP2PConfiguration(requestConfig)
            .start()
            .awaitUninterruptibly();
    putStats.report(System.currentTimeMillis() - startTime, futureGet.isSuccess());
    LOG.debug("Get is success {}. Reason: {}", futureGet.isSuccess(), futureGet.failedReason());

    if (futureGet.data() != null) {
      return futureGet.data();
    } else {
      return null;
    }
  }
예제 #8
0
  public boolean put(Number640 key) {
    Data data = generateRandomData();
    long startTime = System.currentTimeMillis();
    FuturePut futurePut =
        peerDHT
            .put(key.locationKey())
            .domainKey(key.domainKey())
            .versionKey(key.versionKey())
            .data(key.contentKey(), data)
            .routingConfiguration(routingConfig)
            .requestP2PConfiguration(requestConfig)
            .start()
            .awaitUninterruptibly();
    putStats.report(System.currentTimeMillis() - startTime, futurePut.isSuccess());

    LOG.debug(
        "Put of {} bytes is success = {}. Reason: {}",
        data.length(),
        futurePut.isSuccess(),
        futurePut.failedReason());
    return futurePut.isSuccess();
  }
예제 #9
0
 public Pair<Data, Enum<?>> remove(Number640 key, PublicKey publicKey, boolean returnData) {
   RangeLock<Number640>.Range lock = lock(key);
   try {
     if (!canClaimDomain(key.locationAndDomainKey(), publicKey)) {
       return new Pair<Data, Enum<?>>(null, PutStatus.FAILED_SECURITY);
     }
     if (!canClaimEntry(key.locationAndDomainAndContentKey(), publicKey)) {
       return new Pair<Data, Enum<?>>(null, PutStatus.FAILED_SECURITY);
     }
     if (!backend.contains(key)) {
       return new Pair<Data, Enum<?>>(null, PutStatus.NOT_FOUND);
     }
     backend.removeTimeout(key);
     Data removed = backend.remove(key, returnData);
     if (removed != null && !returnData) {
       removed.release();
     }
     // else -> it will be removed in the encoder
     return new Pair<Data, Enum<?>>(removed, PutStatus.OK);
   } finally {
     lock.unlock();
   }
 }
예제 #10
0
 // iterative version
 private NavigableMap<Number640, Data> deletePredecessors(
     Number640 key, NavigableMap<Number640, Data> sortedMap) {
   final List<Number640> toRemove = new ArrayList<Number640>();
   final NavigableMap<Number640, Data> removed = new TreeMap<Number640, Data>();
   toRemove.add(key);
   while (!toRemove.isEmpty()) {
     final Number640 key2 = toRemove.remove(0);
     final Data version = sortedMap.remove(key2);
     if (version != null) {
       removed.put(key2, version);
       // check if version has been already deleted && // check if version is initial version
       if (!version.basedOnSet().isEmpty()) {
         for (final Number160 basedOnKey : version.basedOnSet()) {
           toRemove.add(new Number640(key.locationAndDomainAndContentKey(), basedOnKey));
         }
       }
     }
   }
   return removed;
 }
예제 #11
0
  public Enum<?> updateMeta(PublicKey publicKey, Number640 key, Data newData) {
    RangeLock<Number640>.Range lock = lock(key);
    try {
      if (!securityEntryCheck(
          key.locationAndDomainAndContentKey(),
          publicKey,
          newData.publicKey(),
          newData.isProtectedEntry())) {
        return PutStatus.FAILED_SECURITY;
      }

      final Data data = backend.get(key);
      boolean changed = false;
      if (data != null && newData.publicKey() != null) {
        data.publicKey(newData.publicKey());
        changed = true;
      }
      if (data != null && newData.isSigned()) {
        data.signature(newData.signature());
        changed = true;
      }
      if (data != null) {
        data.validFromMillis(newData.validFromMillis());
        data.ttlSeconds(newData.ttlSeconds());
        changed = true;
      }
      if (changed) {
        long expiration = data.expirationMillis();
        // handle timeout
        backend.addTimeout(key, expiration);
        // no release of old data, as we just update it
        backend.put(key, data);
        return PutStatus.OK;
      } else {
        return PutStatus.NOT_FOUND;
      }
    } finally {
      newData.release();
      lock.unlock();
    }
  }
예제 #12
0
  public Map<Number640, Enum<?>> putAll(
      final NavigableMap<Number640, Data> dataMap,
      PublicKey publicKey,
      boolean putIfAbsent,
      boolean domainProtection,
      boolean sendSelf) {
    if (dataMap.isEmpty()) {
      return Collections.emptyMap();
    }
    final Number640 min = dataMap.firstKey();
    final Number640 max = dataMap.lastKey();
    final Map<Number640, Enum<?>> retVal = new HashMap<Number640, Enum<?>>();
    final HashSet<Number480> keysToCheck = new HashSet<Number480>();
    final RangeLock<Number640>.Range lock = lock(min, max);
    try {
      for (Map.Entry<Number640, Data> entry : dataMap.entrySet()) {
        Number640 key = entry.getKey();
        keysToCheck.add(key.locationAndDomainAndContentKey());
        Data newData = entry.getValue();
        if (!securityDomainCheck(
            key.locationAndDomainKey(), publicKey, publicKey, domainProtection)) {
          retVal.put(key, PutStatus.FAILED_SECURITY);
          newData.release();
          continue;
        }

        // We need this check in case we did not use the encoder/decoder,
        // which is the case if we send the message to ourself. In that
        // case, the public key of the data is never set to the message
        // publick key, if the publick key of the data was null.
        final PublicKey dataKey;
        if (sendSelf && newData.publicKey() == null) {
          dataKey = publicKey;
        } else {
          dataKey = newData.publicKey();
        }

        if (!securityEntryCheck(
            key.locationAndDomainAndContentKey(), publicKey, dataKey, newData.isProtectedEntry())) {
          retVal.put(key, PutStatus.FAILED_SECURITY);
          newData.release();
          continue;
        }

        final Data oldDataGet = backend.get(key);
        if (oldDataGet != null) {
          if (putIfAbsent) {
            retVal.put(key, PutStatus.FAILED_NOT_ABSENT);
            newData.release();
            continue;
          }

          if (oldDataGet.isDeleted()) {
            retVal.put(key, PutStatus.DELETED);
            newData.release();
            continue;
          }
          if (!oldDataGet.basedOnSet().equals(newData.basedOnSet())) {
            retVal.put(key, PutStatus.VERSION_FORK);
            newData.release();
            continue;
          }
        }

        final Data oldDataPut = backend.put(key, newData);

        long expiration = newData.expirationMillis();
        // handle timeout
        backend.addTimeout(key, expiration);

        if (newData.hasPrepareFlag()) {
          retVal.put(key, PutStatus.OK_PREPARED);
        } else {
          retVal.put(key, PutStatus.OK);
        }
        if (oldDataPut != null && oldDataPut != newData) {
          oldDataPut.release();
        }
      }

      for (Number480 key : keysToCheck) {

        // now check for forks
        Number640 minVersion = new Number640(key, Number160.ZERO);
        Number640 maxVersion = new Number640(key, Number160.MAX_VALUE);
        NavigableMap<Number640, Data> tmp = backend.subMap(minVersion, maxVersion);
        tmp = filterCopyOrig(tmp, -1, true);
        NavigableMap<Number640, Data> heads = getLatestInternalOrig(tmp);

        final boolean forked = heads.size() > 1;
        for (final Map.Entry<Number640, Data> entry : heads.entrySet()) {
          if (forked) {
            if (retVal.containsKey(entry.getKey())) {
              retVal.put(entry.getKey(), PutStatus.VERSION_FORK);
            }
          }
        }

        // now remove old versions
        if (maxVersions > 0) {
          NavigableMap<Number640, Data> versions = backend.subMap(minVersion, maxVersion);

          while (!versions.isEmpty()
              && versions.firstKey().versionKey().timestamp() + maxVersions
                  <= versions.lastKey().versionKey().timestamp()) {
            Map.Entry<Number640, Data> entry = versions.pollFirstEntry();
            Data removed = backend.remove(entry.getKey(), true);
            if (removed != null) {
              removed.release();
            }
            backend.removeTimeout(entry.getKey());
          }
        }
      }
      return retVal;

    } finally {
      lock.unlock();
    }
  }