OpenShot Audio Library | OpenShotAudio 0.3.2
Loading...
Searching...
No Matches
juce_StringPool.cpp
1/*
2 ==============================================================================
3
4 This file is part of the JUCE library.
5 Copyright (c) 2017 - ROLI Ltd.
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) {}
32
33struct StartEndString
34{
35 StartEndString (String::CharPointerType s, String::CharPointerType e) noexcept : start (s), end (e) {}
36 operator String() const { return String (start, end); }
37
38 String::CharPointerType start, end;
39};
40
41static int compareStrings (const String& s1, const String& s2) noexcept { return s1.compare (s2); }
42static int compareStrings (CharPointer_UTF8 s1, const String& s2) noexcept { return s1.compare (s2.getCharPointer()); }
43
44static int compareStrings (const StartEndString& string1, const String& string2) noexcept
45{
46 String::CharPointerType s1 (string1.start), s2 (string2.getCharPointer());
47
48 for (;;)
49 {
50 const int c1 = s1 < string1.end ? (int) s1.getAndAdvance() : 0;
51 const int c2 = (int) s2.getAndAdvance();
52 const int diff = c1 - c2;
53
54 if (diff != 0) return diff < 0 ? -1 : 1;
55 if (c1 == 0) break;
56 }
57
58 return 0;
59}
60
61template <typename NewStringType>
62static String addPooledString (Array<String>& strings, const NewStringType& newString)
63{
64 int start = 0;
65 int end = strings.size();
66
67 while (start < end)
68 {
69 const String& startString = strings.getReference (start);
70 const int startComp = compareStrings (newString, startString);
71
72 if (startComp == 0)
73 return startString;
74
75 const int halfway = (start + end) / 2;
76
77 if (halfway == start)
78 {
79 if (startComp > 0)
80 ++start;
81
82 break;
83 }
84
85 const String& halfwayString = strings.getReference (halfway);
86 const int halfwayComp = compareStrings (newString, halfwayString);
87
88 if (halfwayComp == 0)
89 return halfwayString;
90
91 if (halfwayComp > 0)
92 start = halfway;
93 else
94 end = halfway;
95 }
96
97 strings.insert (start, newString);
98 return strings.getReference (start);
99}
100
102{
103 if (newString == nullptr || *newString == 0)
104 return {};
105
106 const ScopedLock sl (lock);
107 garbageCollectIfNeeded();
108 return addPooledString (strings, CharPointer_UTF8 (newString));
109}
110
111String StringPool::getPooledString (String::CharPointerType start, String::CharPointerType end)
112{
113 if (start.isEmpty() || start == end)
114 return {};
115
116 const ScopedLock sl (lock);
117 garbageCollectIfNeeded();
118 return addPooledString (strings, StartEndString (start, end));
119}
120
122{
123 if (newString.isEmpty())
124 return {};
125
126 const ScopedLock sl (lock);
127 garbageCollectIfNeeded();
128 return addPooledString (strings, newString.text);
129}
130
132{
133 if (newString.isEmpty())
134 return {};
135
136 const ScopedLock sl (lock);
137 garbageCollectIfNeeded();
138 return addPooledString (strings, newString);
139}
140
141void StringPool::garbageCollectIfNeeded()
142{
143 if (strings.size() > minNumberOfStringsForGarbageCollection
144 && Time::getApproximateMillisecondCounter() > lastGarbageCollectionTime + garbageCollectionInterval)
146}
147
149{
150 const ScopedLock sl (lock);
151
152 for (int i = strings.size(); --i >= 0;)
153 if (strings.getReference(i).getReferenceCount() == 1)
154 strings.remove (i);
155
156 lastGarbageCollectionTime = Time::getApproximateMillisecondCounter();
157}
158
160{
161 static StringPool pool;
162 return pool;
163}
164
165} // namespace juce
bool isEmpty() const noexcept
Definition juce_Array.h:222
int size() const noexcept
Definition juce_Array.h:215
ElementType & getReference(int index) noexcept
Definition juce_Array.h:267
String getPooledString(const String &original)
static StringPool & getGlobalPool() noexcept
static uint32 getApproximateMillisecondCounter() noexcept