JUCE-7.0.12-0-g4f43011b96 JUCE-7.0.12-0-g4f43011b96
JUCE — C++ application framework with suport for VST, VST3, LV2 audio plug-ins

« « « Anklang Documentation
Loading...
Searching...
No Matches
juce_StringPool.cpp
Go to the documentation of this file.
1 /*
2 ==============================================================================
3
4 This file is part of the JUCE library.
5 Copyright (c) 2022 - Raw Material Software Limited
6
7 JUCE is an open source library subject to commercial or open-source
8 licensing.
9
10 The code included in this file is provided under the terms of the ISC license
11 http://www.isc.org/downloads/software-support-policy/isc-license. Permission
12 To use, copy, modify, and/or distribute this software for any purpose with or
13 without fee is hereby granted provided that the above copyright notice and
14 this permission notice appear in all copies.
15
16 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
17 EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
18 DISCLAIMED.
19
20 ==============================================================================
21*/
22
23namespace juce
24{
25
26static const int minNumberOfStringsForGarbageCollection = 300;
27static const uint32 garbageCollectionInterval = 30000;
28
29
30StringPool::StringPool() noexcept : lastGarbageCollectionTime (0) {}
31
33{
34 StartEndString (String::CharPointerType s, String::CharPointerType e) noexcept : start (s), end (e) {}
35 operator String() const { return String (start, end); }
36
37 String::CharPointerType start, end;
38};
39
40static int compareStrings (const String& s1, const String& s2) noexcept { return s1.compare (s2); }
41static int compareStrings (CharPointer_UTF8 s1, const String& s2) noexcept { return s1.compare (s2.getCharPointer()); }
42
43static int compareStrings (const StartEndString& string1, const String& string2) noexcept
44{
45 String::CharPointerType s1 (string1.start), s2 (string2.getCharPointer());
46
47 for (;;)
48 {
49 const int c1 = s1 < string1.end ? (int) s1.getAndAdvance() : 0;
50 const int c2 = (int) s2.getAndAdvance();
51 const int diff = c1 - c2;
52
53 if (diff != 0) return diff < 0 ? -1 : 1;
54 if (c1 == 0) break;
55 }
56
57 return 0;
58}
59
60template <typename NewStringType>
61static String addPooledString (Array<String>& strings, const NewStringType& newString)
62{
63 int start = 0;
64 int end = strings.size();
65
66 while (start < end)
67 {
68 const String& startString = strings.getReference (start);
69 const int startComp = compareStrings (newString, startString);
70
71 if (startComp == 0)
72 return startString;
73
74 const int halfway = (start + end) / 2;
75
76 if (halfway == start)
77 {
78 if (startComp > 0)
79 ++start;
80
81 break;
82 }
83
84 const String& halfwayString = strings.getReference (halfway);
85 const int halfwayComp = compareStrings (newString, halfwayString);
86
87 if (halfwayComp == 0)
88 return halfwayString;
89
90 if (halfwayComp > 0)
91 start = halfway;
92 else
93 end = halfway;
94 }
95
96 strings.insert (start, newString);
97 return strings.getReference (start);
98}
99
101{
102 if (newString == nullptr || *newString == 0)
103 return {};
104
105 const ScopedLock sl (lock);
106 garbageCollectIfNeeded();
107 return addPooledString (strings, CharPointer_UTF8 (newString));
108}
109
111{
112 if (start.isEmpty() || start == end)
113 return {};
114
115 const ScopedLock sl (lock);
116 garbageCollectIfNeeded();
117 return addPooledString (strings, StartEndString (start, end));
118}
119
121{
122 if (newString.isEmpty())
123 return {};
124
125 const ScopedLock sl (lock);
126 garbageCollectIfNeeded();
127 return addPooledString (strings, newString.text);
128}
129
131{
132 if (newString.isEmpty())
133 return {};
134
135 const ScopedLock sl (lock);
136 garbageCollectIfNeeded();
137 return addPooledString (strings, newString);
138}
139
140void StringPool::garbageCollectIfNeeded()
141{
142 if (strings.size() > minNumberOfStringsForGarbageCollection
143 && Time::getApproximateMillisecondCounter() > lastGarbageCollectionTime + garbageCollectionInterval)
145}
146
148{
149 const ScopedLock sl (lock);
150
151 for (int i = strings.size(); --i >= 0;)
152 if (strings.getReference (i).getReferenceCount() == 1)
153 strings.remove (i);
154
155 lastGarbageCollectionTime = Time::getApproximateMillisecondCounter();
156}
157
159{
160 static StringPool pool;
161 return pool;
162}
163
164} // namespace juce
Wraps a pointer to a null-terminated UTF-8 character string, and provides various methods to operate ...
bool isEmpty() const noexcept
Returns true if this pointer is pointing to a null character.
Automatically locks and unlocks a mutex object.
A StringPool holds a set of shared strings, which reduces storage overheads and improves comparison s...
String getPooledString(const String &original)
Returns a pointer to a shared copy of the string that is passed in.
StringPool() noexcept
Creates an empty pool.
static StringPool & getGlobalPool() noexcept
Returns a shared global pool which is used for things like Identifiers, XML parsing.
void garbageCollect()
Scans the pool, and removes any strings that are unreferenced.
A simple class for holding temporary references to a string literal or String.
The JUCE String class!
Definition juce_String.h:53
CharPointer_UTF8 CharPointerType
This is the character encoding type used internally to store the string.
static uint32 getApproximateMillisecondCounter() noexcept
Less-accurate but faster version of getMillisecondCounter().
typedef int
JUCE Namespace.
RangedDirectoryIterator end(const RangedDirectoryIterator &)
Returns a default-constructed sentinel value.
Type unalignedPointerCast(void *ptr) noexcept
Casts a pointer to another type via void*, which suppresses the cast-align warning which sometimes ar...
Definition juce_Memory.h:88
unsigned int uint32
A platform-independent 32-bit unsigned integer type.