office-gobmx/include/editeng/charreliefitem.hxx
Armin Le Grand (allotropia) 063781f4a9 tdf#158605 Add global SfxPoolItem re-use
The task shows that the commit including the Item
paradigm change has follow-ups: It now does no
longer try to share Items as much as possible
(detailed reasons in that commit). Mainly for speed
reasons since that sharing was done before by
(mostly) linearly searching in existing instances
registered at one Pool, using the operator== of the
SfxPoolItems. That costs runtime.

There is somewhere a sweet-spot between memory and
runtime: the number of Items allocated and the time
spent to share them more effectively. This task shows
- despite being a non-real-world document - that
for extremes like this putting work in sharing is
still needed.

But there are possibilities to combine both: If we
can implement solutions that do not need much time
to ideintify an aleady existing instance we will get
the best of both worlds.

As explained already in that change, if we would
need that again, then on a better base. Thus I drove
forward ITEM changes to a state where we are now able
to share Items globally in the office - not per pool
but for all ItemSets/ItemHolders and thus all Apps/
Models/opened documents.

NOTE: This currently needs to include the WhichID
that is included in the Item, so cannot share pure
Item-data (as the old usage did too). This does not
need to stay that way: If you think about it, the
association between WhichID and Pool/Holder is
defined in Pool/Holder, so theoretically the Item
does not need to contain the WhichID. This will
be hard to do due too many places in the code that
use the WhichID stored at the Item.

To support that I added an ItemInstanceManager with
a simple interface (find/add/remove) and it's usage
in the two central Item-existance managing methods
implCreateItemEntry/implCleanupItemEntry. The
interface is pure virtual and all methods private,
only the mentioned managing methods are allowed to
access these. Also added a virtual method to
SfxPoolItem called getItemInstanceManager() that
can be implemented by Items that want to support
that.

Also added a default implementation of
ItemInstanceManager called DefaultItemInstanceManager
that uses linear search using operator== from the
Item that can be used/added to every Item easily.
It works for all Items and does in principle what
the former implementation does. It is intended as
simple/fast fallback.

I also added a statistic element to measure the most
used non-RefCounted Items on an Office-run, this
will be printed at office shutdown using SAL_LOG
and the 'svl.items' flag.

I then checked all Items that were used in this
error/bug scenario that used an extensive number
of incarnations and added an ItemInstanceManager
for these.

For SvxFontItem I added one that creates a hash and
thus needs not to search for instances at all, with
the caveat that the WhichID needs to be included.
Thus the hash is not at the Item, but only in the
ItemInstanceManager implementation.

For SfxBoolItem I implemented one that hashes using
the WhichID and holding both possible states in an
associated std::pair, true and false, thus the
SfxBoolItem is identified fast and only two instances
per WhichID exist (when used in Pool/Holder).

For 11 other Items I just added using the standard
implementation, DefaultItemInstanceManager. Of
course the more we optimize the better it will get.

For all Items where I added that mechanism I also
added ASSERT_CHANGE_REFCOUNTED_ITEM to all write
calls/methods for that Item. It asserts when the
RefCounted Item is to be changed. This should be
done in all write accesses to Items, but we have
ca. 500 derivations.
NOTE: There was *one* place I found where that
was already done -> was alredy seen as problem,
but not really adressed.

Despite this example file is not representative,
it is still a start to init this new instance
re-use of Items.

I am already thinking about doing that globally,
depending on the usage number (maybe combined with
sizeof(item)). There is no argument to not even
change strategy at runtime when a specific number
of incarnations of one Item derivation is reached,
but this is not part of this fix.

Change-Id: Ie56cf40e0341f98dcbf29cf5c06368316829415e
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/162402
Tested-by: Jenkins
Reviewed-by: Armin Le Grand <Armin.Le.Grand@me.com>
2024-01-23 18:56:12 +01:00

62 lines
2.3 KiB
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 .
*/
#ifndef INCLUDED_EDITENG_CHARRELIEFITEM_HXX
#define INCLUDED_EDITENG_CHARRELIEFITEM_HXX
#include <svl/eitem.hxx>
#include <vcl/fntstyle.hxx>
#include <editeng/editengdllapi.h>
// class SvxCharRotateItem ----------------------------------------------
/* [Description]
This item defines a character relief and has currently the values
emboss, relief.
*/
class EDITENG_DLLPUBLIC SvxCharReliefItem final : public SfxEnumItem<FontRelief>
{
protected:
virtual ItemInstanceManager* getItemInstanceManager() const override;
public:
static SfxPoolItem* CreateDefault();
SvxCharReliefItem( FontRelief eValue /*= FontRelief::NONE*/,
const sal_uInt16 nId );
virtual SvxCharReliefItem* Clone( SfxItemPool *pPool = nullptr ) const override;
static OUString GetValueTextByPos( sal_uInt16 nPos );
virtual sal_uInt16 GetValueCount() const override;
virtual bool GetPresentation( SfxItemPresentation ePres,
MapUnit eCoreMetric,
MapUnit ePresMetric,
OUString &rText,
const IntlWrapper& ) const override;
virtual bool QueryValue( css::uno::Any& rVal, sal_uInt8 nMemberId = 0 ) const override;
virtual bool PutValue( const css::uno::Any& rVal, sal_uInt8 nMemberId ) override;
};
#endif
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */