diff options
author | rowanbeentje <rowan@beent.je> | 2010-04-26 23:42:32 +0000 |
---|---|---|
committer | rowanbeentje <rowan@beent.je> | 2010-04-26 23:42:32 +0000 |
commit | 1d7de2c00dae782992e1c082fbf3e98fe3666b88 (patch) | |
tree | 2433baaa13234e09732d2e9f6e127a88674e5273 | |
parent | 4826a8a8523690c063fd25797a3d7d232043f31a (diff) | |
download | sequelpro-1d7de2c00dae782992e1c082fbf3e98fe3666b88.tar.gz sequelpro-1d7de2c00dae782992e1c082fbf3e98fe3666b88.tar.bz2 sequelpro-1d7de2c00dae782992e1c082fbf3e98fe3666b88.zip |
- Improve threading of SPFileHandle to achieve much faster writing due to increased separation of the writing thread. This results in a up-to 1.2x faster MySQL dump for fast servers, and makes SPFileHandle faster than NSFileHandle for writing data (either directly or GZIP compressed).
-rw-r--r-- | Source/SPFileHandle.h | 1 | ||||
-rw-r--r-- | Source/SPFileHandle.m | 39 |
2 files changed, 31 insertions, 9 deletions
diff --git a/Source/SPFileHandle.h b/Source/SPFileHandle.h index 05a8da0e..05e05dd5 100644 --- a/Source/SPFileHandle.h +++ b/Source/SPFileHandle.h @@ -44,6 +44,7 @@ int fileMode; BOOL dataWritten; + BOOL allDataWritten; BOOL fileIsClosed; BOOL useGzip; } diff --git a/Source/SPFileHandle.m b/Source/SPFileHandle.m index e0838a6d..bceae2aa 100644 --- a/Source/SPFileHandle.m +++ b/Source/SPFileHandle.m @@ -51,6 +51,8 @@ - (id) initWithFile:(void *)theFile fromPath:(const char *)path mode:(int)mode { if (self = [super init]) { + dataWritten = NO; + allDataWritten = YES; fileIsClosed = NO; wrappedFile = theFile; @@ -216,9 +218,12 @@ if (fileIsClosed) [NSException raise:NSInternalInconsistencyException format:@"Cannot write to a file handle after it has been closed"]; // Add the data to the buffer - pthread_mutex_lock(&bufferLock); - [buffer appendData:data]; - bufferDataLength += [data length]; + if ([data length]) { + pthread_mutex_lock(&bufferLock); + [buffer appendData:data]; + allDataWritten = NO; + bufferDataLength += [data length]; + } // If the buffer is large, wait for some to be written out while (bufferDataLength > SPFH_MAX_WRITE_BUFFER_SIZE) { @@ -235,7 +240,7 @@ - (void) synchronizeFile { pthread_mutex_lock(&bufferLock); - while (bufferDataLength) { + while (!allDataWritten) { pthread_mutex_unlock(&bufferLock); usleep(100); pthread_mutex_lock(&bufferLock); @@ -302,17 +307,33 @@ continue; } + // Copy the data into a local buffer + NSData *dataToBeWritten = [NSData dataWithData:buffer]; + [buffer setLength:0]; + bufferDataLength = 0; + pthread_mutex_unlock(&bufferLock); + // Write out the data long bufferLengthWrittenOut; if (useGzip) { - bufferLengthWrittenOut = gzwrite(wrappedFile, [buffer bytes], bufferDataLength); + bufferLengthWrittenOut = gzwrite(wrappedFile, [dataToBeWritten bytes], [dataToBeWritten length]); } else { - bufferLengthWrittenOut = fwrite([buffer bytes], 1, bufferDataLength, wrappedFile); + bufferLengthWrittenOut = fwrite([dataToBeWritten bytes], 1, [dataToBeWritten length], wrappedFile); } - // Update the buffer - CFDataDeleteBytes((CFMutableDataRef)buffer, CFRangeMake(0, bufferLengthWrittenOut)); - bufferDataLength = 0; + // Restore data to the buffer if it wasn't written out + pthread_mutex_lock(&bufferLock); + if (bufferLengthWrittenOut < [dataToBeWritten length]) { + if ([buffer length]) { + long dataLengthToRestore = [dataToBeWritten length] - bufferLengthWrittenOut; + [buffer replaceBytesInRange:NSMakeRange(0, 0) withBytes:[[dataToBeWritten subdataWithRange:NSMakeRange(bufferLengthWrittenOut, dataLengthToRestore)] bytes] length:dataLengthToRestore]; + bufferDataLength += dataLengthToRestore; + } + + // Otherwise, mark all data as written if it has been - allows synching to hard disk. + } else if (![buffer length]) { + allDataWritten = YES; + } pthread_mutex_unlock(&bufferLock); } |