src/core/net/sf/basedb/util/listable/SourceItemTransformerWithCache.java

Code
Comments
Other
Rev Date Author Line
7770 10 Feb 20 nicklas 1 /**
7770 10 Feb 20 nicklas 2   $Id$
7770 10 Feb 20 nicklas 3
7770 10 Feb 20 nicklas 4   Copyright (C) 2015 Nicklas Nordborg
7770 10 Feb 20 nicklas 5
7770 10 Feb 20 nicklas 6   This file is part of BASE - BioArray Software Environment.
7770 10 Feb 20 nicklas 7   Available at http://base.thep.lu.se/
7770 10 Feb 20 nicklas 8
7770 10 Feb 20 nicklas 9   BASE is free software; you can redistribute it and/or
7770 10 Feb 20 nicklas 10   modify it under the terms of the GNU General Public License
7770 10 Feb 20 nicklas 11   as published by the Free Software Foundation; either version 3
7770 10 Feb 20 nicklas 12   of the License, or (at your option) any later version.
7770 10 Feb 20 nicklas 13
7770 10 Feb 20 nicklas 14   BASE is distributed in the hope that it will be useful,
7770 10 Feb 20 nicklas 15   but WITHOUT ANY WARRANTY; without even the implied warranty of
7770 10 Feb 20 nicklas 16   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
7770 10 Feb 20 nicklas 17   GNU General Public License for more details.
7770 10 Feb 20 nicklas 18
7770 10 Feb 20 nicklas 19   You should have received a copy of the GNU General Public License
7770 10 Feb 20 nicklas 20   along with BASE. If not, see <http://www.gnu.org/licenses/>.
7770 10 Feb 20 nicklas 21 */
7770 10 Feb 20 nicklas 22 package net.sf.basedb.util.listable;
7770 10 Feb 20 nicklas 23
7772 17 Feb 20 nicklas 24 import java.util.Collections;
7770 10 Feb 20 nicklas 25 import java.util.List;
7770 10 Feb 20 nicklas 26 import java.util.Set;
7770 10 Feb 20 nicklas 27
7770 10 Feb 20 nicklas 28 import net.sf.basedb.core.Item;
7770 10 Feb 20 nicklas 29 import net.sf.basedb.core.SyncFilter.SourceItemTransform;
7770 10 Feb 20 nicklas 30 import net.sf.basedb.util.listable.TransformCache.CacheKey;
7770 10 Feb 20 nicklas 31
7770 10 Feb 20 nicklas 32 /**
7770 10 Feb 20 nicklas 33   This is a wrapper transformer factory that can be applied to any other
7770 10 Feb 20 nicklas 34   factory in order to provide support for caching.
7770 10 Feb 20 nicklas 35   
7770 10 Feb 20 nicklas 36   The cache holds the result from {@link SourceItemTransformer#transform(TransformContext, Set)}
7770 10 Feb 20 nicklas 37   so that if the same set of source ids are provided it will pick the cache result if
7770 10 Feb 20 nicklas 38   available and only forward to the wrapped factory in case no old result exists or if it
7770 10 Feb 20 nicklas 39   is too old.
7770 10 Feb 20 nicklas 40
7770 10 Feb 20 nicklas 41   @author Nicklas
7770 10 Feb 20 nicklas 42   @since 3.16
7770 10 Feb 20 nicklas 43 */
7770 10 Feb 20 nicklas 44 public class SourceItemTransformerWithCache 
7770 10 Feb 20 nicklas 45   implements SourceItemTransformerFactory 
7770 10 Feb 20 nicklas 46 {
7770 10 Feb 20 nicklas 47
7770 10 Feb 20 nicklas 48   private final SourceItemTransformerFactory factory;
8094 04 Nov 22 nicklas 49   private final String cacheRegion;
7770 10 Feb 20 nicklas 50   
7770 10 Feb 20 nicklas 51   /**
7770 10 Feb 20 nicklas 52     Create a new source item transformer chain. The chain
7770 10 Feb 20 nicklas 53     must contain at least one element and all steps must have
7770 10 Feb 20 nicklas 54     matching source and target item types.
7770 10 Feb 20 nicklas 55     @throws IllegalArgumentException If the chain is null or empty or have non-matching
7770 10 Feb 20 nicklas 56       transformation steps
7770 10 Feb 20 nicklas 57   */
7770 10 Feb 20 nicklas 58   public SourceItemTransformerWithCache(SourceItemTransformerFactory factory)
7770 10 Feb 20 nicklas 59   {
8094 04 Nov 22 nicklas 60     this(factory, null);
8094 04 Nov 22 nicklas 61   }
8094 04 Nov 22 nicklas 62
8094 04 Nov 22 nicklas 63   public SourceItemTransformerWithCache(SourceItemTransformerFactory factory, String cacheRegion)
8094 04 Nov 22 nicklas 64   {
7770 10 Feb 20 nicklas 65     this.factory = factory;
8094 04 Nov 22 nicklas 66     this.cacheRegion = cacheRegion;
7770 10 Feb 20 nicklas 67   }
8094 04 Nov 22 nicklas 68   
8094 04 Nov 22 nicklas 69   
7770 10 Feb 20 nicklas 70   @Override
7770 10 Feb 20 nicklas 71   public Item getTargetItem() 
7770 10 Feb 20 nicklas 72   {
7770 10 Feb 20 nicklas 73     return factory.getTargetItem();
7770 10 Feb 20 nicklas 74   }
7770 10 Feb 20 nicklas 75
7770 10 Feb 20 nicklas 76   @Override
7770 10 Feb 20 nicklas 77   public List<Item> getSupportedSourceItems(SourceItemTransform transform) 
7770 10 Feb 20 nicklas 78   {
7770 10 Feb 20 nicklas 79     return factory.getSupportedSourceItems(transform);
7770 10 Feb 20 nicklas 80   }
7770 10 Feb 20 nicklas 81
7770 10 Feb 20 nicklas 82   @Override
7770 10 Feb 20 nicklas 83   public SourceItemTransformer create(Item sourceItemType, SourceItemTransform transform) 
7770 10 Feb 20 nicklas 84   {
8094 04 Nov 22 nicklas 85     return new TransformerWithCache(factory.create(sourceItemType, transform), transform, cacheRegion);
7770 10 Feb 20 nicklas 86   }
7770 10 Feb 20 nicklas 87   
7770 10 Feb 20 nicklas 88
7770 10 Feb 20 nicklas 89   static class TransformerWithCache
7770 10 Feb 20 nicklas 90     implements SourceItemTransformer
7770 10 Feb 20 nicklas 91   {
7770 10 Feb 20 nicklas 92
7770 10 Feb 20 nicklas 93     private final SourceItemTransformer transformer;
7770 10 Feb 20 nicklas 94     private final SourceItemTransform transform;
8094 04 Nov 22 nicklas 95     private final String cacheRegion;
7770 10 Feb 20 nicklas 96     
8094 04 Nov 22 nicklas 97     TransformerWithCache(SourceItemTransformer transformer, SourceItemTransform transform, String cacheRegion)
7770 10 Feb 20 nicklas 98     {
7770 10 Feb 20 nicklas 99       this.transformer = transformer;
7770 10 Feb 20 nicklas 100       this.transform = transform;
8094 04 Nov 22 nicklas 101       this.cacheRegion = cacheRegion;
7770 10 Feb 20 nicklas 102     }
7770 10 Feb 20 nicklas 103     
7770 10 Feb 20 nicklas 104     @Override
7770 10 Feb 20 nicklas 105     public Item getSourceItemType() 
7770 10 Feb 20 nicklas 106     {
7770 10 Feb 20 nicklas 107       return transformer.getSourceItemType();
7770 10 Feb 20 nicklas 108     }
7770 10 Feb 20 nicklas 109
7770 10 Feb 20 nicklas 110     @Override
7770 10 Feb 20 nicklas 111     public Item getTargetItemType() 
7770 10 Feb 20 nicklas 112     {
7770 10 Feb 20 nicklas 113       return transformer.getTargetItemType();
7770 10 Feb 20 nicklas 114     }
7770 10 Feb 20 nicklas 115
7770 10 Feb 20 nicklas 116     /**
7770 10 Feb 20 nicklas 117       If a cache exists check if it has data for this transform already.
7770 10 Feb 20 nicklas 118       If not, forward to the parent transformer and then cache the result
7770 10 Feb 20 nicklas 119       for future use.
7770 10 Feb 20 nicklas 120     */
7770 10 Feb 20 nicklas 121     @Override
7770 10 Feb 20 nicklas 122     public Set<Integer> transform(TransformContext context, Set<Integer> source) 
7770 10 Feb 20 nicklas 123     {
7770 10 Feb 20 nicklas 124       Set<Integer> target = null;
7770 10 Feb 20 nicklas 125       TransformCache cache = context.getCache();
7770 10 Feb 20 nicklas 126       CacheKey key = null;
7770 10 Feb 20 nicklas 127       if (cache != null)
7770 10 Feb 20 nicklas 128       {
8094 04 Nov 22 nicklas 129         key = TransformCache.getKey(cacheRegion, getSourceItemType(), getTargetItemType(), transform, source);
7770 10 Feb 20 nicklas 130         target = cache.get(key);
7770 10 Feb 20 nicklas 131       }
7770 10 Feb 20 nicklas 132       if (target == null)
7770 10 Feb 20 nicklas 133       {
7770 10 Feb 20 nicklas 134         target = transformer.transform(context, source);
7770 10 Feb 20 nicklas 135         if (cache != null) cache.store(key, target);
7770 10 Feb 20 nicklas 136       }
7772 17 Feb 20 nicklas 137       return Collections.unmodifiableSet(target);
7770 10 Feb 20 nicklas 138     }
7770 10 Feb 20 nicklas 139   }
7770 10 Feb 20 nicklas 140 }