001/*
002 * Trident - A Multithreaded Server Alternative
003 * Copyright 2014 The TridentSDK Team
004 *
005 * Licensed under the Apache License, Version 2.0 (the "License");
006 * you may not use this file except in compliance with the License.
007 * You may obtain a copy of the License at
008 *
009 *    http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package net.tridentsdk.server.chunk;
018
019import net.tridentsdk.server.world.TridentChunk;
020
021import javax.annotation.concurrent.ThreadSafe;
022import java.util.concurrent.atomic.LongAdder;
023
024@ThreadSafe
025// TODO add reference to avoid lookup each call
026public class CRefCounter {
027    private final TridentChunk wrapped;
028    private final LongAdder strongRefs = new LongAdder();
029    private final LongAdder weakRefs = new LongAdder();
030
031    private CRefCounter(TridentChunk wrapped) {
032        this.wrapped = wrapped;
033    }
034
035    public static CRefCounter wrap(TridentChunk chunk) {
036        return new CRefCounter(chunk);
037    }
038
039    public void refStrong() {
040        strongRefs.increment();
041    }
042
043    public void releaseStrong() {
044        strongRefs.decrement();
045        wrapped.world().chunkHandler().tryRemove(wrapped.location());
046
047        if (strongRefs.sum() < 0L) throw new IllegalStateException("Sub-zero strongrefs");
048    }
049
050    public void refWeak() {
051        weakRefs.increment();
052    }
053
054    public void releaseWeak() {
055        weakRefs.decrement();
056
057        if (weakRefs.sum() < 0L) throw new IllegalStateException("Sub-zero weakrefs");
058    }
059
060    public boolean hasStrongRefs() {
061        return strongRefs.sum() > 0L;
062    }
063
064    public boolean hasWeakRefs() {
065        return weakRefs.sum() > 0L;
066    }
067
068    public TridentChunk unwrap() {
069        return wrapped;
070    }
071
072    public long list() {
073        return strongRefs.sum();
074    }
075}