Changeset 5121


Ignore:
Timestamp:
Oct 9, 2009, 10:54:34 AM (12 years ago)
Author:
Nicklas Nordborg
Message:

References #1374: Caching of experimental factors

This should invalidate (delete) the cached snapshots when annotation values or the inheritance structure is changed.

Location:
trunk/src/core/net/sf/basedb
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/core/net/sf/basedb/core/Annotation.java

    r5120 r5121  
    449449    getData().getValues().setSingleValue(Values.getDataValue(value));
    450450    getData().setLastUpdate(new Date());
     451    getAnnotationSet().setSnapshotInvalid();
    451452  }
    452453
     
    508509    getData().getValues().replaceValues(Values.getDataValues(convertedValues));
    509510    getData().setLastUpdate(new Date());
     511    getAnnotationSet().setSnapshotInvalid();
    510512  }
    511513
  • trunk/src/core/net/sf/basedb/core/AnnotationSet.java

    r5120 r5121  
    2323package net.sf.basedb.core;
    2424
    25 import java.io.Serializable;
    26 import java.util.ArrayList;
    2725import java.util.Collections;
    2826import java.util.Date;
     
    3836import net.sf.basedb.core.query.Hql;
    3937import net.sf.basedb.core.snapshot.AnnotationSetSnapshot;
    40 import net.sf.basedb.core.snapshot.AnnotationSnapshot;
    4138import net.sf.basedb.core.snapshot.SnapshotManager;
    4239
     
    4542import net.sf.basedb.core.data.AnnotationTypeData;
    4643import net.sf.basedb.util.AnnotationUtil;
    47 import net.sf.basedb.util.StaticCache;
    4844import net.sf.basedb.util.filter.Filter;
    4945
     
    6864public class AnnotationSet
    6965  extends BasicItem<AnnotationSetData>
     66  implements Transactional
    7067{
    7168  /**
     
    124121
    125122  /**
     123    Load the id of the item that this annotation set belongs to.
    126124    @since 2.14
    127125  */
     
    137135 
    138136  /**
     137    Create a new annotation snapshot for the given annotation set.
     138    NOTE! This method will always create a new snapshot from the
     139    database. The snapshot is not saved in the cache.
     140    <p>
     141    It is recommended that snapshots are cached as files in the static cache
     142    since they are much quiker to load. Use {@link SnapshotManager#getSnapshot(DbControl, int)}
     143    is instead of this method.
     144   
     145    @param dc A DbControl to use for database access
     146    @param annotationSetId The ID of the annotation set
     147    @return A snapshot, or null if the annotation set with the given
     148      id doesn't exist
     149    @since 2.14
     150  */
     151  public static AnnotationSetSnapshot createSnapshot(DbControl dc, int annotationSetId)
     152  {
     153    AnnotationSetData set = HibernateUtil.loadData(dc.getHibernateSession(), AnnotationSetData.class, annotationSetId);
     154    if (set == null) return null;
     155   
     156    AnnotationSetSnapshot snapshot = new AnnotationSetSnapshot();
     157    snapshot.init(set);
     158    return snapshot;
     159  }
     160 
     161  /**
    139162    The item this annotation set belongs to.
    140163  */
    141164  private Annotatable item;
     165 
     166  /**
     167    Flag to indicate if this annotation set has been modified
     168    and the snapshot must be removed.
     169  */
     170  private boolean snapshotIsInvalid;
    142171 
    143172  /**
     
    229258  {
    230259    return PluginPermission.NO_PLUGIN;
     260  }
     261  /**
     262    Remove the cached snapshot if needed.
     263  */
     264  @Override
     265  void onBeforeCommit(Action action)
     266    throws BaseException
     267  {
     268    super.onBeforeCommit(action);
     269    if ((snapshotIsInvalid && action == Action.UPDATE) || action == Action.DELETE)
     270    {
     271      if (!SnapshotManager.removeSnapshot(getId()))
     272      {
     273        throw new BaseException("Could not remove cached snapshot for annotation set[id=" + getId() + "]");
     274      }
     275    }
    231276  }
    232277  // -------------------------------------------
     
    344389      a = Annotation.getNew(dc, annotationType, this);
    345390      getData().getAnnotations().put(annotationType.getData(), a.getData());
    346       dc.saveItemIf(this, a, false);
     391      dc.saveItemIf(this, a, false);
     392      setSnapshotInvalid();
    347393    }
    348394    return a;
     
    399445    the current transaction and not yet committed to the database are not included
    400446    in the result.
     447    <p>
     448    NOTE!!!! Do not use this method if you need to find many annotation in many items.
     449    It has bad performance. It is better to use the cached snapshots.
     450    See {@link SnapshotManager}.
    401451   
    402452    @param dc The DbControl to use for database access
     
    495545        Annotation a = dc.getItem(Annotation.class, ad);
    496546        dc.deleteItem(a);
     547        setSnapshotInvalid();
    497548      }
    498549    }
     
    530581    if (annotation == null) throw new InvalidUseOfNullException("annotation");
    531582    annotation.checkPermission(Permission.USE);
    532     getData().getInherited().add(annotation.getData());
     583    if (getData().getInherited().add(annotation.getData()))
     584    {
     585      setSnapshotInvalid();
     586    }
    533587  }
    534588 
     
    545599    checkPermission(Permission.WRITE);
    546600    if (annotation == null) throw new InvalidUseOfNullException("annotation");
    547     getData().getInherited().remove(annotation.getData());
     601    if (getData().getInherited().remove(annotation.getData()))
     602    {
     603      setSnapshotInvalid();
     604    }
    548605  }
    549606 
     
    623680    if (annotationSet == null) throw new InvalidUseOfNullException("annotationSet");
    624681    annotationSet.checkPermission(Permission.USE);
    625     getData().getInheritedSets().add(annotationSet.getData());
     682    if (getData().getInheritedSets().add(annotationSet.getData()))
     683    {
     684      setSnapshotInvalid();
     685    }
     686
    626687  }
    627688 
     
    638699    checkPermission(Permission.WRITE);
    639700    if (annotationSet == null) throw new InvalidUseOfNullException("annotationSet");
    640     getData().getInheritedSets().remove(annotationSet.getData());
     701    if (getData().getInheritedSets().remove(annotationSet.getData()))
     702    {
     703      setSnapshotInvalid();
     704    }
    641705  }
    642706
     
    781845        to.getValues().replaceValues(from.getValues().getValues());
    782846        to.setLastUpdate(new Date());
     847        setSnapshotInvalid();
    783848      }
    784849    }
     
    804869 
    805870  /**
    806     Create a new annotation snapshot for the given annotation set.
    807     NOTE! This method will create a new snapshot from the database.
    808     Snapshots can be cached as files which are much quicker to load.
    809     It is recommended that {@link SnapshotManager#getSnapshot(int)}
    810     is used instead of this method.
    811    
    812     @param dc A DbControl to use for database access
    813     @param annotationSetId The ID of the annotation set
    814     @return A snapshot, or null if the annotation set with the given
    815       id doens't exist
     871    Mark the snapshot (if it exists) of this annotation set as
     872    invalid. The snapshot will be removed when the transaction
     873    is committed. Once the snapshot has been marked as invalid
     874    it can't be unmarked.   
    816875    @since 2.14
    817876  */
    818   public static AnnotationSetSnapshot createSnapshot(DbControl dc, int annotationSetId)
    819   {
    820 
    821     AnnotationSetData set = HibernateUtil.loadData(dc.getHibernateSession(), AnnotationSetData.class, annotationSetId);
    822     if (set == null) return null;
    823    
    824     AnnotationSetSnapshot snapshot = new AnnotationSetSnapshot();
    825     snapshot.init(set);
    826     return snapshot;
    827   }
    828 
     877  public void setSnapshotInvalid()
     878  {
     879    this.snapshotIsInvalid = true;
     880  }
     881 
     882  /**
     883    Get the status of the 'invalid snapshot' flag.
     884    @return TRUE if the snapshot has been marked as invalid,
     885      FALSE if not
     886    @since 2.14
     887  */
     888  public boolean isSnapshotInvalid()
     889  {
     890    return snapshotIsInvalid;
     891  }
    829892 
    830893  private static class QueryRuntimeFilterImpl
  • trunk/src/core/net/sf/basedb/core/AnnotationType.java

    r4889 r5121  
    2424package net.sf.basedb.core;
    2525
     26import net.sf.basedb.core.data.AnnotationSetData;
    2627import net.sf.basedb.core.data.ParameterValueData;
    2728import net.sf.basedb.core.data.AnnotationTypeData;
     
    3233import net.sf.basedb.core.query.Expressions;
    3334import net.sf.basedb.core.query.Hql;
     35import net.sf.basedb.core.snapshot.SnapshotManager;
    3436import net.sf.basedb.info.AnnotationTypeInfo;
    3537import net.sf.basedb.info.ToTransferable;
     
    382384          if (isEnumeration())
    383385          {
    384             // Change the unit on all annotations
     386            // Change the unit on all annotations
     387            // The values should NOT be changed!!
    385388            org.hibernate.Query query = HibernateUtil.getPredefinedQuery(
    386389              getDbControl().getHibernateSession(),
     
    417420            query.setInteger("annotationType", getId());
    418421            HibernateUtil.executeUpdate(query);
     422           
     423            // We also need to invalidate all annotation set snapshots that
     424            // include this annotation type
     425            query = HibernateUtil.createQuery(getDbControl().getHibernateSession(),
     426              "SELECT a.annotationSet " +
     427              "FROM AnnotationData a " +
     428              "WHERE a.annotationType = :annotationType");
     429            query.setInteger("annotationType", getId());
     430            List<AnnotationSetData> tmp = HibernateUtil.loadList(AnnotationSetData.class, query, getSessionControl());
     431            for (AnnotationSetData as : tmp)
     432            {
     433              SnapshotManager.removeSnapshot(as.getId());
     434            }
    419435          }
    420436        }
  • trunk/src/core/net/sf/basedb/core/data/ParameterValueData.java

    r5056 r5121  
    2525import java.util.Arrays;
    2626import java.util.List;
     27
     28import net.sf.basedb.core.AnnotationSet;
    2729
    2830/**
     
    110112    for an {@link AnnotationData}, don't forget to also update
    111113    the last update timestamp: {@link AnnotationData#setLastUpdate(java.util.Date)}.
     114    and to invalidate the annotation set snapshot: {@link AnnotationSet#setSnapshotInvalid()}
    112115  */
    113116  @SuppressWarnings("unchecked")
     
    126129    for an {@link AnnotationData}, don't forget to also update
    127130    the last update timestamp: {@link AnnotationData#setLastUpdate(java.util.Date)}.
     131    and to invalidate the annotation set snapshot: {@link AnnotationSet#setSnapshotInvalid()}
    128132  */
    129133  @SuppressWarnings("unchecked")
  • trunk/src/core/net/sf/basedb/core/snapshot/SnapshotManager.java

    r5120 r5121  
    4848  private final Map<Integer, AnnotationSetSnapshot> snapshots;
    4949 
     50  public static String getCacheKey(int annotationSetId)
     51  {
     52    return "/snapshots-v" + AnnotationSetSnapshot.FILE_VERSION +
     53      "/annotation-set-" + annotationSetId + ".ser";
     54  }
     55 
     56  /**
     57    Removes a snapshot from the static cache.
     58    @param annotationSetId The ID of the annotation set 
     59    @return TRUE if the snapshot was removed or didn't
     60      exists to begin with, FALSE if it existed and could
     61      not be removed
     62  */
     63  public static boolean removeSnapshot(int annotationSetId)
     64  {
     65    StaticCache cache = Application.getStaticCache();
     66    String cacheKey = getCacheKey(annotationSetId);
     67    return cache.delete(cacheKey, 1000);
     68  }
     69 
    5070  /**
    5171    Create a new snapshot manager.
     
    7191    // Then check the static cache
    7292    StaticCache cache = Application.getStaticCache();
    73     String cacheKey = "/annotations/snapshot-set-" + annotationSetId +
    74       "-v" + AnnotationSetSnapshot.FILE_VERSION + ".ser";
     93    String cacheKey = getCacheKey(annotationSetId);
    7594    snapshot = (AnnotationSetSnapshot)cache.load(cacheKey, 1000);
    7695    if (snapshot == null)
  • trunk/src/core/net/sf/basedb/util/StaticCache.java

    r4977 r5121  
    437437  }
    438438 
     439  /**
     440    Deletes an object from the cache.
     441   
     442    @param key The cache key
     443    @param timeout A timeout in milliseconds to wait for a write lock
     444      on the requested cache entry
     445    @return TRUE if the cached object was deleted or if it didn't exist to
     446      begin with or if the static cache is disabled, FALSE is only returned
     447      if it is certain that the cached object still exists after this call
     448    @since 2.14
     449  */
     450  public boolean delete(String key, int timeout)
     451  {
     452    if (disabled) return true;
     453    validateKey(key);
     454    log.debug("Delete request for static cache: " + key);
     455    File f = new File(root, key);
     456    if (!f.exists())
     457    {
     458      log.debug("Cache entry doesn't exist: " + key);
     459      return true;
     460    }
     461    LockEntry lock = aquireLock(key, true, timeout);
     462    if (lock == null) return false;
     463    try
     464    {
     465      return f.delete();
     466    }
     467    finally
     468    {
     469      lock.writeLock().unlock();
     470    }
     471  }
     472 
    439473  private void validateKey(String key)
    440474  {
Note: See TracChangeset for help on using the changeset viewer.