aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core
diff options
context:
space:
mode:
authorGravatar Hoa V. DINH <dinh.viet.hoa@gmail.com>2014-10-25 15:31:05 -0700
committerGravatar Hoa V. DINH <dinh.viet.hoa@gmail.com>2014-10-25 15:31:05 -0700
commit97de9211f38bf5823d08e529b65841c9a6f7962f (patch)
tree124d3243f34a884e5527bdca1a4af73a3f41348e /src/core
parent386f84abe048c4b37cef42195d612b480021df3f (diff)
Additional memory allocation optimization
Diffstat (limited to 'src/core')
-rw-r--r--src/core/basetypes/MCData.cc36
-rw-r--r--src/core/basetypes/MCData.h4
-rw-r--r--src/core/basetypes/MCString.cc34
-rw-r--r--src/core/basetypes/MCString.h2
4 files changed, 51 insertions, 25 deletions
diff --git a/src/core/basetypes/MCData.cc b/src/core/basetypes/MCData.cc
index a4426e49..d7d4e7a6 100644
--- a/src/core/basetypes/MCData.cc
+++ b/src/core/basetypes/MCData.cc
@@ -21,17 +21,29 @@
using namespace mailcore;
-void Data::allocate(unsigned int length)
+static int isPowerOfTwo (unsigned int x)
{
- length ++;
- if (length < mAllocated)
+ return ((x != 0) && !(x & (x - 1)));
+}
+
+void Data::allocate(unsigned int length, bool force)
+{
+ if (length <= mAllocated)
return;
-
- if (mAllocated == 0) {
- mAllocated = 4;
+
+ if (force) {
+ mAllocated = length;
}
- while (length > mAllocated) {
- mAllocated *= 2;
+ else {
+ if (!isPowerOfTwo(mAllocated)) {
+ mAllocated = 0;
+ }
+ if (mAllocated == 0) {
+ mAllocated = 4;
+ }
+ while (length > mAllocated) {
+ mAllocated *= 2;
+ }
}
mBytes = (char *) realloc(mBytes, mAllocated);
@@ -62,7 +74,7 @@ Data::Data(const char * bytes, unsigned int length)
{
mBytes = NULL;
reset();
- allocate(length);
+ allocate(length, true);
appendBytes(bytes, length);
}
@@ -70,7 +82,7 @@ Data::Data(int capacity)
{
mBytes = NULL;
reset();
- allocate(capacity);
+ allocate(capacity, true);
}
Data::~Data()
@@ -403,7 +415,7 @@ String * Data::charsetWithFilteredHTML(bool filterHTML, String * hintCharset)
return result;
}
-void Data::replaceWithAllocatedBytes(char * bytes, unsigned int length)
+void Data::takeBytesOwnership(char * bytes, unsigned int length)
{
free(mBytes);
mBytes = (char *) bytes;
@@ -440,7 +452,7 @@ Data * Data::dataWithContentsOfFile(String * filename)
}
data = Data::data();
- data->replaceWithAllocatedBytes(buf, (unsigned int) stat_buf.st_size);
+ data->takeBytesOwnership(buf, (unsigned int) stat_buf.st_size);
fclose(f);
diff --git a/src/core/basetypes/MCData.h b/src/core/basetypes/MCData.h
index 131cb722..43ffb30f 100644
--- a/src/core/basetypes/MCData.h
+++ b/src/core/basetypes/MCData.h
@@ -62,10 +62,10 @@ namespace mailcore {
char * mBytes;
unsigned int mLength;
unsigned int mAllocated;
- void allocate(unsigned int length);
+ void allocate(unsigned int length, bool force = false);
void reset();
String * charsetWithFilteredHTMLWithoutHint(bool filterHTML);
- void replaceWithAllocatedBytes(char * bytes, unsigned int length);
+ void takeBytesOwnership(char * bytes, unsigned int length);
};
diff --git a/src/core/basetypes/MCString.cc b/src/core/basetypes/MCString.cc
index a90a32b3..dbf43943 100644
--- a/src/core/basetypes/MCString.cc
+++ b/src/core/basetypes/MCString.cc
@@ -691,7 +691,7 @@ String::String(const UChar * unicodeChars)
mUnicodeChars = NULL;
reset();
if (unicodeChars != NULL) {
- allocate(u_strlen(unicodeChars));
+ allocate(u_strlen(unicodeChars), true);
}
appendCharacters(unicodeChars);
}
@@ -700,7 +700,7 @@ String::String(const UChar * unicodeChars, unsigned int length)
{
mUnicodeChars = NULL;
reset();
- allocate(length);
+ allocate(length, true);
appendCharactersLength(unicodeChars, length);
}
@@ -708,6 +708,7 @@ String::String(const char * UTF8Characters)
{
mUnicodeChars = NULL;
reset();
+ allocate((unsigned int) strlen(UTF8Characters), true);
appendUTF8Characters(UTF8Characters);
}
@@ -729,7 +730,7 @@ String::String(const char * bytes, unsigned int length, const char * charset)
{
mUnicodeChars = NULL;
reset();
- allocate(length);
+ allocate(length, true);
if (charset == NULL) {
appendUTF8CharactersLength(bytes, length);
}
@@ -743,17 +744,30 @@ String::~String()
reset();
}
-void String::allocate(unsigned int length)
+static int isPowerOfTwo (unsigned int x)
+{
+ return ((x != 0) && !(x & (x - 1)));
+}
+
+void String::allocate(unsigned int length, bool force)
{
length ++;
- if (length < mAllocated)
+ if (length <= mAllocated)
return;
-
- if (mAllocated == 0) {
- mAllocated = 4;
+
+ if (force) {
+ mAllocated = length;
}
- while (length > mAllocated) {
- mAllocated *= 2;
+ else {
+ if (!isPowerOfTwo(mAllocated)) {
+ mAllocated = 0;
+ }
+ if (mAllocated == 0) {
+ mAllocated = 4;
+ }
+ while (length > mAllocated) {
+ mAllocated *= 2;
+ }
}
mUnicodeChars = (UChar *) realloc(mUnicodeChars, mAllocated * sizeof(* mUnicodeChars));
diff --git a/src/core/basetypes/MCString.h b/src/core/basetypes/MCString.h
index 25439cf2..cad79c21 100644
--- a/src/core/basetypes/MCString.h
+++ b/src/core/basetypes/MCString.h
@@ -130,7 +130,7 @@ namespace mailcore {
UChar * mUnicodeChars;
unsigned int mLength;
unsigned int mAllocated;
- void allocate(unsigned int length);
+ void allocate(unsigned int length, bool force = false);
void reset();
int compareWithCaseSensitive(String * otherString, bool caseSensitive);
void appendBytes(const char * bytes, unsigned int length, const char * charset);