Skip to main content

detect sequence changes at plugin level

Comments

5 comments

  • Geneious Team

    Hi Adrian, 

    The short answer to your question is no.

    Can you elaborate on why you need this?  There may be a different approach that would work for you.

    Cheers,
    Matthew

    0
  • Adrian

    Hi Matt,

    I need to perform an expensive calculation that is needed for both stats and graphs and potentially other places only when the sequence changes. Now I'm doing it in multiple places which is redundant and expensive and messy.

    Maybe we add a listener on AnnotatedPluginDocument.

    Cheers,

    Adrian

    0
  • Matthew Cheung

    Hi Adrian,

    If you're working with a SequenceGraph then Geneious will tell your graph to cancel the current calculation and start again.  So you probably don't need a document listener.  This is done by returning true from the isCancelled() method on the ProgressListener that was given to the calculation method.  Geneious will then call the calculation method again.

    If you need to synchronise the calculation from multiple places that support this same behaviour then you could consider using a static calculator class that caches and re-uses the result based on the URN and modified date of the document.  If you keep the cache in memory, you'll have to be careful to discard results if they are no longer needed or you'll end up causing a memory leak.

    ---

    Regarding a document listener, it actually looks like I was mistaken.  You can add a listener using:

    AnnotatedPluginDocument.addWeakReferenceDocumentListener()

    It'll only be fired when the document is saved though rather than responding to live edits like with the SequenceGraph.  So if that is OK, then you could go with that instead of my earlier suggestion.

    Cheers,
    Matthew

    0
  • Adrian

    Matt,

    I'm already using a singleton to cache the results in the memory and I clear that in several places in the code but I'm looking for a place where I can put that to that to make sure it's not kept in memory when moving to another document.

     

     

    Cheers,

    Adrian

    0
  • Matthew Cheung

    Hi Adrian,

    One approach would be to have a system for notifying when the data is no longer needed.  This will only work if all the different places you need the data also have a way of knowing when they no longer need it.  You would need to increment a number when a new request is made and decrement it when notified of no longer being needed.  When it reaches zero you can discard the data.

    Another perhaps easier approach might be to use a WeakReference for keeping track of the mapping from the document to your object. See https://docs.oracle.com/javase/8/docs/api/java/lang/ref/WeakReference.html

    Somewhere in your class you can maintain a map similar to:

    Map<WeakReference<AnnotatedPluginDocument>, DataObject> dataByDocument

    Then have a cleanup thread run in the background that periodically checks the keys in the map.  If the WeakReference ends up pointing to null then it means the AnnotatedPluginDocument was garbage collected i.e. no longer used and you can discard the DataObject.

    Make sure not to strongly reference the AnnotatedPluginDocument anywhere otherwise you'll prevent the WeakReference from being garbage collected.

    Cheers,
    Matthew

    0

Please sign in to leave a comment.