Version 6.1.0.2, tag libreoffice-6.1.0.2
[LibreOffice.git] / sc / inc / lookupcache.hxx
blobfa55c2bcbced92b90303c3848a81b0e1ed080aed
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #ifndef INCLUDED_SC_INC_LOOKUPCACHE_HXX
21 #define INCLUDED_SC_INC_LOOKUPCACHE_HXX
23 #include "address.hxx"
24 #include <svl/listener.hxx>
26 #include <unordered_map>
28 class ScDocument;
29 struct ScQueryEntry;
31 /** Lookup cache for one range used with interpreter functions such as VLOOKUP
32 and MATCH. Caches query for a specific row and the resulting address looked
33 up, in case other lookups of the same query in the same row are to be
34 performed, which usually occur to obtain a different offset column of the
35 same query.
38 class ScLookupCache : public SvtListener
40 public:
42 enum Result
44 NOT_CACHED, /// Query not found in cache.
45 CRITERIA_DIFFERENT, /// Different criteria for same query position exists.
46 NOT_AVAILABLE, /// Criteria not available in lookup range.
47 FOUND /// Criteria found.
50 enum QueryOp
52 UNKNOWN,
53 EQUAL,
54 LESS_EQUAL,
55 GREATER_EQUAL
58 class QueryCriteria
60 union
62 double mfVal;
63 const OUString *mpStr;
65 bool mbAlloc;
66 bool mbString;
67 QueryOp meOp;
69 void deleteString()
71 if (mbAlloc && mbString)
72 delete mpStr;
75 QueryCriteria & operator=( const QueryCriteria & r ) = delete;
77 public:
79 explicit QueryCriteria( const ScQueryEntry & rEntry );
80 QueryCriteria( const QueryCriteria & r );
81 ~QueryCriteria();
83 QueryOp getQueryOp() const { return meOp; }
85 void setDouble( double fVal )
87 deleteString();
88 mbAlloc = mbString = false;
89 mfVal = fVal;
92 void setString( const OUString & rStr )
94 deleteString();
95 mbAlloc = mbString = true;
96 mpStr = new OUString( rStr);
99 bool operator==( const QueryCriteria & r ) const
101 return meOp == r.meOp && mbString == r.mbString &&
102 (mbString ? (*mpStr == *r.mpStr) : (mfVal == r.mfVal));
107 /// MUST be new'd because Notify() deletes.
108 ScLookupCache( ScDocument * pDoc, const ScRange & rRange );
109 virtual ~ScLookupCache() override;
110 /// Remove from document structure and delete (!) cache on modify hint.
111 virtual void Notify( const SfxHint& rHint ) override;
113 /// @returns document address in o_rAddress if Result==FOUND
114 Result lookup( ScAddress & o_rResultAddress,
115 const QueryCriteria & rCriteria,
116 const ScAddress & rQueryAddress ) const;
118 /** Insert query and result.
119 @param bAvailable
120 Pass sal_False if the search didn't deliver a result. A subsequent
121 lookup() then will return Result::NOT_AVAILABLE.
122 @returns successful insertion.
124 bool insert( const ScAddress & rResultAddress,
125 const QueryCriteria & rCriteria,
126 const ScAddress & rQueryAddress,
127 const bool bAvailable );
129 const ScRange& getRange() const { return maRange; }
131 struct Hash
133 size_t operator()( const ScRange & rRange ) const
135 // Lookups are performed on the first column.
136 return rRange.hashStartColumn();
140 private:
142 struct QueryKey
144 SCROW mnRow;
145 SCTAB mnTab;
146 QueryOp meOp;
148 QueryKey( const ScAddress & rAddress, const QueryOp eOp ) :
149 mnRow( rAddress.Row()),
150 mnTab( rAddress.Tab()),
151 meOp( eOp)
155 bool operator==( const QueryKey & r ) const
157 return mnRow == r.mnRow && mnTab == r.mnTab && meOp == r.meOp && meOp != UNKNOWN;
160 struct Hash
162 size_t operator()( const QueryKey & r ) const
164 return (static_cast<size_t>(r.mnTab) << 24) ^
165 (static_cast<size_t>(r.meOp) << 22) ^
166 static_cast<size_t>(r.mnRow);
171 struct QueryCriteriaAndResult
173 QueryCriteria maCriteria;
174 ScAddress maAddress;
176 QueryCriteriaAndResult( const QueryCriteria & rCriteria, const ScAddress & rAddress ) :
177 maCriteria( rCriteria),
178 maAddress( rAddress)
183 std::unordered_map< QueryKey, QueryCriteriaAndResult, QueryKey::Hash > maQueryMap;
184 ScRange maRange;
185 ScDocument * mpDoc;
187 ScLookupCache( const ScLookupCache & ) = delete;
188 ScLookupCache & operator=( const ScLookupCache & ) = delete;
192 #endif
194 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */