~ubuntu-branches/ubuntu/quantal/ehcache/quantal

« back to all changes in this revision

Viewing changes to src/main/java/net/sf/ehcache/store/MemoryOnlyStore.java

  • Committer: Package Import Robot
  • Author(s): Miguel Landaeta
  • Date: 2012-03-01 19:15:46 UTC
  • mfrom: (1.1.6) (2.1.7 sid)
  • Revision ID: package-import@ubuntu.com-20120301191546-rvlk8tomip0c2m9p
Tags: 2.5.0-1
* Team upload.
* New upstream release. (Closes: #661450).
* Bump Standards-Version to 3.9.3. No changes were required.
* Fix lintian warning with copyright file.
* Remove unnecessary dependencies on JRE for libehcache-java.
* Wrap list of dependencies and uploaders.
* Fix clean target by adding a mh_clean call, to allow twice in a row builds.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/**
 
2
 *  Copyright 2003-2010 Terracotta, Inc.
 
3
 *
 
4
 *  Licensed under the Apache License, Version 2.0 (the "License");
 
5
 *  you may not use this file except in compliance with the License.
 
6
 *  You may obtain a copy of the License at
 
7
 *
 
8
 *      http://www.apache.org/licenses/LICENSE-2.0
 
9
 *
 
10
 *  Unless required by applicable law or agreed to in writing, software
 
11
 *  distributed under the License is distributed on an "AS IS" BASIS,
 
12
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 
13
 *  See the License for the specific language governing permissions and
 
14
 *  limitations under the License.
 
15
 */
 
16
 
 
17
package net.sf.ehcache.store;
 
18
 
 
19
import net.sf.ehcache.CacheException;
 
20
import net.sf.ehcache.Ehcache;
 
21
import net.sf.ehcache.Element;
 
22
import net.sf.ehcache.config.CacheConfiguration;
 
23
import net.sf.ehcache.pool.Pool;
 
24
import net.sf.ehcache.search.Attribute;
 
25
import net.sf.ehcache.search.Result;
 
26
import net.sf.ehcache.search.Results;
 
27
import net.sf.ehcache.search.aggregator.AggregatorInstance;
 
28
import net.sf.ehcache.search.attribute.AttributeExtractor;
 
29
import net.sf.ehcache.search.expression.Criteria;
 
30
import net.sf.ehcache.search.impl.AggregateOnlyResult;
 
31
import net.sf.ehcache.search.impl.BaseResult;
 
32
import net.sf.ehcache.search.impl.OrderComparator;
 
33
import net.sf.ehcache.search.impl.ResultImpl;
 
34
import net.sf.ehcache.search.impl.ResultsImpl;
 
35
import net.sf.ehcache.transaction.SoftLock;
 
36
 
 
37
import java.util.ArrayList;
 
38
import java.util.Collections;
 
39
import java.util.HashMap;
 
40
import java.util.List;
 
41
import java.util.Map;
 
42
import java.util.concurrent.ConcurrentHashMap;
 
43
 
 
44
/**
 
45
 * A memory-only store with support for all caching features.
 
46
 *
 
47
 * @author Ludovic Orban
 
48
 */
 
49
public final class MemoryOnlyStore extends FrontEndCacheTier<NullStore, MemoryStore> {
 
50
 
 
51
    private static final Object[] EMPTY_OBJECT_ARRAY = new Object[0];
 
52
 
 
53
    private final Map<String, AttributeExtractor> attributeExtractors = new ConcurrentHashMap<String, AttributeExtractor>();
 
54
    private final Map<String, Attribute> searchAttributes = new ConcurrentHashMap<String, Attribute>();
 
55
 
 
56
 
 
57
    private MemoryOnlyStore(CacheConfiguration cacheConfiguration, NullStore cache, MemoryStore authority) {
 
58
        super(cache, authority, cacheConfiguration.getCopyStrategy(), cacheConfiguration.isCopyOnWrite(), cacheConfiguration.isCopyOnRead());
 
59
    }
 
60
 
 
61
    /**
 
62
     * Create an instance of MemoryStore
 
63
     * @param cache the cache
 
64
     * @param onHeapPool the on heap pool
 
65
     * @return an instance of MemoryStore
 
66
     */
 
67
    public static Store create(Ehcache cache, Pool onHeapPool) {
 
68
        final NullStore nullStore = NullStore.create();
 
69
        final MemoryStore memoryStore = NotifyingMemoryStore.create(cache, onHeapPool);
 
70
        return new MemoryOnlyStore(cache.getCacheConfiguration(), nullStore, memoryStore);
 
71
    }
 
72
 
 
73
    /**
 
74
     * {@inheritDoc}
 
75
     */
 
76
    @Override
 
77
    public void setAttributeExtractors(Map<String, AttributeExtractor> extractors) {
 
78
        this.attributeExtractors.putAll(extractors);
 
79
 
 
80
        for (String name : extractors.keySet()) {
 
81
            searchAttributes.put(name, new Attribute(name));
 
82
        }
 
83
    }
 
84
 
 
85
    /**
 
86
     * {@inheritDoc}
 
87
     */
 
88
    @Override
 
89
    public Results executeQuery(StoreQuery query) {
 
90
        Criteria c = query.getCriteria();
 
91
 
 
92
        List<AggregatorInstance<?>> aggregators = query.getAggregatorInstances();
 
93
 
 
94
 
 
95
        boolean includeResults = query.requestsKeys() || query.requestsValues() || !query.requestedAttributes().isEmpty();
 
96
 
 
97
        ArrayList<Result> results = new ArrayList<Result>();
 
98
 
 
99
        boolean hasOrder = !query.getOrdering().isEmpty();
 
100
 
 
101
        boolean anyMatches = false;
 
102
 
 
103
        for (Element element : authority.elementSet()) {
 
104
            if (!hasOrder && query.maxResults() >= 0 && results.size() == query.maxResults()) {
 
105
                break;
 
106
            }
 
107
            if (element.getObjectValue() instanceof SoftLock) {
 
108
                continue;
 
109
            }
 
110
 
 
111
            if (c.execute(element, attributeExtractors)) {
 
112
                anyMatches = true;
 
113
 
 
114
                if (includeResults) {
 
115
                    final Map<String, Object> attributes;
 
116
                    if (query.requestedAttributes().isEmpty()) {
 
117
                        attributes = Collections.emptyMap();
 
118
                    } else {
 
119
                        attributes = new HashMap<String, Object>();
 
120
                        for (Attribute attribute : query.requestedAttributes()) {
 
121
                            String name = attribute.getAttributeName();
 
122
                            attributes.put(name, attributeExtractors.get(name).attributeFor(element, name));
 
123
                        }
 
124
                    }
 
125
 
 
126
                    final Object[] sortAttributes;
 
127
                    List<StoreQuery.Ordering> orderings = query.getOrdering();
 
128
                    if (orderings.isEmpty()) {
 
129
                        sortAttributes = EMPTY_OBJECT_ARRAY;
 
130
                    } else {
 
131
                        sortAttributes = new Object[orderings.size()];
 
132
                        for (int i = 0; i < sortAttributes.length; i++) {
 
133
                            String name = orderings.get(i).getAttribute().getAttributeName();
 
134
                            sortAttributes[i] = attributeExtractors.get(name).attributeFor(element, name);
 
135
                        }
 
136
                    }
 
137
 
 
138
 
 
139
                    results.add(new ResultImpl(element.getObjectKey(), element.getObjectValue(), query, attributes, sortAttributes));
 
140
                }
 
141
 
 
142
                for (AggregatorInstance<?> aggregator : aggregators) {
 
143
                    Attribute<?> attribute = aggregator.getAttribute();
 
144
                    if (attribute == null) {
 
145
                        aggregator.accept(null);
 
146
                    } else {
 
147
                        Object val = attributeExtractors.get(attribute.getAttributeName()).attributeFor(element,
 
148
                                attribute.getAttributeName());
 
149
                        aggregator.accept(val);
 
150
                    }
 
151
                }
 
152
            }
 
153
        }
 
154
 
 
155
        if (hasOrder) {
 
156
            Collections.sort(results, new OrderComparator(query.getOrdering()));
 
157
 
 
158
            // trim results to max length if necessary
 
159
            int max = query.maxResults();
 
160
            if (max >= 0 && (results.size() > max)) {
 
161
                results.subList(max, results.size()).clear();
 
162
                results.trimToSize();
 
163
            }
 
164
        }
 
165
 
 
166
 
 
167
        List<Object> aggregateResults = aggregators.isEmpty() ? Collections.emptyList() : new ArrayList<Object>();
 
168
        for (AggregatorInstance<?> aggregator : aggregators) {
 
169
            aggregateResults.add(aggregator.aggregateResult());
 
170
        }
 
171
 
 
172
        if (anyMatches && !includeResults && !aggregateResults.isEmpty()) {
 
173
            // add one row in the results if the only thing included was aggregators and anything matched
 
174
            results.add(new AggregateOnlyResult(query));
 
175
        }
 
176
 
 
177
 
 
178
        if (!aggregateResults.isEmpty()) {
 
179
            for (Result result : results) {
 
180
                // XXX: yucky cast
 
181
                ((BaseResult)result).setAggregateResults(aggregateResults);
 
182
            }
 
183
        }
 
184
 
 
185
        return new ResultsImpl(results, query.requestsKeys(), query.requestsValues(),
 
186
                !query.requestedAttributes().isEmpty(), anyMatches && !aggregateResults.isEmpty());
 
187
    }
 
188
 
 
189
    /**
 
190
     * {@inheritDoc}
 
191
     */
 
192
    @Override
 
193
    public <T> Attribute<T> getSearchAttribute(String attributeName) throws CacheException {
 
194
        return searchAttributes.get(attributeName);
 
195
    }
 
196
 
 
197
    /**
 
198
     * {@inheritDoc}
 
199
     */
 
200
    public Object getMBean() {
 
201
        return null;
 
202
    }
 
203
}