[Scummvm-cvs-logs] SF.net SVN: scummvm: [22896] scummvm/trunk/common

fingolfin at users.sourceforge.net fingolfin at users.sourceforge.net
Sat Jun 3 18:33:48 CEST 2006


Revision: 22896
Author:   fingolfin
Date:     2006-06-03 09:33:42 -0700 (Sat, 03 Jun 2006)
ViewCVS:  http://svn.sourceforge.net/scummvm/?rev=22896&view=rev

Log Message:
-----------
Allocate and grow Common::String objects in multiples of 32, and leave at least 16 spare bytes at the end, in case the string grows a little bit.

Modified Paths:
--------------
    scummvm/trunk/common/str.cpp
    scummvm/trunk/common/str.h
Modified: scummvm/trunk/common/str.cpp
===================================================================
--- scummvm/trunk/common/str.cpp	2006-06-03 16:09:51 UTC (rev 22895)
+++ scummvm/trunk/common/str.cpp	2006-06-03 16:33:42 UTC (rev 22896)
@@ -34,20 +34,31 @@
 const char *String::emptyString = "";
 #endif
 
+static int computeCapacity(int len) {
+	// By default, for the capacity we use the nearest multiple of 32
+	// that leaves at least 16 chars of extra space (in case the string
+	// grows a bit).
+	// Finally, we subtract 1 to compensate for the trailing zero byte.
+	len += 16;
+	return (len + 32 - 1) & ~0x1F - 1;
+}
+
 String::String(const char *str, int len, int capacity)
-: _str(0), _len(0) {
+: _str(0), _len(0), _refCount(0) {
 
-	_refCount = new int(1);
+	incRefCount();
 
 	if (str && *str && len != 0) {
 		if (len > 0)
-			_capacity = _len = len;
+			_len = len;
 		else
-			_capacity = _len = strlen(str);
+			_len = strlen(str);
 
-		_capacity = MAX(capacity, _capacity);
+		_capacity = computeCapacity(_len);
+		if (_capacity < capacity)
+			_capacity = capacity;
 
-		_str = (char *)calloc(1, _capacity+1);
+		_str = (char *)malloc(_capacity+1);
 		memcpy(_str, str, _len);
 		_str[_len] = 0;
 	} else {
@@ -57,21 +68,25 @@
 }
 
 String::String(const String &str)
- : _str(0), _len(0) {
+ : _str(str._str), _len(str._len), _refCount(str._refCount), _capacity(str._capacity) {
 
-	++(*str._refCount);
-
-	_refCount = str._refCount;
-	_capacity = str._capacity;
-	_len = str._len;
-	_str = str._str;
+	incRefCount();
 }
 
 String::~String() {
 	decRefCount();
 }
 
+void String::incRefCount() const {
+	if (_refCount == 0) {
+		_refCount = new int(1);
+	} else {
+		++(*_refCount);
+	}
+}
+
 void String::decRefCount() {
+	assert(_refCount);
 	--(*_refCount);
 	if (*_refCount <= 0) {
 		delete _refCount;
@@ -88,8 +103,9 @@
 		memcpy(_str, str, _len + 1);
 	} else if (_len > 0) {
 		decRefCount();
+		_refCount = 0;
+		incRefCount();
 
-		_refCount = new int(1);
 		_capacity = 0;
 		_len = 0;
 		_str = 0;
@@ -98,8 +114,7 @@
 }
 
 String &String::operator  =(const String &str) {
-	++(*str._refCount);
-
+	str.incRefCount();
 	decRefCount();
 
 	_refCount = str._refCount;
@@ -197,8 +212,9 @@
 void String::clear() {
 	if (_capacity) {
 		decRefCount();
+		_refCount = 0;
+		incRefCount();
 
-		_refCount = new int(1);
 		_capacity = 0;
 		_len = 0;
 		_str = 0;
@@ -241,17 +257,23 @@
 	if (new_len <= _capacity && *_refCount == 1)
 		return;
 
-	int newCapacity = (new_len <= _capacity) ? _capacity : new_len + 32;
-	char *newStr = (char *)calloc(1, newCapacity+1);
+	int newCapacity = computeCapacity(new_len);
 
+	// FIXME: We never shrink the capacity here. Is that really a good idea?
+	if (newCapacity < _capacity)
+		newCapacity = _capacity;
+
+	char *newStr = (char *)malloc(newCapacity+1);
+
 	if (keep_old && _str)
 		memcpy(newStr, _str, _len + 1);
 	else
 		_len = 0;
 
 	decRefCount();
+	_refCount = 0;
+	incRefCount();
 
-	_refCount = new int(1);
 	_capacity = newCapacity;
 	_str = newStr;
 }

Modified: scummvm/trunk/common/str.h
===================================================================
--- scummvm/trunk/common/str.h	2006-06-03 16:09:51 UTC (rev 22895)
+++ scummvm/trunk/common/str.h	2006-06-03 16:33:42 UTC (rev 22896)
@@ -32,10 +32,10 @@
 
 class String {
 protected:
-	char	*_str;
-	int 	_len;
-	int 	*_refCount;
-	int 	_capacity;
+	char		*_str;
+	int 		_len;
+	mutable int *_refCount;
+	int 		_capacity;
 
 public:
 #if !(defined(PALMOS_ARM) || defined(PALMOS_DEBUG) || defined(__GP32__))
@@ -44,7 +44,7 @@
 	static const char *emptyString;
 #endif
 
-	String() : _str(0), _len(0), _capacity(0) { _refCount = new int(1); }
+	String() : _str(0), _len(0), _refCount(0), _capacity(0) { incRefCount(); }
 	String(const char *str, int len = -1, int capacity = 16);
 	String(const String &str);
 	virtual ~String();
@@ -114,6 +114,7 @@
 
 protected:
 	void ensureCapacity(int new_len, bool keep_old);
+	void incRefCount() const;
 	void decRefCount();
 };
 


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.





More information about the Scummvm-git-logs mailing list