Quellcodebibliothek Statistik Leitseite products/sources/formale Sprachen/C/LibreOffice/sc/inc/   (Office von Apache Version 25.8.3.2©)  Datei vom 5.10.2025 mit Größe 6 kB image not shown  

Quelle  lookupcache.hxx   Sprache: C

 
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */


#pragma once

#include "address.hxx"
#include <svl/listener.hxx>

#include <memory>
#include <unordered_map>

class ScDocument;
struct ScLookupCacheMap;
struct ScQueryEntry;
enum class LookupSearchMode;

/** Lookup cache for one range used with interpreter functions such as VLOOKUP
    and MATCH. Caches query for a specific row and the resulting address looked
    up, in case other lookups of the same query in the same row are to be
    performed, which usually occur to obtain a different offset column of the
    same query.
 */

class ScLookupCache final : public SvtListener
{
public:

    enum Result
    {
        NOT_CACHED,         /// Query not found in cache.
        CRITERIA_DIFFERENT, /// Different criteria for same query position exists.
        NOT_AVAILABLE,      /// Criteria not available in lookup range.
        FOUND               /// Criteria found.
    };

    enum QueryOp
    {
        UNKNOWN,
        EQUAL,
        LESS_EQUAL,
        GREATER_EQUAL
    };

    class QueryCriteria
    {
        union
        {
            double          mfVal;
            const OUString *mpStr;
        };
        bool                mbAlloc;
        bool                mbString;
        QueryOp             meOp;
        LookupSearchMode    meSearchMode;

        void deleteString()
        {
            if (mbAlloc && mbString)
                delete mpStr;
        }

        QueryCriteria & operator=( const QueryCriteria & r ) = delete;

    public:

        explicit QueryCriteria( const ScQueryEntry & rEntry, LookupSearchMode nSearchMode );
        QueryCriteria( const QueryCriteria & r );
        ~QueryCriteria();

        QueryOp getQueryOp() const { return meOp; }
        LookupSearchMode getSearchMode() const { return meSearchMode; }

        void setDouble( double fVal )
        {
            deleteString();
            mbAlloc = mbString = false;
            mfVal = fVal;
        }

        void setString( const OUString & rStr )
        {
            deleteString();
            mbAlloc = mbString = true;
            mpStr = new OUString( rStr);
        }

        bool operator==( const QueryCriteria & r ) const
        {
            return meOp == r.meOp && meSearchMode == r.meSearchMode && mbString == r.mbString &&
                (mbString ? (*mpStr == *r.mpStr) : (mfVal == r.mfVal));
        }

        bool isEmptyStringQuery() const
        {
            return (getQueryOp() == QueryOp::EQUAL) && mbString && mpStr && mpStr->isEmpty();
        }
    };

    /// MUST be new'd because Notify() deletes.
                            ScLookupCache( ScDocument * pDoc, const ScRange & rRange, ScLookupCacheMap & cacheMap )
                                : maRange( rRange), mpDoc( pDoc), mCacheMap(cacheMap) {}
    /// Remove from document structure and delete (!) cache on modify hint.
    virtual void Notify( const SfxHint& rHint ) override;

    /// @returns document address in o_rResultAddress if Result==FOUND
            Result          lookup( ScAddress & o_rResultAddress,
                                    const QueryCriteria & rCriteria,
                                    const ScAddress & rQueryAddress ) const;

            SCROW           lookup( const QueryCriteria & rCriteria ) const;

    /** Insert query and result.
        @param bAvailable
            Pass sal_False if the search didn't deliver a result. A subsequent
            lookup() then will return Result::NOT_AVAILABLE.
        @returns successful insertion.
      */

            bool            insert( const ScAddress & rResultAddress,
                                    const QueryCriteria & rCriteria,
                                    const ScAddress & rQueryAddress,
                                    const bool bAvailable );

    const ScRange&  getRange() const { return maRange; }

    ScLookupCacheMap & getCacheMap() const { return mCacheMap; }

    struct Hash
    {
        size_t operator()( const ScRange & rRange ) const
        {
            // Lookups are performed on the first column.
            return rRange.hashStartColumn();
        }
    };

private:

    struct QueryKey
    {
        SCROW           mnRow;
        SCTAB           mnTab;
        QueryOp         meOp;
        LookupSearchMode meSearchMode;

        QueryKey( const ScAddress & rAddress, const QueryOp eOp, LookupSearchMode eSearchMode ) :
            mnRow( rAddress.Row()),
            mnTab( rAddress.Tab()),
            meOp( eOp),
            meSearchMode( eSearchMode)
        {
        }

        bool operator==( const QueryKey & r ) const
        {
            return mnRow == r.mnRow && mnTab == r.mnTab && meOp == r.meOp && meOp != UNKNOWN &&
                meSearchMode == r.meSearchMode;
        }

        struct Hash
        {
            size_t operator()( const QueryKey & r ) const
            {
                return (static_cast<size_t>(r.mnTab) << 24) ^
                    (static_cast<size_t>(r.meOp) << 22) ^
                    (static_cast<size_t>(r.meSearchMode) << 20) ^
                    static_cast<size_t>(r.mnRow);
            }
        };
    };

    struct QueryCriteriaAndResult
    {
        QueryCriteria   maCriteria;
        ScAddress       maAddress;

        QueryCriteriaAndResult( const QueryCriteria & rCriteria, const ScAddress & rAddress ) :
            maCriteria( rCriteria),
            maAddress( rAddress)
        {
        }
    };

    typedef std::unordered_map<QueryKey, QueryCriteriaAndResult, QueryKey::Hash> QueryMap;
    QueryMap maQueryMap;
    ScRange         maRange;
    ScDocument *    mpDoc;
    ScLookupCacheMap & mCacheMap;

    ScLookupCache( const ScLookupCache & ) = delete;
    ScLookupCache & operator=( const ScLookupCache & ) = delete;

};

// Struct because including lookupcache.hxx in document.hxx isn't wanted.
struct ScLookupCacheMap
{
    std::unordered_map< ScRange, std::unique_ptr<ScLookupCache>, ScLookupCache::Hash > aCacheMap;
};


/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Messung V0.5
C=95 H=93 G=93

¤ Dauer der Verarbeitung: 0.12 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.