示例#1
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();
    }
  }
示例#2
0
 private boolean isEmpty(Number160 locationKey) {
   Number640 from = new Number640(locationKey, Number160.ZERO, Number160.ZERO, Number160.ZERO);
   Number640 to =
       new Number640(locationKey, Number160.MAX_VALUE, Number160.MAX_VALUE, Number160.MAX_VALUE);
   Map<Number640, Data> tmp = backend.subMap(from, to);
   return tmp.size() == 0;
 }
示例#3
0
  public NavigableMap<Number640, Data> get(
      Number640 from,
      Number640 to,
      SimpleBloomFilter<Number160> contentKeyBloomFilter,
      SimpleBloomFilter<Number160> versionKeyBloomFilter,
      SimpleBloomFilter<Number160> contentBloomFilter,
      int limit,
      boolean ascending,
      boolean isBloomFilterAnd) {
    RangeLock<Number640>.Range lock = rangeLock.lock(from, to);
    try {
      NavigableMap<Number640, Data> tmp = backend.subMap(from, to);
      tmp = filterCopy(tmp, limit, ascending);
      Iterator<Map.Entry<Number640, Data>> iterator = tmp.entrySet().iterator();

      while (iterator.hasNext()) {
        Map.Entry<Number640, Data> entry = iterator.next();

        if (isBloomFilterAnd) {
          if (!contentKeyBloomFilter.contains(entry.getKey().contentKey())) {
            entry.getValue().release();
            iterator.remove();
            continue;
          }
          if (!versionKeyBloomFilter.contains(entry.getKey().versionKey())) {
            entry.getValue().release();
            iterator.remove();
            continue;
          }
          if (!contentBloomFilter.contains(entry.getValue().hash())) {
            entry.getValue().release();
            iterator.remove();
            continue;
          }
        } else {
          if (contentKeyBloomFilter.contains(entry.getKey().contentKey())) {
            entry.getValue().release();
            iterator.remove();
            continue;
          }
          if (versionKeyBloomFilter.contains(entry.getKey().versionKey())) {
            entry.getValue().release();
            iterator.remove();
            continue;
          }
          if (contentBloomFilter.contains(entry.getValue().hash())) {
            entry.getValue().release();
            iterator.remove();
            continue;
          }
        }
      }

      return tmp;
    } 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 NavigableMap<Number640, Data> get(
     Number640 from, Number640 to, int limit, boolean ascending) {
   RangeLock<Number640>.Range lock = rangeLock.lock(from, to);
   try {
     NavigableMap<Number640, Data> tmp = backend.subMap(from, to);
     tmp = filterCopy(tmp, limit, ascending);
     return tmp;
   } finally {
     lock.unlock();
   }
 }
示例#6
0
 /* (non-Javadoc)
  * @see net.tomp2p.dht.DigestStorage#digest(net.tomp2p.peers.Number640, net.tomp2p.peers.Number640, int, boolean)
  */
 @Override
 public DigestInfo digest(Number640 from, Number640 to, int limit, boolean ascending) {
   DigestInfo digestInfo = new DigestInfo();
   RangeLock<Number640>.Range lock = rangeLock.lock(from, to);
   try {
     NavigableMap<Number640, Data> tmp = backend.subMap(from, to);
     tmp = filterCopyOrig(tmp, limit, ascending);
     for (Map.Entry<Number640, Data> entry : tmp.entrySet()) {
       if (!entry.getValue().hasPrepareFlag()) {
         digestInfo.put(entry.getKey(), entry.getValue().basedOnSet());
       }
     }
     return digestInfo;
   } finally {
     lock.unlock();
   }
 }
示例#7
0
 public SortedMap<Number640, Byte> removeReturnStatus(
     Number640 from, Number640 to, PublicKey publicKey) {
   RangeLock<Number640>.Range lock = rangeLock.lock(from, to);
   try {
     Map<Number640, Data> tmp = backend.subMap(from, to);
     SortedMap<Number640, Byte> result = new TreeMap<Number640, Byte>();
     for (Number640 key : tmp.keySet()) {
       Pair<Data, Enum<?>> pair = remove(key, publicKey, false);
       if (pair.element0() != null) {
         pair.element0().release();
       }
       result.put(key, (byte) pair.element1().ordinal());
     }
     return result;
   } finally {
     lock.unlock();
   }
 }
示例#8
0
 /* (non-Javadoc)
  * @see net.tomp2p.dht.DigestStorage#digest(net.tomp2p.peers.Number320, net.tomp2p.rpc.SimpleBloomFilter, net.tomp2p.rpc.SimpleBloomFilter, int, boolean, boolean)
  */
 @Override
 public DigestInfo digest(
     Number320 locationAndDomainKey,
     SimpleBloomFilter<Number160> keyBloomFilter,
     SimpleBloomFilter<Number160> contentKeyBloomFilter,
     int limit,
     boolean ascending,
     boolean isBloomFilterAnd) {
   DigestInfo digestInfo = new DigestInfo();
   RangeLock<Number640>.Range lock = lock(locationAndDomainKey);
   try {
     Number640 from = new Number640(locationAndDomainKey, Number160.ZERO, Number160.ZERO);
     Number640 to = new Number640(locationAndDomainKey, Number160.MAX_VALUE, Number160.MAX_VALUE);
     NavigableMap<Number640, Data> tmp = backend.subMap(from, to);
     tmp = filterCopyOrig(tmp, limit, ascending);
     for (Map.Entry<Number640, Data> entry : tmp.entrySet()) {
       if (isBloomFilterAnd) {
         if (keyBloomFilter == null || keyBloomFilter.contains(entry.getKey().contentKey())) {
           if (contentKeyBloomFilter == null
               || contentKeyBloomFilter.contains(entry.getValue().hash())) {
             if (!entry.getValue().hasPrepareFlag()) {
               digestInfo.put(entry.getKey(), entry.getValue().basedOnSet());
             }
           }
         }
       } else {
         if (keyBloomFilter == null || !keyBloomFilter.contains(entry.getKey().contentKey())) {
           if (contentKeyBloomFilter == null
               || !contentKeyBloomFilter.contains(entry.getValue().hash())) {
             if (!entry.getValue().hasPrepareFlag()) {
               digestInfo.put(entry.getKey(), entry.getValue().basedOnSet());
             }
           }
         }
       }
     }
     return digestInfo;
   } finally {
     lock.unlock();
   }
 }
示例#9
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();
    }
  }