Commit Graph

43 Commits

Author SHA1 Message Date
Kevin Martin
edb8e4c937 Address performance of existing unique-name generation (Part 2) (#18676)
As described in Issue 16849, the existing Tools::getUniqueName method
requires calling code to form a vector of existing names to be avoided.

This leads to poor performance both in the O(n) cost of building such a
vector and also getUniqueName's O(n) algorithm for actually generating
the unique name (where 'n' is the number of pre-existing names).

This has  particularly noticeable cost in documents with large numbers
of DocumentObjects because generating both Names and Labels for each new
object incurs this cost. During an operation such as importing this
results in an O(n^2) time spent generating names.

The other major cost is in the saving of the temporary backup file,
which uses name generation for the "files" embedded in the Zip file.
Documents can easily need several such "files" for each object in the
document.

This update includes the following changes to use the newly-added
UniqueNameManager as a replacement for the old Tools::getUniqueName
method and deletes the latter to remove any temptation to use it as
its usage model breeds inefficiency:

Eliminate Tools::getUniqueName, its local functions, and its unit tests.

Make DocumentObject naming use the new UniqueNameManager class.

Make DocumentObject Label naming use the new UniqueNameManager class.
This needs to monitor DocumentObject Labels for changes since this
property is not read-only. The special handling for the Label
property, which includes optionally forcing uniqueness and updating
links in referencing objects, has been mostly moved from
PropertyString to DocumentObject.

Add Document::containsObject(DocumentObject*) for a definitive
test of an object being in a Document. This is needed because
DocumentObjects can be in a sort of limbo (e.g. when they are in the
Undo/Redo lists) where they have a parent linkage to the Document but
should not participate in Label collision checks.

Rename Document.getStandardObjectName to getStandardObjectLabel
to better represent what it does.

Use new UniqueNameManager for Writer internal filenames within the zip
file.

Eliminate unneeded Reader::FileNames collection. The file names
already exist in the FileList collection elements. The only existing
use for the FileNames collection was to determine if there were any
files at all, and with FileList and FileNames being parallel
vectors, they both had the same length so FileList could be used
for this test..

Use UniqueNameManager for document names and labels. This uses ad hoc
UniqueNameManager objects created on the spot on the assumption that
document creation is relatively rare and there are few documents, so
although the cost is O(n), n itself is small.

Use an ad hoc UniqueNameManager to name new DymanicProperty entries.
This is only done if a property of the proposed name already exists,
since such a check is more-or-less O(log(n)), almost never finds a
collision, and avoids the O(n) building of the UniqueNameManager.
If there is a collision an ad-hoc UniqueNameManager is built
and discarded after use.
The property management classes have a bit of a mess of methods
including several to populate various collection types with all
existing properties. Rather than introducing yet another such
collection-specific method to fill a UniqueNameManager, a
visitProperties method was added which calls a passed function for
each property. The existing code (e.g. getPropertyMap) would be
simpler if they all used this but the cost of calling a lambda
for each property must be considered. It would clarify the semantics
of these methods, which have a bit of variance in which properties
populate the passed collection, e.g. when there are duplicate names..
Ideally the PropertyContainer class would keep a central directory of
all properties ("static", Dynamic, and exposed by ExtensionContainer and
other derivations) and a permanent UniqueNameManager. However the
Property management is a bit of a mess making such a change a project
unto itself.
2025-02-24 10:23:53 -06:00
Benjamin Bræstrup Sayoc
6f619b5f1c Base: remove unneeded includes 2025-02-18 11:07:57 -06:00
Benjamin Nauck
39402e2083 Revert "Address the poor performance of the existing unique-name generation (#17944)"
This reverts commit 83202d8ad6.

# Conflicts:
#	src/Base/Tools.cpp
#	src/Base/Tools.h
2024-12-16 17:31:43 +01:00
Kevin Martin
5696c9add3 Address the poor performance of the existing unique-name generation (#17944)
* Address the poor performance of the existing unique-name generation

As described in Issue 16849, the existing Tools::getUniqueName method
requires calling code to form a vector of existing names to be avoided.

This leads to poor performance both in the O(n) cost of building such a
vector and also getUniqueName's O(n) algorithm for actually generating
the unique name (where 'n' is the number of pre-existing names).

This has  particularly noticeable cost in documents with large numbers
of DocumentObjects because generating both Names and Labels for each new
object incurs this cost. During an operation such as importing this
results in an O(n^2) time spent generating names.

The other major cost is in the saving of the temporary backup file,
which uses name generation for the "files" embedded in the Zip file.
Documents can easily need several such "files" for each object in the
document.

This update includes the following changes:

Create UniqueNameManager to keep a list of existing names organized in
a manner that eases unique-name generation. This class essentially acts
as a set of names, with the ability to add and remove names and check if
a name is already there, with the added ability to take a prototype name
and generate a unique form for it which is not already in the set.

Eliminate Tools::getUniqueName

Make DocumentObject naming use the new UniqueNameManager class

Make DocumentObject Label naming use the new UniqueNameManager class.
Labels are not always unique; unique labels are generated if the
settings at the time request it (and other conditions). Because of this
the Label management requires additionally keeping a map of counts
for labels which already exist more than once.
These collections are maintained via notifications of value changes on
the Label properties of the objects in the document.

Add Document::containsObject(DocumentObject*) for a definitive
test of an object being in a Document. This is needed because
DocumentObjects can be in a sort of limbo (e.g. when they are in the
Undo/Redo lists) where they have a parent linkage to the Document but
should not participate in Label collision checks.

Rename Document.getStandardObjectName to getStandardObjectLabel
to better represent what it does.

Use new UniqueNameManager for Writer internal filenames within the zip
file.

Eliminate unneeded Reader::FileNames collection. The file names
already exist in the FileList collection elements. The only existing
use for the FileNames collection was to determine if there were any
files at all, and with FileList and FileNames being parallel
vectors, they both had the same length so FileList could be used
for this test..

Use UniqueNameManager for document names and labels. This uses ad hoc
UniqueNameManager objects created on the spot on the assumption that
document creation is relatively rare and there are few documents, so
although the cost is O(n), n itself is small.

Use an ad hoc UniqueNameManager to name new DymanicProperty entries.
This is only done if a property of the proposed name already exists,
since such a check is more-or-less O(log(n)), almost never finds a
collision, and avoids the O(n) building of the UniqueNameManager.
If there is a collision an ad-hoc UniqueNameManager is built
and discarded after use.
The property management classes have a bit of a mess of methods
including several to populate various collection types with all
existing properties. Rather than introducing yet another such
collection-specific method to fill a UniqueNameManager, a
visitProperties method was added which calls a passed function for
each property. The existing code would be simpler if existing
fill-container methods all used this.
Ideally the PropertyContainer class would keep a central directory of
all properties ("static", Dynamic, and exposed by ExtensionContainer and
other derivations) and a permanent UniqueNameManager. However the
Property management is a bit of a mess making such a change a project
unto itself.

The unit tests for Tools:getUniqueName have been changed to test
UniqueNameManager.makeUniqueName instead.
This revealed a small regression insofar as passing a prototype name
like "xyz1234" to the old code would yield "xyz1235" whether or
not "xyz1234" already existed, while the new code will return the next
name above the currently-highest name on the "xyz" model, which could
be "xyz" or "xyz1".

* Correct wrong case on include path

* Implement suggested code changes
Also change the semantics of visitProperties to not have any short-circuit return

* Remove reference through undefined iterator

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Fix up some comments for DOxygen

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2024-12-13 10:54:46 -06:00
wmayer
6e1e832039 Core: Fix flaw in XMLReader class
Remove implementation details of the Document class from the XMLReader class.
Instead keep an array of failed files and check them in the calling instance.
2024-11-17 08:34:03 +01:00
huguesdpdn-aerospace
611bab3d6d PD: Xerces-C++ - Prepare for the latest version (backward compatible) 2024-09-08 20:31:25 -05:00
bgbsww
3efba18ad4 Expand reader getAttribute calls to accept a default value 2024-07-18 18:18:38 -05:00
Catalin MARINCIA
20b59ce9dd Build: Fix visibility of fields in Reader.h to be compiled with GCC 13 toolchain 2024-01-08 18:32:40 +01:00
wmayer
985def3416 Base: apply clang format 2023-11-13 12:01:26 -05:00
wmayer
e3fb3b9639 Base: add method XMLReader::isStartOfDocument() 2023-10-12 19:46:21 +02:00
Chris Hennes
33abb7b5b1 App/Toponaming: Add base64 encoding to XML 2023-10-10 10:19:43 -05:00
wmayer
3e33591093 Core: add method to XMLReader to access next element of an XML file
If the next element could be read-in successfully true is returned, and false otherwise.
2023-10-09 15:06:45 +02:00
wmayer
d305f306df Core: Revert superfluous changes made with PR #9521 2023-10-09 15:06:45 +02:00
AgCaliva
3da00e36a3 Merge Master 2023-08-30 16:24:16 -03:00
wmayer
4210ab01e0 Base: modernize C++: use default member init 2023-08-23 19:51:44 +02:00
AgCaliva
d838225357 Merge branch 'master' into User/Document/Feature_level_units_selection_#7746 2023-07-02 17:45:05 -03:00
AgCaliva
9cf1cdadbc Implemented DocumentReader for GuiDocument.xml reading. Final 2023-06-30 20:50:36 -03:00
AgCaliva
1db4bcf374 Revert "DocumentReader implemented for GuiDocument.xml reading."
This reverts commit 2eb5fd7f132035e24880bd88076d49ed368e23e0.
2023-06-30 20:27:12 -03:00
AgCaliva
69b324e422 DocumentReader implemented for GuiDocument.xml reading. 2023-06-30 18:41:00 -03:00
Chris Hennes
9ebaa34e1e App/Toponaming: Add supporting code
Support for reading and writing binary data, and a small tweak to bitmask.
2023-05-11 14:34:35 -05:00
berniev
5678fc1abe remove xcerces2 2022-09-09 08:02:35 +02:00
wmayer
4e42ff7baa Base: modernize C++: replace 'typedef' with 'using' 2022-08-29 11:42:09 +02:00
berniev
15419982d4 Base: Modernise ctors dtors defs etc 2022-08-02 12:37:46 +02:00
wmayer
a6624ef264 Base: fix warnings from code analysers:
* replace some C-style casts with static_cast
* remove unneeded destructors
* define default copy-constructor and assignment operator
2022-03-05 19:03:21 +01:00
Uwe
5b1114e914 [Base] Reader and Writer: remove unused includes 2022-02-27 23:54:00 +01:00
wmayer
cad0d01883 Base: modernize C++11
* remove redundant void-arg
* use nullptr
* replace deprecated headers
2022-01-25 20:21:30 +01:00
luz.paz
011e5aedfa src/Base: [skip ci] fix header uniformity
This PR fixes header uniformity across all `src/Base` files
2019-12-25 11:38:58 +01:00
wmayer
f88dad0905 use shared_ptr to avoid possible memory leaks and improve exception-safety 2019-09-03 17:21:13 +02:00
Jean-Marie Verdun
e20456dc1f Destroy XMLReader object attached to Reader one when this one is gone as to avoid
potential memory leaks.
2019-09-03 17:21:08 +02:00
Jean-Marie Verdun
a2e21f79f2 Add initial version of the Cloud workbench 2019-09-03 17:21:05 +02:00
Zheng, Lei
576d51a78a Base::Reader: support reading child element with the same name as parent
Future GuiDocument.xml will save recursive tree item expansion status
using child element with the same name as the parent.
2019-08-17 14:52:11 +02:00
Abdullah Tahiri
7cfae563c3 Extension of XMLReader to facilitate partial restores 2018-11-19 11:31:10 +01:00
hgutsche
201c9d89b0 Some fixes for doygen syntax errors and some configuration to make it run smoother under Windows 2017-02-28 18:52:04 +01:00
Mateusz Skowroński
05f95c0506 Fix files encoding. Go from ISO8859-1 to UTF-8. 2015-09-21 19:50:49 -03:00
wmayer
22b7fb660c + save Brep in binary format for recovery files 2015-09-16 22:58:47 +02:00
wmayer
3fd44cf3f0 + make XML parser more robust against unexpected structure 2015-04-11 13:11:12 +02:00
wmayer
87fa47d8e3 + allow to suppress verbose mode of XMLReader 2015-01-13 21:57:18 +01:00
wmayer
5aa1f90dbd + Keep trailing digits when loading project file 2013-12-30 12:54:45 +01:00
wmayer
bb63f7a4d5 Remove FileVersion from RestoreDocFile, convert point data back to floats 2013-03-29 15:23:51 +01:00
jrheinlaender
ad6444053b Added FileVersion attribute to XML format to distinguish legacy float binary files from new double binary files 2013-03-27 11:47:18 +04:30
wmayer
d4f1250453 0000827: Sketch copy deletes all constraints 2012-11-20 13:16:15 +01:00
wmayer
399d9468f4 Implement CDATA reader, fix bugs in Writer::insertBinFile 2012-05-31 11:50:25 +02:00
wmayer
120ca87015 + unify DLL export defines to namespace names
git-svn-id: https://free-cad.svn.sourceforge.net/svnroot/free-cad/trunk@5000 e8eeb9e2-ec13-0410-a4a9-efa5cf37419d
2011-10-10 13:44:52 +00:00