List Info

Thread: Feature patch: FLV Cache




Feature patch: FLV Cache
user name
2006-07-29 10:00:57
Hi Paul,

Thanks for the patch. Just to confirm I understand how the
code will
work. This cache holds named cachable objects which wrap an
array of
bytes. The cache uses soft references so that cachable
objects can be
garbage collected when they are no longer in use. What would
be great
is if you could provide a test that compares FLV readers
with and
without the cache turned on.

Has anyone else got any thoughts on the cache
implementation?

- Luke

On 7/28/06, Mondain <mondaingmail.com> wrote:
> Luke,
> I sent this to the list earlier tonight but after an
hour I still
> havent seen it come through. Below is my patch
containing the first
> rev of the FLV caching system. It works but still needs
polish and
> refactoring...
>
>
> Index:
D:/diff/java/server/trunk/src/org/red5/server/cache/CacheImp
l.java
>
============================================================
=======
> ---
D:/diff/java/server/trunk/src/org/red5/server/cache/CacheImp
l.java  (revision
> 0)
> +++
D:/diff/java/server/trunk/src/org/red5/server/cache/CacheImp
l.java  (revision
> 0)
>  -0,0 +1,157 
> +package org.red5.server.cache;
> +
> +/*
> + * RED5 Open Source Flash Server - http://www.osflash.org/re
d5
> + *
> + * Copyright (c) 2006 by respective authors (see
below). All rights reserved.
> + *
> + * This library is free software; you can redistribute
it and/or
> modify it under the
> + * terms of the GNU Lesser General Public License as
published by the
> Free Software
> + * Foundation; either version 2.1 of the License, or
(at your option)
> any later
> + * version.
> + *
> + * This library is distributed in the hope that it
will be useful,
> but WITHOUT ANY
> + * WARRANTY; without even the implied warranty of
MERCHANTABILITY or
> FITNESS FOR A
> + * PARTICULAR PURPOSE. See the GNU Lesser General
Public License for
> more details.
> + *
> + * You should have received a copy of the GNU Lesser
General Public
> License along
> + * with this library; if not, write to the Free
Software Foundation, Inc.,
> + * 59 Temple Place, Suite 330, Boston, MA 02111-1307
USA
> + */
> +
> +import java.lang.ref.SoftReference;
> +import java.util.Collections;
> +import java.util.HashMap;
> +import java.util.HashSet;
> +import java.util.Iterator;
> +import java.util.Map;
> +
> +import org.apache.commons.logging.Log;
> +import org.apache.commons.logging.LogFactory;
> +import org.apache.mina.common.ByteBuffer;
> +import org.red5.server.api.cache.ICacheStore;
> +import org.red5.server.api.cache.ICacheable;
> +
> +/**
> + * Provides an implementation of an object cache.
> + *
> + * author The Red5 Project (red5osflash.org)
> + * author Paul Gregoire (mondaingmail.com)
> + */
> +public class CacheImpl implements ICacheStore {
> +
> +       protected static Log log =
LogFactory.getLog(CacheImpl.class.getName());
> +
> +       private static volatile CacheImpl instance;
> +       private static final Map<String,
SoftReference<? extends ICacheable>> CACHE;
> +       //cache registry - keeps hard references to
objects in the cache
> +       private static Map<String, Integer>
registry;
> +
> +       private static int MAX_SIZE = 5;
> +       private static volatile long cacheHit = 0;
> +       private static volatile long cacheMiss = 0;
> +
> +       static {
> +               //create an instance
> +               instance = new CacheImpl();
> +               //instance a static map with an initial
small (prime) size
> +               CACHE = new HashMap<String,
SoftReference<? extends ICacheable>>(3);
> +               //instance a hard-ref registry
> +               registry = new HashMap<String,
Integer>(3);
> +       }
> +
> +       /*
> +        * This constructor helps to ensure that we are
singleton.
> +        */
> +       private CacheImpl() {
> +       }
> +
> +       /**
> +        * Returns the instance of this class.
> +        *
> +        * return
> +        */
> +       public static CacheImpl getInstance() {
> +               return instance;
> +       }
> +
> +       public Iterator<String> getObjectNames()
{
> +               return
Collections.unmodifiableSet(CACHE.keySet()).iterator();
> +       }
> +
> +       public Iterator<SoftReference<? extends
ICacheable>> getObjects() {
> +               return
Collections.unmodifiableCollection(CACHE.values()).iterator(
);
> +       }
> +
> +       public boolean offer(String key, ByteBuffer
obj) {
> +               return offer(key, new
CacheableImpl(obj));
> +       }
> +
> +       public boolean offer(String key, ICacheable
obj) {
> +               boolean accepted = false;
> +               //check map size
> +               if (CACHE.size() < MAX_SIZE) {
> +                       SoftReference tmp =
CACHE.get(key);
> +                       //because soft references can
be garbage collected when a system is
> +                       //in need of memory, we will
check that the cacheable object is valid
> +                       log.debug("Softreference:
" + (null == tmp));
> +                       if (null != tmp) {
> +                              
log.debug("Softreference value: " + (null ==
tmp.get()));
> +                       }
> +                       if (null == tmp || null ==
tmp.get()) {
> +                               //set the objects name
> +                               obj.setName(key);
> +                               //set a registry entry
> +                               registry.put(key, 1);
> +                               //create a soft
reference
> +                              
SoftReference<ICacheable> value = new
SoftReference<ICacheable>(obj);
> +                               CACHE.put(key, value);
> +                               //set acceptance
> +                               accepted = true;
> +                               log.warn(key + "
has been added to the cache. Current size: " +
> CACHE.size());
> +                       }
> +               } else {
> +                       log.warn("Cache has
reached max element size: " + MAX_SIZE);
> +               }
> +               return accepted;
> +       }
> +
> +       public ICacheable get(String name) {
> +               log.debug("Looking up " +
name + " in the cache. Current size: " +
> CACHE.size());
> +               ICacheable ic = null;
> +               SoftReference sr = null;
> +               if (!CACHE.isEmpty() && null !=
(sr = CACHE.get(name))) {
> +                       ic = (ICacheable) sr.get();
> +                       //add a request count to the
registry
> +                       int requestCount =
registry.get(name);
> +                       registry.put(name,
(requestCount += 1));
> +                       //increment cache hits
> +                       cacheHit += 1;
> +               } else {
> +                       //add a request count to the
registry
> +                       registry.put(name, 1);
> +                       //increment cache misses
> +                       cacheMiss += 1;
> +               }
> +               log.debug("Registry on get:
" + registry.toString());
> +               return ic;
> +       }
> +
> +       public boolean remove(ICacheable obj) {
> +               log.debug("Looking up " +
obj.getName() + " in the cache. Current
> size: " + CACHE.size());
> +               return remove(obj.getName());
> +       }
> +
> +       public boolean remove(String name) {
> +               return CACHE.remove(name) != null ?
true : false;
> +       }
> +
> +       public static long getCacheHit() {
> +               return cacheHit;
> +       }
> +
> +       public static long getCacheMiss() {
> +               return cacheMiss;
> +       }
> +
> +}
> Index:
D:/diff/java/server/trunk/src/org/red5/server/cache/Cacheabl
eImpl.java
>
============================================================
=======
> ---
D:/diff/java/server/trunk/src/org/red5/server/cache/Cacheabl
eImpl.java      (revision
> 0)
> +++
D:/diff/java/server/trunk/src/org/red5/server/cache/Cacheabl
eImpl.java      (revision
> 0)
>  -0,0 +1,100 
> +package org.red5.server.cache;
> +
> +/*
> + * RED5 Open Source Flash Server - http://www.osflash.org/re
d5
> + *
> + * Copyright (c) 2006 by respective authors (see
below). All rights reserved.
> + *
> + * This library is free software; you can redistribute
it and/or
> modify it under the
> + * terms of the GNU Lesser General Public License as
published by the
> Free Software
> + * Foundation; either version 2.1 of the License, or
(at your option)
> any later
> + * version.
> + *
> + * This library is distributed in the hope that it
will be useful,
> but WITHOUT ANY
> + * WARRANTY; without even the implied warranty of
MERCHANTABILITY or
> FITNESS FOR A
> + * PARTICULAR PURPOSE. See the GNU Lesser General
Public License for
> more details.
> + *
> + * You should have received a copy of the GNU Lesser
General Public
> License along
> + * with this library; if not, write to the Free
Software Foundation, Inc.,
> + * 59 Temple Place, Suite 330, Boston, MA 02111-1307
USA
> + */
> +
> +import java.nio.MappedByteBuffer;
> +
> +import org.apache.commons.logging.Log;
> +import org.apache.commons.logging.LogFactory;
> +import org.apache.mina.common.ByteBuffer;
> +import
org.apache.mina.common.SimpleByteBufferAllocator;
> +import org.red5.io.utils.BufferUtils;
> +import org.red5.server.api.cache.ICacheable;
> +
> +/**
> + * Provides an implementation of a cacheable object.
> + *
> + * author The Red5 Project (red5osflash.org)
> + * author Paul Gregoire (mondaingmail.com)
> + */
> +public class CacheableImpl implements ICacheable {
> +
> +       protected static Log log =
LogFactory.getLog(CacheableImpl.class.getName());
> +
> +       private byte[] bytes;
> +       private String name;
> +       private boolean cached;
> +
> +       public CacheableImpl(Object obj) {
> +               ByteBuffer tmp =
ByteBuffer.allocate(1024, true);
> +               tmp.setAutoExpand(true);
> +               tmp.putObject(obj);
> +               bytes = new byte[tmp.capacity()];
> +               tmp.get(bytes);
> +               tmp.release();
> +               cached = true;
> +       }
> +
> +       public CacheableImpl(ByteBuffer buffer) {
> +               log.debug("Buffer is direct:
" + buffer.isDirect() + " capacity: "
> + buffer.capacity());
> +               log.debug("Buffer limit: "
+ buffer.limit() + " remaining: " +
> buffer.remaining() + " position: " +
buffer.position());
> +               bytes = new byte[buffer.capacity()];
> +               buffer.rewind();
> +               int i = 0;
> +               while (i < buffer.limit()) {
> +                       buffer.position(i);
> +                       while (buffer.remaining() >
0) {
> +                               bytes[i++] =
buffer.get();
> +                       }
> +               }
> +               cached = true;
> +               log.debug("Buffer size: " +
buffer.capacity());
> +               buffer.release();
> +       }
> +
> +       public void addRequest() {
> +               log.info("Adding request for:
" + name);
> +       }
> +
> +       public byte[] getBytes() {
> +               return bytes;
> +       }
> +
> +       public ByteBuffer getByteBuffer() {
> +               return
ByteBuffer.wrap(bytes).asReadOnlyBuffer();
> +       }
> +
> +       public String getName() {
> +               return name;
> +       }
> +
> +       public boolean isCached() {
> +               return cached;
> +       }
> +
> +       public void setCached(boolean cached) {
> +               this.cached = cached;
> +       }
> +
> +       public void setName(String name) {
> +               this.name = name;
> +       }
> +
> +}
> Index:
D:/diff/java/server/trunk/src/org/red5/server/api/cache/ICac
heable.java
>
============================================================
=======
> ---
D:/diff/java/server/trunk/src/org/red5/server/api/cache/ICac
heable.java     (revision
> 0)
> +++
D:/diff/java/server/trunk/src/org/red5/server/api/cache/ICac
heable.java     (revision
> 0)
>  -0,0 +1,83 
> +package org.red5.server.api.cache;
> +
> +/*
> + * RED5 Open Source Flash Server - http://www.osflash.org/re
d5
> + *
> + * Copyright (c) 2006 by respective authors (see
below). All rights reserved.
> + *
> + * This library is free software; you can redistribute
it and/or
> modify it under the
> + * terms of the GNU Lesser General Public License as
published by the
> Free Software
> + * Foundation; either version 2.1 of the License, or
(at your option)
> any later
> + * version.
> + *
> + * This library is distributed in the hope that it
will be useful,
> but WITHOUT ANY
> + * WARRANTY; without even the implied warranty of
MERCHANTABILITY or
> FITNESS FOR A
> + * PARTICULAR PURPOSE. See the GNU Lesser General
Public License for
> more details.
> + *
> + * You should have received a copy of the GNU Lesser
General Public
> License along
> + * with this library; if not, write to the Free
Software Foundation, Inc.,
> + * 59 Temple Place, Suite 330, Boston, MA 02111-1307
USA
> + */
> +
> +import org.apache.mina.common.ByteBuffer;
> +
> +/**
> + * Base interface for objects that can be made
cacheable.
> + *
> + * see ICacheStore
> + *
> + * http://www-128.ibm.com/developerworks/java/lib
rary/j-jtp01246.html
> + * http://java.sun.com/developer/technicalArticles/ALT/R
efObj/
> + * http://www.onjava.com/pub/a/onjava/2002/10/02/j
avanio.html?page=3
> + * http://csci.csusb.edu/turner/arch
ive/courses/aiit2004/proxy_cache_solution.html
> + *
> + * author The Red5 Project (red5osflash.org)
> + * author Paul Gregoire (mondaingmail.com)
> + */
> +public interface ICacheable {
> +
> +       /**
> +        * Returns <code>true</code> if the
object is cached, <code>false</code>
> +        * otherwise.
> +        *
> +        * return true or false
> +        */
> +       public boolean isCached();
> +
> +       /**
> +        * Sets a flag to represent the cached status
of a cacheable object.
> +        *
> +        * param cached
> +        */
> +       public void setCached(boolean cached);
> +
> +       /**
> +        * Returns the name of the cached object.
> +        *
> +        * return the name of the object
> +        */
> +       public String getName();
> +
> +       /**
> +        * Set the name of the cached object.
> +        *
> +        * param name
> +        *            the new name of the object
> +        */
> +       public void setName(String name);
> +
> +       /**
> +        * Returns the object contained within the
cacheable reference.
> +        *
> +        * return
> +        */
> +       public byte[] getBytes();
> +
> +       /**
> +        * Returns a readonly byte buffer.
> +        *
> +        * return
> +        */
> +       public ByteBuffer getByteBuffer();
> +
> +}
> Index:
D:/diff/java/server/trunk/src/org/red5/server/api/cache/ICac
heStore.java
>
============================================================
=======
> ---
D:/diff/java/server/trunk/src/org/red5/server/api/cache/ICac
heStore.java    (revision
> 0)
> +++
D:/diff/java/server/trunk/src/org/red5/server/api/cache/ICac
heStore.java    (revision
> 0)
>  -0,0 +1,84 
> +package org.red5.server.api.cache;
> +
> +/*
> + * RED5 Open Source Flash Server - http://www.osflash.org/re
d5
> + *
> + * Copyright (c) 2006 by respective authors (see
below). All rights reserved.
> + *
> + * This library is free software; you can redistribute
it and/or
> modify it under the
> + * terms of the GNU Lesser General Public License as
published by the
> Free Software
> + * Foundation; either version 2.1 of the License, or
(at your option)
> any later
> + * version.
> + *
> + * This library is distributed in the hope that it
will be useful,
> but WITHOUT ANY
> + * WARRANTY; without even the implied warranty of
MERCHANTABILITY or
> FITNESS FOR A
> + * PARTICULAR PURPOSE. See the GNU Lesser General
Public License for
> more details.
> + *
> + * You should have received a copy of the GNU Lesser
General Public
> License along
> + * with this library; if not, write to the Free
Software Foundation, Inc.,
> + * 59 Temple Place, Suite 330, Boston, MA 02111-1307
USA
> + */
> +
> +import java.lang.ref.SoftReference;
> +import java.util.Iterator;
> +
> +/**
> + * Storage for cacheable objects.
> + *
> + * author The Red5 Project (red5osflash.org)
> + * author Paul Gregoire (mondaingmail.com)
> + */
> +public interface ICacheStore {
> +
> +       /**
> +        * Offer an object to the cache with an
associated key.
> +        *
> +        * param key
> +        *            string name representing the
object
> +        * param obj
> +        *            cacheable object
> +        * return true if accepted, false otherwise
> +        */
> +       public boolean offer(String key, ICacheable
obj);
> +
> +       /**
> +        * Return a cached object with the given name.
> +        *
> +        * param name
> +        *            the name of the object to return
> +        * return the object or
<code>null</code> if no such object was found
> +        */
> +       public ICacheable get(String name);
> +
> +       /**
> +        * Delete the passed cached object.
> +        *
> +        * param obj
> +        *            the object to delete
> +        */
> +       public boolean remove(ICacheable obj);
> +
> +       /**
> +        * Delete the cached object with the given
name.
> +        *
> +        * param name
> +        *            the name of the object to delete
> +        */
> +       public boolean remove(String name);
> +
> +       /**
> +        * Return iterator over the names of all
already loaded objects in the
> +        * storage.
> +        *
> +        * return iterator over all objects names
> +        */
> +       public Iterator<String> getObjectNames();
> +
> +       /**
> +        * Return iterator over the already loaded
objects in the storage.
> +        *
> +        * return iterator over all objects
> +        */
> +       public Iterator<SoftReference<? extends
ICacheable>> getObjects();
> +
> +}
>
>
>
> Paul
>
> --
> The early bird may get the worm, but the second mouse
gets the cheese.
>

_______________________________________________
Red5devs mailing list
Red5devsosflash.org
http://osflash.org/mailman/listinfo/red5devs_osflash.org

[1]

about | contact  Other archives ( Real Estate discussion Medical topics )