Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Update NSPointerArray usage in SPDataStorage for 10.9 SDK, tracking e…
…dited row count and using for fast bounds checks; this should fix #1884
  • Loading branch information
rowanbeentje committed Feb 4, 2014
1 parent 0dad321 commit 1d8db00
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 20 deletions.
1 change: 1 addition & 0 deletions Source/SPDataStorage.h
Expand Up @@ -46,6 +46,7 @@
BOOL *unloadedColumns;

NSUInteger numberOfColumns;
NSUInteger editedRowCount;

This comment has been minimized.

Copy link
@dmoagx

dmoagx Feb 4, 2014

Member

The name had me confused for a few minutes. It suggests this is the "number of edited rows", but actually it is the "number of rows after editing". Perhaps rename it to rowCountAfterEdit or rowCountIncludingEdits or rowCountNew?

This comment has been minimized.

Copy link
@rowanbeentje

rowanbeentje Feb 4, 2014

Author Collaborator

It is actually the "number of edited rows" :) SPDataStorage manages two groups of storage; firstly it allows access to a wrapped SPMySQLStreamingResultStore (low memory usage for uneditable records), and secondly it keeps a sparse NSPointerArray of rows that have been edited. On initial load this will have zero size; when the table has fully loaded it'll be setCount: to the total number of rows, but have no entries until a row is actually edited.

A bit complicated, but that allows us to use a nice compact uneditable store for the vast majority of rows, then layer a few NSObject-based rows on top of that... :)

}

/* Setting result store */
Expand Down
68 changes: 48 additions & 20 deletions Source/SPDataStorage.m
Expand Up @@ -58,6 +58,7 @@ - (void) setDataStorage:(SPMySQLStreamingResultStore *)newDataStorage updatingEx
{
NSUInteger i;
[editedRows release], editedRows = nil;
editedRowCount = 0;
if (unloadedColumns) free(unloadedColumns), unloadedColumns = NULL;

if (dataStorage) {
Expand Down Expand Up @@ -96,9 +97,12 @@ - (NSMutableArray *) rowContentsAtIndex:(NSUInteger)anIndex
{

// If an edited row exists for the supplied index, return it
NSMutableArray *editedRow = SPDataStorageGetEditedRow(editedRows, anIndex);
if (editedRow != NULL) {
return editedRow;
if (anIndex < editedRowCount) {
NSMutableArray *editedRow = SPDataStorageGetEditedRow(editedRows, anIndex);

if (editedRow != NULL) {
return editedRow;
}
}

// Otherwise, prepare to return the underlying storage row
Expand All @@ -120,10 +124,12 @@ - (NSMutableArray *) rowContentsAtIndex:(NSUInteger)anIndex
- (id) cellDataAtRow:(NSUInteger)rowIndex column:(NSUInteger)columnIndex
{
// If an edited row exists at the supplied index, return it
NSMutableArray *editedRow = SPDataStorageGetEditedRow(editedRows, rowIndex);
if (rowIndex < editedRowCount) {
NSMutableArray *editedRow = SPDataStorageGetEditedRow(editedRows, rowIndex);

if (editedRow != NULL) {
return CFArrayGetValueAtIndex((CFArrayRef)editedRow, columnIndex);
if (editedRow != NULL) {
return CFArrayGetValueAtIndex((CFArrayRef)editedRow, columnIndex);
}
}

// Throw an exception if the column index is out of bounds
Expand All @@ -148,13 +154,16 @@ - (id) cellPreviewAtRow:(NSUInteger)rowIndex column:(NSUInteger)columnIndex prev
{

// If an edited row exists at the supplied index, return it
NSMutableArray *editedRow = SPDataStorageGetEditedRow(editedRows, rowIndex);
if (editedRow != NULL) {
id anObject = CFArrayGetValueAtIndex((CFArrayRef)editedRow, columnIndex);
if ([anObject isKindOfClass:[NSString class]] && [(NSString *)anObject length] > 150) {
return ([NSString stringWithFormat:@"%@...", [anObject substringToIndex:147]]);
if (rowIndex < editedRowCount) {
NSMutableArray *editedRow = SPDataStorageGetEditedRow(editedRows, rowIndex);

if (editedRow != NULL) {
id anObject = CFArrayGetValueAtIndex((CFArrayRef)editedRow, columnIndex);
if ([anObject isKindOfClass:[NSString class]] && [(NSString *)anObject length] > 150) {
return ([NSString stringWithFormat:@"%@...", [anObject substringToIndex:147]]);
}
return anObject;
}
return anObject;
}

// Throw an exception if the column index is out of bounds
Expand All @@ -177,9 +186,12 @@ - (id) cellPreviewAtRow:(NSUInteger)rowIndex column:(NSUInteger)columnIndex prev
- (BOOL) cellIsNullOrUnloadedAtRow:(NSUInteger)rowIndex column:(NSUInteger)columnIndex
{
// If an edited row exists at the supplied index, check it for a NULL.
NSMutableArray *editedRow = SPDataStorageGetEditedRow(editedRows, rowIndex);
if (editedRow != NULL) {
return [(id)CFArrayGetValueAtIndex((CFArrayRef)editedRow, columnIndex) isNSNull];
if (rowIndex < editedRowCount) {
NSMutableArray *editedRow = SPDataStorageGetEditedRow(editedRows, rowIndex);

if (editedRow != NULL) {
return [(id)CFArrayGetValueAtIndex((CFArrayRef)editedRow, columnIndex) isNSNull];
}
}

// Throw an exception if the column index is out of bounds
Expand All @@ -204,13 +216,17 @@ - (BOOL) cellIsNullOrUnloadedAtRow:(NSUInteger)rowIndex column:(NSUInteger)colum
*/
- (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state objects:(id *)stackbuf count:(NSUInteger)len
{
NSMutableArray *targetRow = NULL;

// If the start index is out of bounds, return 0 to indicate end of results
if (state->state >= SPMySQLResultStoreGetRowCount(dataStorage)) return 0;

// If an edited row exists for the supplied index, use that; otherwise use the underlying
// storage row
NSMutableArray *targetRow = SPDataStorageGetEditedRow(editedRows, state->state);
if (state->state < editedRowCount) {
targetRow = SPDataStorageGetEditedRow(editedRows, state->state);
}

if (targetRow == NULL) {
targetRow = SPMySQLResultStoreGetRow(dataStorage, state->state);

Expand Down Expand Up @@ -248,6 +264,7 @@ - (void) addRowWithContents:(NSMutableArray *)aRow

// Add the new row to the editable store
[editedRows addPointer:aRow];
editedRowCount++;

// Update the underlying store as well to keep counts correct
[dataStorage addDummyRow];
Expand Down Expand Up @@ -277,6 +294,7 @@ - (void) insertRowContents:(NSMutableArray *)aRow atIndex:(NSUInteger)anIndex

// Add the new row to the editable store
[editedRows insertPointer:aRow atIndex:anIndex];
editedRowCount++;

// Update the underlying store to keep counts and indices correct
[dataStorage insertDummyRowAtIndex:anIndex];
Expand All @@ -296,9 +314,13 @@ - (void) replaceRowAtIndex:(NSUInteger)anIndex withRowContents:(NSMutableArray *
*/
- (void) replaceObjectInRow:(NSUInteger)rowIndex column:(NSUInteger)columnIndex withObject:(id)anObject
{
NSMutableArray *editableRow = NULL;

if (rowIndex < editedRowCount) {
editableRow = SPDataStorageGetEditedRow(editedRows, rowIndex);
}

// Make sure that the row in question is editable
NSMutableArray *editableRow = SPDataStorageGetEditedRow(editedRows, rowIndex);
if (editableRow == NULL) {
editableRow = [self rowContentsAtIndex:rowIndex];
[editedRows replacePointerAtIndex:rowIndex withPointer:editableRow];
Expand All @@ -320,7 +342,9 @@ - (void) removeRowAtIndex:(NSUInteger)anIndex
}

// Remove the row from the edited list and underlying storage
[editedRows removePointerAtIndex:anIndex];
if (anIndex < editedRowCount) {
[editedRows removePointerAtIndex:anIndex];
}
[dataStorage removeRowAtIndex:anIndex];
}

Expand All @@ -337,9 +361,10 @@ - (void) removeRowsInRange:(NSRange)rangeToRemove
}

// Remove the rows from the edited list and underlying storage
NSUInteger i = rangeToRemove.location + rangeToRemove.length;
NSUInteger i = MIN(editedRowCount, rangeToRemove.location + rangeToRemove.length);
while (--i >= rangeToRemove.location) {
[editedRows removePointerAtIndex:i];
editedRowCount--;
}
[dataStorage removeRowsInRange:rangeToRemove];
}
Expand All @@ -350,6 +375,7 @@ - (void) removeRowsInRange:(NSRange)rangeToRemove
- (void) removeAllRows
{
[editedRows setCount:0];
editedRowCount = 0;
[dataStorage removeAllRows];
}

Expand Down Expand Up @@ -400,7 +426,8 @@ - (BOOL) dataDownloaded
*/
- (void)resultStoreDidFinishLoadingData:(SPMySQLStreamingResultStore *)resultStore
{
[editedRows setCount:(NSUInteger)[resultStore numberOfRows]];
editedRowCount = [resultStore numberOfRows];
[editedRows setCount:editedRowCount];
}

/**
Expand All @@ -415,6 +442,7 @@ - (id) init {
unloadedColumns = NULL;

numberOfColumns = 0;
editedRowCount = 0;
}
return self;
}
Expand Down

0 comments on commit 1d8db00

Please sign in to comment.