import java.util.*;
import java.util.concurrent.locks.*;


/**
 * A PresenceRecord is a "read mostly" record of presence.  It can be
 * used to keep a record of objects and that can be accessed
 * simultaneously by many threads.
 *
 * @author  Prof. David Bernstein, James Madison University
 * @version 1.0
 */
public class PresenceRecord<E> 
{
    private final HashSet<E>    set  = new HashSet<E>();
    private final ReadWriteLock lock = new ReentrantReadWriteLock();
    private final Lock          r    = lock.readLock();
    private final Lock          w    = lock.writeLock();
    
    /**
     * Add a given element to this PresenceRecord.
     *
     * @param e  The element to add
     */
    public boolean add(E e)
    {
        w.lock(); // This is a write operation
        try     
        {
          return set.add(e); 
        }
        finally 
        { 
          w.unlock(); 
        }
    }
    
    /**
     * Clear this Presencerecord.
     */
    public void clear()
    {
        w.lock(); // This is a write operation
        try     
        {
          set.clear(); 
        }
        finally 
        { 
          w.unlock(); 
        }
    }

    /**
     * Returns true if this PresenceRecord contains the given element.
     *
     * @return  true if the element is present; false otherwise
     */
    public boolean contains(E e)
    {
        r.lock(); // This is a read operation
        try     
        {
            return set.contains(e);
        }
        finally 
        {
            r.unlock();
        }
    }

    /**
     * Removes the given element from this PresenceRecord (if present).
     *
     * @return  true if the element was present; false otherwise
     */
    public boolean remove(E e)
    {
        w.lock(); // This is a write operation
        try     
        {
            return set.remove(e);
        }
        finally 
        {
            w.unlock();
        }
    }
}
