All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.maxifier.mxcache.clean.ClassCleanableInstanceList Maven / Gradle / Ivy

/*
 * Copyright (c) 2008-2014 Maxifier Ltd. All Rights Reserved.
 */
package com.maxifier.mxcache.clean;

import com.maxifier.mxcache.caches.CleaningNode;
import javax.annotation.Nullable;

import java.util.*;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

import com.maxifier.mxcache.caches.Cache;

/**
 * ClassCleanableInstanceList
 *
 * @author Andrey Yakoushin ([email protected])
 * @author Alexander Kochurov ([email protected])
 */
@SuppressWarnings({"unchecked"})
final class ClassCleanableInstanceList extends WeakList implements CleanableInstanceList {
    private final ClassCleanableInstanceList parent;
    private final List> children;

    private final Class clazz;

    private final Cleanable cleanable;

    private final Map groups;
    private final Map tags;

    private final Lock readLock;
    private final Lock writeLock;

    private volatile int version;

    //------------------------------------------------------------------------------------------------------------------

    public ClassCleanableInstanceList(@Nullable ClassCleanableInstanceList parent, Cleanable cleanable, Map groups, Map tags, Class clazz) {
        this.parent = parent;
        this.tags = tags;
        this.groups = groups;
        this.clazz = clazz;
        //noinspection CollectionWithoutInitialCapacity
        children = new ArrayList>();
        this.cleanable = cleanable;
        if (parent != null) {
            parent.addChild(this);
        }

        ReadWriteLock lock = new ReentrantReadWriteLock();
        readLock = lock.readLock();
        writeLock = lock.writeLock();
    }

    //------------------------------------------------------------------------------------------------------------------

    void addChild(ClassCleanableInstanceList child) {
        writeLock.lock();
        try {
            version++;
            children.add(child);
        } finally {
            writeLock.unlock();
        }
    }

    //------------------------------------------------------------------------------------------------------------------

    @Override
    public int deepLock() {
        readLock.lock();
        int version = this.version;
        for (ClassCleanableInstanceList child : children) {
            version += child.deepLock();
        }
        return version;
    }

    @Override
    public void deepUnlock() {
        for (ClassCleanableInstanceList child : children) {
            child.deepUnlock();
        }
        readLock.unlock();
    }

    @Override
    public void getLists(List> lists) {
        lists.add(this);
        for (ClassCleanableInstanceList child : children) {
            child.getLists(lists);
        }
    }

    @Override
    public void getCaches(List caches) {
        ClassCleanableInstanceList list = this.parent;
        while (list != null) {
            for (T t : this) {
                list.cleanable.appendInstanceCachesTo(caches, t);
            }
            list = list.parent;
        }
        getCachesHierarchically(caches);
    }

    private void getCachesHierarchically(List caches) {
        cleanable.appendStaticCachesTo(caches);
        for (T t : this) {
            cleanable.appendInstanceCachesTo(caches, t);
        }
        readLock.lock();
        try {
            for (ClassCleanableInstanceList child : children) {
                child.getCachesHierarchically(caches);
            }
        } finally {
            readLock.unlock();
        }
    }

    //------------------------------------------------------------------------------------------------------------------

    public void clearCache() {
        CleaningHelper.clear(this);
    }

    public void clearCacheByGroup(Object o, String group) {
        T t = (T) o;
        CleaningHelper.lockAndClear(getGroupInstanceCaches(group, t));
    }

    public void clearCacheByTag(Object o, String tag) {
        T t = (T) o;
        CleaningHelper.lockAndClear(getTagInstanceCaches(tag, t));
    }

    private List getTagInstanceCaches(String tag, Object t) {
        //noinspection CollectionWithoutInitialCapacity
        List caches = new ArrayList();
        ClassCleanableInstanceList classList = this;
        while (classList != null) {
            classList.appendTagInstanceCaches(tag, t, caches);
            classList = classList.parent;
        }
        return caches;
    }

    private void appendTagInstanceCaches(String tag, Object t, List caches) {
        if (tags != null) {
            ClassCacheIds ids = tags.get(tag);
            if (ids != null) {
                ids.appendInstanceCaches(cleanable, t, caches);
            }
        }
    }

    private List getGroupInstanceCaches(String tag, Object t) {
        //noinspection CollectionWithoutInitialCapacity
        List caches = new ArrayList();
        ClassCleanableInstanceList classList = this;
        while (classList != null) {
            classList.appendGroupInstanceCaches(tag, t, caches);
            classList = classList.parent;
        }
        return caches;
    }

    private void appendGroupInstanceCaches(String tag, Object t, List caches) {
        if (groups != null) {
            ClassCacheIds ids = groups.get(tag);
            if (ids != null) {
                ids.appendInstanceCaches(cleanable, t, caches);
            }
        }
    }

    public void clearCache(Object o) {
        T t = (T) o;
        CleaningHelper.lockAndClear(getInstanceCaches(t));
    }

    private List getInstanceCaches(T t) {
        //noinspection CollectionWithoutInitialCapacity
        List caches = new ArrayList();
        ClassCleanableInstanceList classList = this;
        while (classList != null) {
            classList.cleanable.appendInstanceCachesTo(caches, t);
            classList = classList.parent;
        }
        return caches;
    }

    public Cleanable getCleanable() {
        return cleanable;
    }

    @Override
    public String toString() {
        return "ClassCleanableInstanceList[" + clazz + "]"; 
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy