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

com.droidlogix.dbflare.a2e.DbFlareResultCache Maven / Gradle / Ivy

There is a newer version: 1.0.8
Show newest version
package com.droidlogix.dbflare.a2e;

import com.google.common.primitives.Longs;

import java.lang.ref.SoftReference;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.DelayQueue;
import java.util.concurrent.Delayed;
import java.util.concurrent.TimeUnit;

/**
 * This class will handle the caching of result. It will cache those parse
 * JSON results based on the endpoint name and query string
 * Code based from https://explainjava.com/simple-in-memory-cache-java/
 * @author John Pili
 * @since 23/11/19
 */

public class DbFlareResultCache implements IDbFlareCache
{
	private final ConcurrentHashMap> items = new ConcurrentHashMap<>();
	private final DelayQueue delayedCacheObjects = new DelayQueue<>();

	public DbFlareResultCache()
	{
		Thread cleanupThread = new Thread(() -> {
			while(!Thread.currentThread().isInterrupted())
			{
				try
				{
					DbFlareDelayedCacheObject dbFlareDelayedCacheObject = delayedCacheObjects.take();
					items.remove(dbFlareDelayedCacheObject.getKey(), dbFlareDelayedCacheObject.getReference());
				}
				catch(InterruptedException interruptionException)
				{
					Thread.currentThread().interrupt();
				}
			}
		});
		cleanupThread.setDaemon(true);
		cleanupThread.start();
	}

	@Override
	public void set(String key, Object value, long periodInMillis)
	{
		try
		{
			if (key == null)
			{
				return;
			}

			if (value != null)
			{
				long expiryTime = System.currentTimeMillis() + periodInMillis;
				//System.out.println("Inserting key: " + key + " expiry = " + Long.toString(expiryTime));
				SoftReference reference = new SoftReference<>(value);
				items.put(key, reference);
				delayedCacheObjects.put(new DbFlareDelayedCacheObject(key, reference, expiryTime));
			}
		}
		catch(Exception exception)
		{
		}
	}

	@Override
	public Object get(String key)
	{
		try
		{
			return items.get(key).get();
		}
		catch(Exception exception)
		{
			return null;
		}
	}

	@Override
	public void delete(String key)
	{
		try
		{
			items.remove(key);
		}
		catch(Exception exception)
		{
			System.out.println(exception.getMessage());
		}
	}

	@Override
	public void deleteByTag(String tag)
	{
		try
		{
			for(Map.Entry> x : items.entrySet())
			{
				if(x.getKey().startsWith(tag))
				{
					delete(x.getKey());
				}
			}
		}
		catch(Exception exception)
		{
			System.out.println(exception.getMessage());
		}
	}

	@Override
	public void clear()
	{
		items.clear();
	}

	@Override
	public long size()
	{
		return items.size();
	}

	private static class DbFlareDelayedCacheObject implements Delayed
	{
		private final String key;
		private final SoftReference reference;
		private final long expiryTime;

		DbFlareDelayedCacheObject(String key, SoftReference value, long expiryTime)
		{
			this.key = key;
			this.reference = value;
			this.expiryTime = expiryTime;
		}

		public String getKey()
		{
			return key;
		}

		public SoftReference getReference()
		{
			return reference;
		}

		public long getExpiryTime()
		{
			return expiryTime;
		}

		@Override
		public long getDelay(TimeUnit unit)
		{
			return unit.convert(expiryTime - System.currentTimeMillis(), TimeUnit.MILLISECONDS);
		}

		@Override
		public int compareTo(Delayed o)
		{
			return Longs.compare(expiryTime, ((DbFlareDelayedCacheObject) o).expiryTime);
		}
	}
}