Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : : #ifndef INCLUDED_SC_LOOKUPCACHE_HXX
30 : : #define INCLUDED_SC_LOOKUPCACHE_HXX
31 : :
32 : : #include "address.hxx"
33 : : #include "global.hxx"
34 : : #include "formula/token.hxx"
35 : : #include <svl/listener.hxx>
36 : : #include <tools/string.hxx>
37 : :
38 : : #include <boost/unordered_map.hpp>
39 : :
40 : : class ScDocument;
41 : : struct ScQueryEntry;
42 : :
43 : : /** Lookup cache for one range used with interpreter functions such as VLOOKUP
44 : : and MATCH. Caches query for a specific row and the resulting address looked
45 : : up, in case other lookups of the same query in the same row are to be
46 : : performed, which usually occur to obtain a different offset column of the
47 : : same query.
48 : : */
49 : :
50 : : class ScLookupCache : public SvtListener
51 : : {
52 : : public:
53 : :
54 : : enum Result
55 : : {
56 : : NOT_CACHED, /// Query not found in cache.
57 : : CRITERIA_DIFFERENT, /// Different criteria for same query position exists.
58 : : NOT_AVAILABLE, /// Criteria not available in lookup range.
59 : : FOUND /// Criteria found.
60 : : };
61 : :
62 : : enum QueryOp
63 : : {
64 : : UNKNOWN,
65 : : EQUAL,
66 : : LESS_EQUAL,
67 : : GREATER_EQUAL
68 : : };
69 : :
70 : : class QueryCriteria
71 : : {
72 : : union
73 : : {
74 : : double mfVal;
75 : : const String * mpStr;
76 : : };
77 : : bool mbAlloc : 1;
78 : : bool mbString : 1;
79 : : QueryOp meOp : 2;
80 : :
81 : 720 : void deleteString()
82 : : {
83 [ + + ][ + - ]: 720 : if (mbAlloc && mbString)
84 [ + - ]: 180 : delete mpStr;
85 : 720 : }
86 : :
87 : : // prevent usage
88 : : QueryCriteria();
89 : : QueryCriteria & operator=( const QueryCriteria & r );
90 : :
91 : : public:
92 : :
93 : : explicit QueryCriteria( const ScQueryEntry & rEntry );
94 : : QueryCriteria( const QueryCriteria & r );
95 : : ~QueryCriteria();
96 : :
97 : 288 : QueryOp getQueryOp() const { return meOp; }
98 : :
99 : 99 : void setDouble( double fVal )
100 : : {
101 : 99 : deleteString();
102 : 99 : mbAlloc = mbString = false;
103 : 99 : mfVal = fVal;
104 : 99 : }
105 : :
106 : : void setString( const String * pStr )
107 : : {
108 : : deleteString();
109 : : mbAlloc = false;
110 : : mbString = true;
111 : : mpStr = pStr;
112 : : }
113 : :
114 : 45 : void setString( const String & rStr )
115 : : {
116 : 45 : deleteString();
117 : 45 : mbAlloc = mbString = true;
118 [ + - ]: 45 : mpStr = new String( rStr);
119 : 45 : }
120 : :
121 : 0 : bool operator==( const QueryCriteria & r ) const
122 : : {
123 : : return meOp == r.meOp && mbString == r.mbString &&
124 [ # # ][ # # ]: 0 : (mbString ? (*mpStr == *r.mpStr) : (mfVal == r.mfVal));
[ # # ][ # # ]
[ # # ]
125 : : }
126 : :
127 : : };
128 : :
129 : : /// MUST be new'd because Notify() deletes.
130 : : ScLookupCache( ScDocument * pDoc, const ScRange & rRange );
131 : : virtual ~ScLookupCache();
132 : : /// Remove from document structure and delete (!) cache on modify hint.
133 : : virtual void Notify( SvtBroadcaster & rBC, const SfxHint & rHint );
134 : :
135 : : /// @returns document address in o_rAddress if Result==FOUND
136 : : Result lookup( ScAddress & o_rResultAddress,
137 : : const QueryCriteria & rCriteria,
138 : : const ScAddress & rQueryAddress ) const;
139 : :
140 : : /** Insert query and result.
141 : : @param bAvailable
142 : : Pass sal_False if the search didn't deliver a result. A subsequent
143 : : lookup() then will return Result::NOT_AVAILABLE.
144 : : @returns successful insertion.
145 : : */
146 : : bool insert( const ScAddress & rResultAddress,
147 : : const QueryCriteria & rCriteria,
148 : : const ScAddress & rQueryAddress,
149 : : const bool bAvailable );
150 : :
151 : 36 : inline const ScRange& getRange() const { return maRange; }
152 : :
153 : : struct Hash
154 : : {
155 : 153 : size_t operator()( const ScRange & rRange ) const
156 : : {
157 : : // Lookups are performed on the first column.
158 : 153 : return rRange.hashStartColumn();
159 : : }
160 : : };
161 : :
162 : : private:
163 : :
164 : : struct QueryKey
165 : : {
166 : : SCROW mnRow;
167 : : SCTAB mnTab;
168 : : QueryOp meOp : 2;
169 : :
170 : 288 : QueryKey( const ScAddress & rAddress, const QueryOp eOp ) :
171 : 288 : mnRow( rAddress.Row()),
172 : 288 : mnTab( rAddress.Tab()),
173 : 576 : meOp( eOp)
174 : : {
175 : 288 : }
176 : :
177 : 0 : bool operator==( const QueryKey & r ) const
178 : : {
179 [ # # ][ # # ]: 0 : return mnRow == r.mnRow && mnTab == r.mnTab && meOp == r.meOp && meOp != UNKNOWN;
[ # # ][ # # ]
180 : : }
181 : :
182 : : struct Hash
183 : : {
184 : 279 : size_t operator()( const QueryKey & r ) const
185 : : {
186 : : return (static_cast<size_t>(r.mnTab) << 24) ^
187 : : (static_cast<size_t>(r.meOp) << 22) ^
188 : 279 : static_cast<size_t>(r.mnRow);
189 : : }
190 : : };
191 : : };
192 : :
193 : 288 : struct QueryCriteriaAndResult
194 : : {
195 : : QueryCriteria maCriteria;
196 : : ScAddress maAddress;
197 : :
198 : 144 : QueryCriteriaAndResult( const QueryCriteria & rCriteria, const ScAddress & rAddress ) :
199 : : maCriteria( rCriteria),
200 : 144 : maAddress( rAddress)
201 : : {
202 : 144 : }
203 : 432 : ~QueryCriteriaAndResult()
204 : 432 : {
205 : 432 : }
206 : : };
207 : :
208 : : typedef ::boost::unordered_map< QueryKey, QueryCriteriaAndResult, QueryKey::Hash, ::std::equal_to< QueryKey > > QueryMap;
209 : : QueryMap maQueryMap;
210 : : ScRange maRange;
211 : : ScDocument * mpDoc;
212 : :
213 : : // prevent usage
214 : : ScLookupCache( const ScLookupCache & );
215 : : ScLookupCache & operator=( const ScLookupCache & );
216 : :
217 : : };
218 : :
219 : :
220 : : typedef ::boost::unordered_map< ScRange, ScLookupCache*, ScLookupCache::Hash, ::std::equal_to< ScRange > > ScLookupCacheMap;
221 : :
222 : : #endif
223 : :
224 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|