Package com.ponysdk.core

Source Code of com.ponysdk.core.WeakHashMap

package com.ponysdk.core;

import java.lang.ref.Reference;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.WeakReference;
import java.util.Collection;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.ponysdk.core.instruction.GC;
import com.ponysdk.core.stm.Txn;
import com.ponysdk.ui.server.basic.PObject;
import com.ponysdk.ui.server.basic.PWidget;

public class WeakHashMap implements Map<Long, PObject> {

    private final Logger log = LoggerFactory.getLogger(WeakHashMap.class);

    private final ReferenceQueue<PObject> queue = new ReferenceQueue<PObject>();

    private final Map<Long, WeakReference<PObject>> referenceByObjectID = new ConcurrentHashMap<Long, WeakReference<PObject>>();

    private final Map<WeakReference<PObject>, Long> objectIDByReferences = new ConcurrentHashMap<WeakReference<PObject>, Long>();

    private final Map<WeakReference<PObject>, Long> parentObjectIDByReferences = new ConcurrentHashMap<WeakReference<PObject>, Long>();

    @Override
    public int size() {
        expungeStaleEntries();
        return referenceByObjectID.size();
    }

    @Override
    public boolean isEmpty() {
        expungeStaleEntries();
        return referenceByObjectID.isEmpty();
    }

    @Override
    public boolean containsKey(final Object key) {
        expungeStaleEntries();
        return referenceByObjectID.containsKey(key);
    }

    @Override
    public boolean containsValue(final Object value) {
        expungeStaleEntries();
        return referenceByObjectID.containsValue(new WeakReference<Object>(value));
    }

    @Override
    public PObject get(final Object key) {
        expungeStaleEntries();
        final WeakReference<PObject> value = referenceByObjectID.get(key);
        if (value == null) return null;
        return value.get();
    }

    @Override
    public PObject put(final Long objectID, final PObject value) {
        expungeStaleEntries();
        final WeakReference<PObject> weakReference = new WeakReference<PObject>(value, queue);
        referenceByObjectID.put(objectID, weakReference);
        objectIDByReferences.put(weakReference, objectID);

        if (log.isDebugEnabled()) log.debug("Registering object: " + value);

        if (value instanceof PWidget) {
            final PWidget widget = (PWidget) value;
            if (widget.getParent() != null) {
                if (log.isDebugEnabled()) log.debug("Attaching object #" + objectID + " to parent: " + widget);
                parentObjectIDByReferences.put(weakReference, widget.getParent().getID());
            }
        }

        return value;
    }

    @Override
    public PObject remove(final Object key) {
        expungeStaleEntries();
        final WeakReference<PObject> reference = referenceByObjectID.remove(key);

        if (log.isDebugEnabled()) log.debug("Removing reference on object #" + key);
        if (reference == null) return null;

        objectIDByReferences.remove(reference);
        parentObjectIDByReferences.remove(reference);

        return reference.get();
    }

    @Override
    public void putAll(final Map<? extends Long, ? extends PObject> m) {
        expungeStaleEntries();
    }

    @Override
    public void clear() {
        expungeStaleEntries();
    }

    @Override
    public Set<Long> keySet() {
        expungeStaleEntries();
        return null;
    }

    @Override
    public Collection<PObject> values() {
        expungeStaleEntries();
        return null;
    }

    @Override
    public Set<java.util.Map.Entry<Long, PObject>> entrySet() {
        expungeStaleEntries();
        return null;
    }

    public void assignParentID(final Long objectID, final Long parentObjectID) {
        if (referenceByObjectID.get(objectID) == null) {
            log.warn("Unkwnown reference to object: " + objectID);
            return;
        }
        parentObjectIDByReferences.put(referenceByObjectID.get(objectID), parentObjectID);
    }

    private void expungeStaleEntries() {
        Reference<? extends PObject> reference = null;

        while ((reference = queue.poll()) != null) {
            final Long objectID = objectIDByReferences.remove(reference);
            final Long parentObjectID = parentObjectIDByReferences.remove(reference);
            referenceByObjectID.remove(objectID);
            if (log.isDebugEnabled()) log.debug("Removing reference on object #" + objectID);

            if (parentObjectID != null) {
                Txn.get().getTxnContext().save(new GC(objectID, parentObjectID));
            }
        }
    }

}
TOP

Related Classes of com.ponysdk.core.WeakHashMap

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.