update dev300-m58
[ooovba.git] / sc / inc / lookupcache.hxx
blob3414e49baf2ed70d26435b3cbea54daa566157ba
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: lookupcache.hxx,v $
10 * $Revision: 1.3 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 #ifndef INCLUDED_SC_LOOKUPCACHE_HXX
32 #define INCLUDED_SC_LOOKUPCACHE_HXX
34 #include "address.hxx"
35 #include "global.hxx"
36 #include "formula/token.hxx"
37 #include <svtools/listener.hxx>
38 #include <tools/string.hxx>
40 #include <hash_map>
42 class ScDocument;
45 /** Lookup cache for one range used with interpreter functions such as VLOOKUP
46 and MATCH. Caches query for a specific row and the resulting address looked
47 up, in case other lookups of the same query in the same row are to be
48 performed, which usually occur to obtain a different offset column of the
49 same query.
52 class ScLookupCache : public SvtListener
54 public:
56 enum Result
58 NOT_CACHED, /// Query not found in cache.
59 CRITERIA_DIFFERENT, /// Different criteria for same query position exists.
60 NOT_AVAILABLE, /// Criteria not available in lookup range.
61 FOUND /// Criteria found.
64 enum QueryOp
66 UNKNOWN,
67 EQUAL,
68 LESS_EQUAL,
69 GREATER_EQUAL
72 class QueryCriteria
74 union
76 double mfVal;
77 const String * mpStr;
79 bool mbAlloc : 1;
80 bool mbString : 1;
81 QueryOp meOp : 2;
83 void deleteString()
85 if (mbAlloc && mbString)
86 delete mpStr;
89 // prevent usage
90 QueryCriteria();
91 QueryCriteria & operator=( const QueryCriteria & r );
93 public:
95 explicit QueryCriteria( const ScQueryEntry & rEntry ) :
96 mfVal(0.0), mbAlloc(false), mbString(false)
98 switch (rEntry.eOp)
100 case SC_EQUAL :
101 meOp = EQUAL;
102 break;
103 case SC_LESS_EQUAL :
104 meOp = LESS_EQUAL;
105 break;
106 case SC_GREATER_EQUAL :
107 meOp = GREATER_EQUAL;
108 break;
109 default:
110 meOp = UNKNOWN;
111 DBG_ERRORFILE( "ScLookupCache::QueryCriteria not prepared for this ScQueryOp");
113 if (rEntry.bQueryByString)
114 setString( rEntry.pStr);
115 else
116 setDouble( rEntry.nVal);
118 QueryCriteria( const QueryCriteria & r ) :
119 mfVal( r.mfVal),
120 mbAlloc( false),
121 mbString( false),
122 meOp( r.meOp)
124 if (r.mbString && r.mpStr)
126 mpStr = new String( *r.mpStr);
127 mbAlloc = mbString = true;
130 ~QueryCriteria()
132 deleteString();
135 QueryOp getQueryOp() const { return meOp; }
137 void setDouble( double fVal )
139 deleteString();
140 mbAlloc = mbString = false;
141 mfVal = fVal;
144 void setString( const String * pStr )
146 deleteString();
147 mbAlloc = false;
148 mbString = true;
149 mpStr = pStr;
152 void setString( const String & rStr )
154 deleteString();
155 mbAlloc = mbString = true;
156 mpStr = new String( rStr);
159 bool operator==( const QueryCriteria & r ) const
161 return meOp == r.meOp && mbString == r.mbString &&
162 (mbString ? (*mpStr == *r.mpStr) : (mfVal == r.mfVal));
167 /// MUST be new'd because Notify() deletes.
168 ScLookupCache( ScDocument * pDoc, const ScRange & rRange );
169 virtual ~ScLookupCache();
170 /// Remove from document structure and delete (!) cache on modify hint.
171 virtual void Notify( SvtBroadcaster & rBC, const SfxHint & rHint );
173 /// @returns document address in o_rAddress if Result==FOUND
174 Result lookup( ScAddress & o_rResultAddress,
175 const QueryCriteria & rCriteria,
176 const ScAddress & rQueryAddress ) const;
178 /** Insert query and result.
179 @param bAvailable
180 Pass FALSE if the search didn't deliver a result. A subsequent
181 lookup() then will return Result::NOT_AVAILABLE.
182 @returns successful insertion.
184 bool insert( const ScAddress & rResultAddress,
185 const QueryCriteria & rCriteria,
186 const ScAddress & rQueryAddress,
187 const bool bAvailable );
189 inline const ScRange& getRange() const { return maRange; }
191 struct Hash
193 size_t operator()( const ScRange & rRange ) const
195 // Lookups are performed on the first column.
196 return rRange.hashStartColumn();
200 private:
202 struct QueryKey
204 SCROW mnRow;
205 SCTAB mnTab;
206 QueryOp meOp : 2;
208 QueryKey( const ScAddress & rAddress, const QueryOp eOp ) :
209 mnRow( rAddress.Row()),
210 mnTab( rAddress.Tab()),
211 meOp( eOp)
215 bool operator==( const QueryKey & r ) const
217 return mnRow == r.mnRow && mnTab == r.mnTab && meOp == r.meOp && meOp != UNKNOWN;
220 struct Hash
222 size_t operator()( const QueryKey & r ) const
224 return (static_cast<size_t>(r.mnTab) << 24) ^
225 (static_cast<size_t>(r.meOp) << 22) ^
226 static_cast<size_t>(r.mnRow);
231 struct QueryCriteriaAndResult
233 QueryCriteria maCriteria;
234 ScAddress maAddress;
236 QueryCriteriaAndResult( const QueryCriteria & rCriteria, const ScAddress & rAddress ) :
237 maCriteria( rCriteria),
238 maAddress( rAddress)
241 ~QueryCriteriaAndResult()
246 typedef ::std::hash_map< QueryKey, QueryCriteriaAndResult, QueryKey::Hash, ::std::equal_to< QueryKey > > QueryMap;
247 QueryMap maQueryMap;
248 ScRange maRange;
249 ScDocument * mpDoc;
251 // prevent usage
252 ScLookupCache( const ScLookupCache & );
253 ScLookupCache & operator=( const ScLookupCache & );
258 typedef ::std::hash_map< ScRange, ScLookupCache*, ScLookupCache::Hash, ::std::equal_to< ScRange > > ScLookupCacheMap;
260 #endif