blob: 053fefc7d5fe47f621444c3b9ee7e416746cee5a [file] [log] [blame]
package org.apache.commons.jcs.engine;
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.
*/
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.jcs.engine.behavior.IElementAttributes;
import org.apache.commons.jcs.engine.control.event.behavior.IElementEventHandler;
/**
* This it the element attribute descriptor class. Each element in the cache has an ElementAttribute
* object associated with it. An ElementAttributes object can be associated with an element in 3
* ways:
* <ol>
* <li>When the item is put into the cache, you can associate an element attributes object.</li>
* <li>If not attributes object is include when the element is put into the cache, then the default
* attributes for the region will be used.</li>
* <li>The element attributes can be reset. This effectively results in a retrieval followed by a
* put. Hence, this is the same as 1.</li>
* </ol>
*/
public class ElementAttributes
implements IElementAttributes
{
/** Don't change. */
private static final long serialVersionUID = 7814990748035017441L;
/** Can this item be flushed to disk */
private boolean IS_SPOOL = true;
/** Is this item laterally distributable */
private boolean IS_LATERAL = true;
/** Can this item be sent to the remote cache */
private boolean IS_REMOTE = true;
/**
* You can turn off expiration by setting this to true. This causes the cache to bypass both max
* life and idle time expiration.
*/
private boolean IS_ETERNAL = true;
/** Max life seconds */
private long maxLife = -1;
/**
* The maximum time an entry can be idle. Setting this to -1 causes the idle time check to be
* ignored.
*/
private long maxIdleTime = -1;
/** The byte size of the field. Must be manually set. */
private int size = 0;
/** The creation time. This is used to enforce the max life. */
private long createTime = 0;
/** The last access time. This is used to enforce the max idel time. */
private long lastAccessTime = 0;
/**
* The list of Event handlers to use. This is transient, since the event handlers cannot usually
* be serialized. This means that you cannot attach a post serialization event to an item.
* <p>
* TODO we need to check that when an item is passed to a non-local cache that if the local
* cache had a copy with event handlers, that those handlers are used.
*/
private transient ArrayList<IElementEventHandler> eventHandlers;
private long timeFactor = 1000;
/**
* Constructor for the IElementAttributes object
*/
public ElementAttributes()
{
this.createTime = System.currentTimeMillis();
this.lastAccessTime = this.createTime;
}
/**
* Constructor for the IElementAttributes object
* <p>
* @param attr
*/
protected ElementAttributes( ElementAttributes attr )
{
IS_ETERNAL = attr.IS_ETERNAL;
// waterfall onto disk, for pure disk set memory to 0
IS_SPOOL = attr.IS_SPOOL;
// lateral
IS_LATERAL = attr.IS_LATERAL;
// central rmi store
IS_REMOTE = attr.IS_REMOTE;
maxLife = attr.maxLife;
// time-to-live
maxIdleTime = attr.maxIdleTime;
size = attr.size;
}
/**
* Sets the maxLife attribute of the IAttributes object.
* <p>
* @param mls The new MaxLifeSeconds value
*/
@Override
public void setMaxLife(long mls)
{
this.maxLife = mls;
}
/**
* Sets the maxLife attribute of the IAttributes object. How many seconds it can live after
* creation.
* <p>
* If this is exceeded the element will not be returned, instead it will be removed. It will be
* removed on retrieval, or removed actively if the memory shrinker is turned on.
* @return The MaxLifeSeconds value
*/
@Override
public long getMaxLife()
{
return this.maxLife;
}
/**
* Sets the idleTime attribute of the IAttributes object. This is the maximum time the item can
* be idle in the cache, that is not accessed.
* <p>
* If this is exceeded the element will not be returned, instead it will be removed. It will be
* removed on retrieval, or removed actively if the memory shrinker is turned on.
* @param idle The new idleTime value
*/
@Override
public void setIdleTime( long idle )
{
this.maxIdleTime = idle;
}
/**
* Size in bytes. This is not used except in the admin pages. It will be 0 by default
* and is only updated when the element is serialized.
* <p>
* @param size The new size value
*/
@Override
public void setSize( int size )
{
this.size = size;
}
/**
* Gets the size attribute of the IAttributes object
* <p>
* @return The size value
*/
@Override
public int getSize()
{
return size;
}
/**
* Gets the createTime attribute of the IAttributes object.
* <p>
* This should be the current time in milliseconds returned by the sysutem call when the element
* is put in the cache.
* <p>
* Putting an item in the cache overrides any existing items.
* @return The createTime value
*/
@Override
public long getCreateTime()
{
return createTime;
}
/**
* Sets the createTime attribute of the IElementAttributes object
*/
public void setCreateTime()
{
createTime = System.currentTimeMillis();
}
/**
* Gets the idleTime attribute of the IAttributes object.
* <p>
* @return The idleTime value
*/
@Override
public long getIdleTime()
{
return this.maxIdleTime;
}
/**
* Gets the time left to live of the IAttributes object.
* <p>
* This is the (max life + create time) - current time.
* @return The TimeToLiveSeconds value
*/
@Override
public long getTimeToLiveSeconds()
{
final long now = System.currentTimeMillis();
final long timeFactorForMilliseconds = getTimeFactorForMilliseconds();
return ( this.getCreateTime() + this.getMaxLife() * timeFactorForMilliseconds - now ) / 1000;
}
/**
* Gets the LastAccess attribute of the IAttributes object.
* <p>
* @return The LastAccess value.
*/
@Override
public long getLastAccessTime()
{
return this.lastAccessTime;
}
/**
* Sets the LastAccessTime as now of the IElementAttributes object
*/
@Override
public void setLastAccessTimeNow()
{
this.lastAccessTime = System.currentTimeMillis();
}
/**
* only for use from test code
*/
public void setLastAccessTime(long time)
{
this.lastAccessTime = time;
}
/**
* Can this item be spooled to disk
* <p>
* By default this is true.
* @return The spoolable value
*/
@Override
public boolean getIsSpool()
{
return this.IS_SPOOL;
}
/**
* Sets the isSpool attribute of the IElementAttributes object
* <p>
* By default this is true.
* @param val The new isSpool value
*/
@Override
public void setIsSpool( boolean val )
{
this.IS_SPOOL = val;
}
/**
* Is this item laterally distributable. Can it be sent to auxiliaries of type lateral.
* <p>
* By default this is true.
* @return The isLateral value
*/
@Override
public boolean getIsLateral()
{
return this.IS_LATERAL;
}
/**
* Sets the isLateral attribute of the IElementAttributes object
* <p>
* By default this is true.
* @param val The new isLateral value
*/
@Override
public void setIsLateral( boolean val )
{
this.IS_LATERAL = val;
}
/**
* Can this item be sent to the remote cache
* @return true if the item can be sent to a remote auxiliary
*/
@Override
public boolean getIsRemote()
{
return this.IS_REMOTE;
}
/**
* Sets the isRemote attribute of the ElementAttributes object
* @param val The new isRemote value
*/
@Override
public void setIsRemote( boolean val )
{
this.IS_REMOTE = val;
}
/**
* You can turn off expiration by setting this to true. The max life value will be ignored.
* <p>
* @return true if the item cannot expire.
*/
@Override
public boolean getIsEternal()
{
return this.IS_ETERNAL;
}
/**
* Sets the isEternal attribute of the ElementAttributes object. True means that the item should
* never expire. If can still be removed if it is the least recently used, and you are using the
* LRUMemory cache. it just will not be filtered for expiration by the cache hub.
* <p>
* @param val The new isEternal value
*/
@Override
public void setIsEternal( boolean val )
{
this.IS_ETERNAL = val;
}
/**
* Adds a ElementEventHandler. Handler's can be registered for multiple events. A registered
* handler will be called at every recognized event.
* <p>
* The alternative would be to register handlers for each event. Or maybe The handler interface
* should have a method to return whether it cares about certain events.
* <p>
* @param eventHandler The ElementEventHandler to be added to the list.
*/
@Override
public void addElementEventHandler( IElementEventHandler eventHandler )
{
// lazy here, no concurrency problems expected
if ( this.eventHandlers == null )
{
this.eventHandlers = new ArrayList<>();
}
this.eventHandlers.add( eventHandler );
}
/**
* Sets the eventHandlers of the IElementAttributes object.
* <p>
* This add the references to the local list. Subsequent changes in the caller's list will not
* be reflected.
* <p>
* @param eventHandlers List of IElementEventHandler objects
*/
@Override
public void addElementEventHandlers( List<IElementEventHandler> eventHandlers )
{
if ( eventHandlers == null )
{
return;
}
for (IElementEventHandler handler : eventHandlers)
{
addElementEventHandler(handler);
}
}
@Override
public long getTimeFactorForMilliseconds()
{
return timeFactor;
}
@Override
public void setTimeFactorForMilliseconds(long factor)
{
this.timeFactor = factor;
}
/**
* Gets the elementEventHandlers. Returns null if none exist. Makes checking easy.
* <p>
* @return The elementEventHandlers List of IElementEventHandler objects
*/
@Override
public ArrayList<IElementEventHandler> getElementEventHandlers()
{
return this.eventHandlers;
}
/**
* For logging and debugging the element IElementAttributes.
* <p>
* @return String info about the values.
*/
@Override
public String toString()
{
StringBuilder dump = new StringBuilder();
dump.append( "[ IS_LATERAL = " ).append( IS_LATERAL );
dump.append( ", IS_SPOOL = " ).append( IS_SPOOL );
dump.append( ", IS_REMOTE = " ).append( IS_REMOTE );
dump.append( ", IS_ETERNAL = " ).append( IS_ETERNAL );
dump.append( ", MaxLifeSeconds = " ).append( this.getMaxLife() );
dump.append( ", IdleTime = " ).append( this.getIdleTime() );
dump.append( ", CreateTime = " ).append( this.getCreateTime() );
dump.append( ", LastAccessTime = " ).append( this.getLastAccessTime() );
dump.append( ", getTimeToLiveSeconds() = " ).append( String.valueOf( getTimeToLiveSeconds() ) );
dump.append( ", createTime = " ).append( String.valueOf( createTime ) ).append( " ]" );
return dump.toString();
}
/**
* @see java.lang.Object#clone()
*/
@Override
public IElementAttributes clone()
{
try
{
ElementAttributes c = (ElementAttributes) super.clone();
c.setCreateTime();
return c;
}
catch (CloneNotSupportedException e)
{
throw new RuntimeException("Clone not supported. This should never happen.", e);
}
}
}