/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.nifi.controller.repository.claim; public class StandardResourceClaim implements ResourceClaim, Comparable<ResourceClaim> { private final StandardResourceClaimManager claimManager; private final String id; private final String container; private final String section; private final boolean lossTolerant; private final int hashCode; private volatile boolean writable = true; public StandardResourceClaim(final StandardResourceClaimManager claimManager, final String container, final String section, final String id, final boolean lossTolerant) { this.claimManager = claimManager; this.container = container.intern(); this.section = section.intern(); this.id = id; this.lossTolerant = lossTolerant; hashCode = 17 + 19 * id.hashCode() + 19 * container.hashCode() + 19 * section.hashCode(); } @Override public boolean isLossTolerant() { return lossTolerant; } /** * @return the unique identifier for this claim */ @Override public String getId() { return id; } /** * @return the container identifier in which this claim is held */ @Override public String getContainer() { return container; } /** * @return the section within a given container the claim is held */ @Override public String getSection() { return section; } @Override public boolean equals(final Object other) { if (this == other) { return true; } if (other == null) { return false; } if (hashCode != other.hashCode()) { // We check hash code before instanceof because instanceof is fairly expensive and for // StandardResourceClaim, calling hashCode() simply returns a pre-calculated value. return false; } if (!(other instanceof ResourceClaim)) { return false; } final ResourceClaim otherClaim = (ResourceClaim) other; return id.equals(otherClaim.getId()) && container.equals(otherClaim.getContainer()) && section.equals(otherClaim.getSection()); } @Override public int hashCode() { return hashCode; } @Override public String toString() { return "StandardResourceClaim[id=" + id + ", container=" + container + ", section=" + section + "]"; } @Override public boolean isWritable() { return writable; } /** * Freeze the Resource Claim so that it can now longer be written to */ void freeze() { this.writable = false; } @Override public boolean isInUse() { // Note that it is critical here that we always check isWritable() BEFORE checking // the claimant count. This is due to the fact that if the claim is in fact writable, the claimant count // could increase. So if we first check claimant count and that is 0, and then we check isWritable, it may be // that the claimant count has changed to 1 before checking isWritable. // However, if isWritable() is false, then the only way that the claimant count can increase is if a FlowFile referencing // the Resource Claim is cloned. In this case, though, the claimant count has not become 0. // Said another way, if isWritable() == false, then the claimant count can never increase from 0. return isWritable() || claimManager.getClaimantCount(this) > 0; } }