Пример #1
0
  // Appends the specified ResourceAllocation to the existing values stored in the map
  private boolean appendValue(
      TransactionalMap<ResourceId, ContinuousResourceAllocation> map,
      ContinuousResource original,
      ResourceAllocation value) {
    ContinuousResourceAllocation oldValue =
        map.putIfAbsent(
            original.id(), new ContinuousResourceAllocation(original, ImmutableList.of(value)));
    if (oldValue == null) {
      return true;
    }

    if (oldValue.allocations().contains(value)) {
      // don't write to map because all values are already stored
      return true;
    }

    ContinuousResourceAllocation newValue =
        new ContinuousResourceAllocation(
            original,
            ImmutableList.<ResourceAllocation>builder()
                .addAll(oldValue.allocations())
                .add(value)
                .build());
    return map.replace(original.id(), oldValue, newValue);
  }
Пример #2
0
  @Override
  public boolean release(List<Resource> resources, List<ResourceConsumer> consumers) {
    checkNotNull(resources);
    checkNotNull(consumers);
    checkArgument(resources.size() == consumers.size());

    TransactionContext tx = service.transactionContextBuilder().build();
    tx.begin();

    TransactionalMap<DiscreteResource, ResourceConsumer> discreteConsumerTxMap =
        tx.getTransactionalMap(DISCRETE_CONSUMER_MAP, SERIALIZER);
    TransactionalMap<ResourceId, ContinuousResourceAllocation> continuousConsumerTxMap =
        tx.getTransactionalMap(CONTINUOUS_CONSUMER_MAP, SERIALIZER);
    Iterator<Resource> resourceIte = resources.iterator();
    Iterator<ResourceConsumer> consumerIte = consumers.iterator();

    while (resourceIte.hasNext() && consumerIte.hasNext()) {
      Resource resource = resourceIte.next();
      ResourceConsumer consumer = consumerIte.next();

      if (resource instanceof DiscreteResource) {
        // if this single release fails (because the resource is allocated to another consumer,
        // the whole release fails
        if (!discreteConsumerTxMap.remove((DiscreteResource) resource, consumer)) {
          return abortTransaction(tx);
        }
      } else if (resource instanceof ContinuousResource) {
        ContinuousResource continuous = (ContinuousResource) resource;
        ContinuousResourceAllocation allocation = continuousConsumerTxMap.get(continuous.id());
        ImmutableList<ResourceAllocation> newAllocations =
            allocation
                .allocations()
                .stream()
                .filter(
                    x ->
                        !(x.consumer().equals(consumer)
                            && ((ContinuousResource) x.resource()).value() == continuous.value()))
                .collect(GuavaCollectors.toImmutableList());

        if (!continuousConsumerTxMap.replace(
            continuous.id(),
            allocation,
            new ContinuousResourceAllocation(allocation.original(), newAllocations))) {
          return abortTransaction(tx);
        }
      }
    }

    return tx.commit();
  }
Пример #3
0
  /**
   * Checks if there is enough resource volume to allocated the requested resource against the
   * specified resource.
   *
   * @param original original resource
   * @param request requested resource
   * @param allocation current allocation of the resource
   * @return true if there is enough resource volume. Otherwise, false.
   */
  private boolean hasEnoughResource(
      ContinuousResource original,
      ContinuousResource request,
      ContinuousResourceAllocation allocation) {
    if (allocation == null) {
      return request.value() <= original.value();
    }

    double allocated =
        allocation
            .allocations()
            .stream()
            .filter(x -> x.resource() instanceof ContinuousResource)
            .map(x -> (ContinuousResource) x.resource())
            .mapToDouble(ContinuousResource::value)
            .sum();
    double left = original.value() - allocated;
    return request.value() <= left;
  }
Пример #4
0
  @Override
  public boolean unregister(List<Resource> resources) {
    checkNotNull(resources);

    TransactionContext tx = service.transactionContextBuilder().build();
    tx.begin();

    TransactionalMap<DiscreteResource, Set<Resource>> childTxMap =
        tx.getTransactionalMap(CHILD_MAP, SERIALIZER);
    TransactionalMap<DiscreteResource, ResourceConsumer> discreteConsumerTxMap =
        tx.getTransactionalMap(DISCRETE_CONSUMER_MAP, SERIALIZER);
    TransactionalMap<ResourceId, ContinuousResourceAllocation> continuousConsumerTxMap =
        tx.getTransactionalMap(CONTINUOUS_CONSUMER_MAP, SERIALIZER);

    // Extract Discrete instances from resources
    Map<DiscreteResource, List<Resource>> resourceMap =
        resources
            .stream()
            .filter(x -> x.parent().isPresent())
            .collect(Collectors.groupingBy(x -> x.parent().get()));

    // even if one of the resources is allocated to a consumer,
    // all unregistrations are regarded as failure
    for (Map.Entry<DiscreteResource, List<Resource>> entry : resourceMap.entrySet()) {
      boolean allocated =
          entry
              .getValue()
              .stream()
              .anyMatch(
                  x -> {
                    if (x instanceof DiscreteResource) {
                      return discreteConsumerTxMap.get((DiscreteResource) x) != null;
                    } else if (x instanceof ContinuousResource) {
                      ContinuousResourceAllocation allocations =
                          continuousConsumerTxMap.get(x.id());
                      return allocations != null && !allocations.allocations().isEmpty();
                    } else {
                      return false;
                    }
                  });
      if (allocated) {
        return abortTransaction(tx);
      }

      if (!removeValues(childTxMap, entry.getKey(), entry.getValue())) {
        return abortTransaction(tx);
      }
    }

    boolean success = tx.commit();
    if (success) {
      List<ResourceEvent> events =
          resources
              .stream()
              .filter(x -> x.parent().isPresent())
              .map(x -> new ResourceEvent(RESOURCE_REMOVED, x))
              .collect(Collectors.toList());
      notifyDelegate(events);
    }
    return success;
  }