View Javadoc

1   /*
2    * Copyright James Leigh (c) 2006, 2007.
3    *
4    * Licensed under the Aduna BSD-style license.
5    */
6   package org.openrdf.repository.augur.model;
7   
8   import java.lang.ref.SoftReference;
9   import java.util.ArrayList;
10  import java.util.HashMap;
11  import java.util.List;
12  import java.util.Map;
13  
14  import info.aduna.iteration.CloseableIteration;
15  import info.aduna.iteration.CloseableIteratorIteration;
16  import info.aduna.iteration.EmptyIteration;
17  
18  import org.openrdf.model.Resource;
19  import org.openrdf.model.Statement;
20  import org.openrdf.model.Value;
21  import org.openrdf.query.QueryEvaluationException;
22  
23  /**
24   * Extends the AugurStatementNode to allow caching of results.
25   * 
26   * @author James Leigh
27   * 
28   */
29  public abstract class CachableAugurNode extends AugurStatementNode {
30  
31  	private static final EmptyIteration<Statement, QueryEvaluationException> EMPTY_ITERATOR = new EmptyIteration<Statement, QueryEvaluationException>();
32  
33  	private SoftReference<Map<Resource, List<Statement>>> _statements;
34  
35  	private boolean cacheEnabled = true;
36  
37  	private int _version;
38  
39  	public CloseableIteration<? extends Statement, QueryEvaluationException> getStatements(Resource subj,
40  			Value obj)
41  	{
42  		if (_statements == null)
43  			return null;
44  		Map<Resource, List<Statement>> cache = _statements.get();
45  		if (cache == null)
46  			return null;
47  		Resource carried = getCarriedOverResource(subj, obj);
48  		List<Statement> result = cache.get(carried);
49  		if (result == null)
50  			return EMPTY_ITERATOR;
51  		return new CloseableIteratorIteration<Statement, QueryEvaluationException>(result.iterator());
52  	}
53  
54  	public boolean isCacheEnabled(int version) {
55  		if (!cacheEnabled)
56  			return false;
57  		if (_statements == null)
58  			return true;
59  		if (_statements.get() == null)
60  			return false;
61  		if (_version != version) {
62  			cacheEnabled = false;
63  			_statements = null;
64  		}
65  		return cacheEnabled;
66  	}
67  
68  	public void enableCache() {
69  		cacheEnabled = true;
70  	}
71  
72  	public void initCache(int version) {
73  		Map<Resource, List<Statement>> cache;
74  		cache = new HashMap<Resource, List<Statement>>();
75  		cacheEnabled = false;
76  		_statements = new SoftReference<Map<Resource, List<Statement>>>(cache);
77  		_version = version;
78  	}
79  
80  	public void cacheStatement(Statement stmt) {
81  		Map<Resource, List<Statement>> cache = _statements.get();
82  		if (cache == null)
83  			return;
84  		Resource subj = stmt.getSubject();
85  		Value obj = stmt.getObject();
86  		Resource key = getCarriedOverResource(subj, obj);
87  		List<Statement> list = cache.get(key);
88  		if (list == null)
89  			cache.put(key, list = new ArrayList<Statement>());
90  		list.add(stmt);
91  	}
92  
93  	public abstract Resource getCarriedOverResource(Resource subj, Value obj);
94  
95  }