io.greptime.common.util.RcResourceHolder Maven / Gradle / Ivy
The newest version!
/*
* Copyright 2023 Greptime Team
*
* Licensed 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 io.greptime.common.util;
import java.util.IdentityHashMap;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Resource holder with ref count.
*/
public class RcResourceHolder {
private static final Logger LOG = LoggerFactory.getLogger(RcResourceHolder.class);
private final Map, Instance> instances = new IdentityHashMap<>();
public synchronized T get(ObjectPool.Resource resource) {
Instance ins = this.instances.get(resource);
if (ins == null) {
ins = new Instance<>(resource.create());
this.instances.put(resource, ins);
LOG.info("[RcResourceHolder] create instance: {}.", ins);
}
ins.inc();
return ins.payload();
}
public synchronized void release(ObjectPool.Resource resource, T returned) {
Instance cached = this.instances.get(resource);
Ensures.ensureNonNull(cached, "No cached instance found for " + resource);
Ensures.ensure(
returned == cached.payload(),
"Releasing the wrong instance, expected=%s, actual=%s",
cached.payload(),
returned);
Ensures.ensure(cached.rc() > 0, "RefCount has already reached zero");
if (cached.decAndGet() == 0) {
LOG.info("[RcResourceHolder] close instance: {}.", cached);
resource.close(cached.payload());
this.instances.remove(resource);
}
}
private static class Instance {
final T payload;
int refCount;
int maxRefCount;
Instance(T payload) {
this.payload = payload;
}
void inc() {
this.refCount++;
this.maxRefCount = Math.max(this.maxRefCount, this.refCount);
}
int decAndGet() {
return --this.refCount;
}
int rc() {
return this.refCount;
}
T payload() {
return this.payload;
}
@Override
public String toString() {
return "Instance{" + "payload=" + payload + ", refCount=" + refCount + ", maxRefCount=" + maxRefCount + '}';
}
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy