Skip to main content
Rollback to Revision 3
Source Link
Jamal
  • 35.2k
  • 13
  • 134
  • 238

UPDATE 22.10.2014

Thanks to @Rob for great comments and suggestions. I did read up on how to best deal with my problem and I particularly liked the Mike Ash blog on the subject, however I am still struggling to get this to work with any speedup. The following works.

-(void) addDictionaryItem:(NSString *) mykey withURL:(NSString *)myurl isDir:(BOOL)  myIsDir andLR:(NSString *)LR
{
    NSDictionary __block *mydict=nil;

      dispatch_barrier_async(queue_sync, ^{
         mydict = [self.dict objectForKey:mykey];
    
    
         if ( mydict !=nil) {
        
             NSMutableArray *myarray = [mydict objectForKey:@"myarray"];
             NSMutableArray *myarrayIsDir = [mydict objectForKey:@"isdir"];
             NSMutableArray *myarrayLR = [mydict objectForKey:@"LR"];
        
             if (![myarray containsObject:myurl]){
                 [myarray addObject:myurl];
            
                 [myarrayLR addObject:LR];
                 [myarrayIsDir addObject:[NSNumber numberWithBool:myIsDir]];
            }
        }
    
        else {
            NSMutableArray *arrayOfFiles = [NSMutableArray array];
            [arrayOfFiles addObject:myurl];
        
            NSMutableArray *arrayIsDir = [NSMutableArray array];
            [arrayIsDir addObject:[NSNumber numberWithBool:myIsDir]];
        
            NSMutableArray *arrayOfLR = [NSMutableArray array];
            [arrayOfLR addObject:LR];
        
            NSMutableDictionary *attrDict = [NSMutableDictionary dictionaryWithObjectsAndKeys:arrayOfLR, @"LR",
                                         arrayOfFiles, @"myarray", arrayIsDir, @"isdir",
                                         nil];
        
            [self.dict setObject:attrDict forKey:mykey];
        }
    });
}

Basically I am just wrapping the whole method in a dispatch_barrier_async call. The queue is defined as queue_sync = dispatch_queue_create("com.my.queue", DISPATCH_QUEUE_CONCURRENT);. The new method finishes at the same speed as my previous approach. I tried to implement a separate concurrent read of the dictionary mydict = [self.dict objectForKey:mykey]; but this did not work as the dictionary may be updated while it is being read. Eventually I will move towards a better approach than having three separate arrays to keep track of. The reason I need this is because I only want to keep track of children of nodes that fulfill certain requirements. This means I have to keep my own recursive record of children and children's children in a tree structure. Currently this works but its slow.

Suggestions as to ways to make the current method be even more efficient are greatly welcomed.

UPDATE 22.10.2014

Thanks to @Rob for great comments and suggestions. I did read up on how to best deal with my problem and I particularly liked the Mike Ash blog on the subject, however I am still struggling to get this to work with any speedup. The following works.

-(void) addDictionaryItem:(NSString *) mykey withURL:(NSString *)myurl isDir:(BOOL)  myIsDir andLR:(NSString *)LR
{
    NSDictionary __block *mydict=nil;

      dispatch_barrier_async(queue_sync, ^{
         mydict = [self.dict objectForKey:mykey];
    
    
         if ( mydict !=nil) {
        
             NSMutableArray *myarray = [mydict objectForKey:@"myarray"];
             NSMutableArray *myarrayIsDir = [mydict objectForKey:@"isdir"];
             NSMutableArray *myarrayLR = [mydict objectForKey:@"LR"];
        
             if (![myarray containsObject:myurl]){
                 [myarray addObject:myurl];
            
                 [myarrayLR addObject:LR];
                 [myarrayIsDir addObject:[NSNumber numberWithBool:myIsDir]];
            }
        }
    
        else {
            NSMutableArray *arrayOfFiles = [NSMutableArray array];
            [arrayOfFiles addObject:myurl];
        
            NSMutableArray *arrayIsDir = [NSMutableArray array];
            [arrayIsDir addObject:[NSNumber numberWithBool:myIsDir]];
        
            NSMutableArray *arrayOfLR = [NSMutableArray array];
            [arrayOfLR addObject:LR];
        
            NSMutableDictionary *attrDict = [NSMutableDictionary dictionaryWithObjectsAndKeys:arrayOfLR, @"LR",
                                         arrayOfFiles, @"myarray", arrayIsDir, @"isdir",
                                         nil];
        
            [self.dict setObject:attrDict forKey:mykey];
        }
    });
}

Basically I am just wrapping the whole method in a dispatch_barrier_async call. The queue is defined as queue_sync = dispatch_queue_create("com.my.queue", DISPATCH_QUEUE_CONCURRENT);. The new method finishes at the same speed as my previous approach. I tried to implement a separate concurrent read of the dictionary mydict = [self.dict objectForKey:mykey]; but this did not work as the dictionary may be updated while it is being read. Eventually I will move towards a better approach than having three separate arrays to keep track of. The reason I need this is because I only want to keep track of children of nodes that fulfill certain requirements. This means I have to keep my own recursive record of children and children's children in a tree structure. Currently this works but its slow.

Suggestions as to ways to make the current method be even more efficient are greatly welcomed.

Fixed a bug and updated answer accordingly
Source Link

UPDATE 2122.10.2014

Thanks to @Rob for great comments and suggestions. I did read up on how to best deal with my problem and I particularly liked the Mike Ash blogMike Ash blog on the subject, however I am still struggling to get this to work correctlywith any speedup. I tried theThe following works.

-(void) addDictionaryItem:(NSString *) mykey withURL:(NSString *)myurl isDir:(BOOL)  myIsDir andLR:(NSString *)LR
{
    NSDictionary __block *mydict=nil;

      dispatch_barrier_async(queue_sync, ^{
         mydict = [self.dict objectForKey:mykey];
    
    
         if ( mydict !=nil) {
        
             NSMutableArray *myarray = [mydict objectForKey:@"myarray"];
             NSMutableArray *myarrayIsDir = [mydict objectForKey:@"isdir"];
             NSMutableArray *myarrayLR = [mydict objectForKey:@"LR"];
        
             if (![myarray containsObject:myurl]){
                 [myarray addObject:myurl];
            
                 [myarrayLR addObject:LR];
                 [myarrayIsDir addObject:[NSNumber numberWithBool:myIsDir]];
            }
        }
    
        else {
            NSMutableArray *arrayOfFiles = [NSMutableArray array];
            [arrayOfFiles addObject:myurl];
        
            NSMutableArray *arrayIsDir = [NSMutableArray array];
            [arrayIsDir addObject:[NSNumber numberWithBool:myIsDir]];
        
            NSMutableArray *arrayOfLR = [NSMutableArray array];
            [arrayOfLR addObject:LR];
        
            NSMutableDictionary *attrDict = [NSMutableDictionary dictionaryWithObjectsAndKeys:arrayOfLR, @"LR",
                                         arrayOfFiles, @"myarray", arrayIsDir, @"isdir",
                                         nil];
        
            [self.dict setObject:attrDict forKey:mykey];
        }
    });
}

Basically I am just wrapping the whole method in a dispatch_barrier_async call. The queue is defined as queue_sync = dispatch_queue_create("com.my.queue", DISPATCH_QUEUE_CONCURRENT);. The new method finishes at the same speed as my previous approach. I tried to implement a separate concurrent read of the dictionary mydict = [self.dict objectForKey:mykey]; (as suggested by Mike Ash) but this did not work as the dictionary may be updated while it is being read. The current approach also creates instability to the code where my program eventually crashes with error on <__NSArrayM: 0x7fa93254b210> was mutated while being enumerated. So clearly my lock is not functioning correctly as this does not happen with my original synchronized approach. I am definitely doing something wrong here and I appreciate suggestions that will speed-up and stabilize my code. Eventually I will move towards a better approach than having three separate arrays to keep track of. The reason I need this is because I only want to keep track of children of nodes that fulfill certain requirements. This means I have to keep my own recursive record of children and children's children in a tree structure. Currently this works but its slow.

Suggestions as to what I did wrong in my update based on @Rob s suggestionsways to make the current method be even more efficient are greatly welcomed.

UPDATE 21.10.2014

Thanks to @Rob for great comments and suggestions. I did read up on how to best deal with my problem and I particularly liked the Mike Ash blog on the subject, however I am still struggling to get this to work correctly. I tried the following.

-(void) addDictionaryItem:(NSString *) mykey withURL:(NSString *)myurl isDir:(BOOL)  myIsDir andLR:(NSString *)LR
{
    NSDictionary __block *mydict=nil;

     dispatch_barrier_async(queue_sync, ^{
         mydict = [self.dict objectForKey:mykey];
    
    
         if ( mydict !=nil) {
        
             NSMutableArray *myarray = [mydict objectForKey:@"myarray"];
             NSMutableArray *myarrayIsDir = [mydict objectForKey:@"isdir"];
             NSMutableArray *myarrayLR = [mydict objectForKey:@"LR"];
        
             if (![myarray containsObject:myurl]){
                 [myarray addObject:myurl];
            
                 [myarrayLR addObject:LR];
                 [myarrayIsDir addObject:[NSNumber numberWithBool:myIsDir]];
            }
        }
    
        else {
            NSMutableArray *arrayOfFiles = [NSMutableArray array];
            [arrayOfFiles addObject:myurl];
        
            NSMutableArray *arrayIsDir = [NSMutableArray array];
            [arrayIsDir addObject:[NSNumber numberWithBool:myIsDir]];
        
            NSMutableArray *arrayOfLR = [NSMutableArray array];
            [arrayOfLR addObject:LR];
        
            NSMutableDictionary *attrDict = [NSMutableDictionary dictionaryWithObjectsAndKeys:arrayOfLR, @"LR",
                                         arrayOfFiles, @"myarray", arrayIsDir, @"isdir",
                                         nil];
        
            [self.dict setObject:attrDict forKey:mykey];
        }
    });
}

Basically I am just wrapping the whole method in a dispatch_barrier_async call. The queue is defined as queue_sync = dispatch_queue_create("com.my.queue", DISPATCH_QUEUE_CONCURRENT);. The new method finishes at the same speed as my previous approach. I tried to implement a separate concurrent read of the dictionary mydict = [self.dict objectForKey:mykey]; (as suggested by Mike Ash) but this did not work as the dictionary may be updated while it is being read. The current approach also creates instability to the code where my program eventually crashes with error on <__NSArrayM: 0x7fa93254b210> was mutated while being enumerated. So clearly my lock is not functioning correctly as this does not happen with my original synchronized approach. I am definitely doing something wrong here and I appreciate suggestions that will speed-up and stabilize my code. Eventually I will move towards a better approach than having three separate arrays to keep track of. The reason I need this is because I only want to keep track of children of nodes that fulfill certain requirements. This means I have to keep my own recursive record of children and children's children in a tree structure. Currently this works but its slow.

Suggestions as to what I did wrong in my update based on @Rob s suggestions are greatly welcomed.

UPDATE 22.10.2014

Thanks to @Rob for great comments and suggestions. I did read up on how to best deal with my problem and I particularly liked the Mike Ash blog on the subject, however I am still struggling to get this to work with any speedup. The following works.

-(void) addDictionaryItem:(NSString *) mykey withURL:(NSString *)myurl isDir:(BOOL)  myIsDir andLR:(NSString *)LR
{
    NSDictionary __block *mydict=nil;

      dispatch_barrier_async(queue_sync, ^{
         mydict = [self.dict objectForKey:mykey];
    
    
         if ( mydict !=nil) {
        
             NSMutableArray *myarray = [mydict objectForKey:@"myarray"];
             NSMutableArray *myarrayIsDir = [mydict objectForKey:@"isdir"];
             NSMutableArray *myarrayLR = [mydict objectForKey:@"LR"];
        
             if (![myarray containsObject:myurl]){
                 [myarray addObject:myurl];
            
                 [myarrayLR addObject:LR];
                 [myarrayIsDir addObject:[NSNumber numberWithBool:myIsDir]];
            }
        }
    
        else {
            NSMutableArray *arrayOfFiles = [NSMutableArray array];
            [arrayOfFiles addObject:myurl];
        
            NSMutableArray *arrayIsDir = [NSMutableArray array];
            [arrayIsDir addObject:[NSNumber numberWithBool:myIsDir]];
        
            NSMutableArray *arrayOfLR = [NSMutableArray array];
            [arrayOfLR addObject:LR];
        
            NSMutableDictionary *attrDict = [NSMutableDictionary dictionaryWithObjectsAndKeys:arrayOfLR, @"LR",
                                         arrayOfFiles, @"myarray", arrayIsDir, @"isdir",
                                         nil];
        
            [self.dict setObject:attrDict forKey:mykey];
        }
    });
}

Basically I am just wrapping the whole method in a dispatch_barrier_async call. The queue is defined as queue_sync = dispatch_queue_create("com.my.queue", DISPATCH_QUEUE_CONCURRENT);. The new method finishes at the same speed as my previous approach. I tried to implement a separate concurrent read of the dictionary mydict = [self.dict objectForKey:mykey]; but this did not work as the dictionary may be updated while it is being read. Eventually I will move towards a better approach than having three separate arrays to keep track of. The reason I need this is because I only want to keep track of children of nodes that fulfill certain requirements. This means I have to keep my own recursive record of children and children's children in a tree structure. Currently this works but its slow.

Suggestions as to ways to make the current method be even more efficient are greatly welcomed.

Update based on suggestions
Source Link

UPDATE 21.10.2014

Thanks to @Rob for great comments and suggestions. I did read up on how to best deal with my problem and I particularly liked the Mike Ash blog on the subject, however I am still struggling to get this to work correctly. I tried the following.

-(void) addDictionaryItem:(NSString *) mykey withURL:(NSString *)myurl isDir:(BOOL)  myIsDir andLR:(NSString *)LR
{
    NSDictionary __block *mydict=nil;

     dispatch_barrier_async(queue_sync, ^{
         mydict = [self.dict objectForKey:mykey];
    
    
         if ( mydict !=nil) {
        
             NSMutableArray *myarray = [mydict objectForKey:@"myarray"];
             NSMutableArray *myarrayIsDir = [mydict objectForKey:@"isdir"];
             NSMutableArray *myarrayLR = [mydict objectForKey:@"LR"];
        
             if (![myarray containsObject:myurl]){
                 [myarray addObject:myurl];
            
                 [myarrayLR addObject:LR];
                 [myarrayIsDir addObject:[NSNumber numberWithBool:myIsDir]];
            }
        }
    
        else {
            NSMutableArray *arrayOfFiles = [NSMutableArray array];
            [arrayOfFiles addObject:myurl];
        
            NSMutableArray *arrayIsDir = [NSMutableArray array];
            [arrayIsDir addObject:[NSNumber numberWithBool:myIsDir]];
        
            NSMutableArray *arrayOfLR = [NSMutableArray array];
            [arrayOfLR addObject:LR];
        
            NSMutableDictionary *attrDict = [NSMutableDictionary dictionaryWithObjectsAndKeys:arrayOfLR, @"LR",
                                         arrayOfFiles, @"myarray", arrayIsDir, @"isdir",
                                         nil];
        
            [self.dict setObject:attrDict forKey:mykey];
        }
    });
}

Basically I am just wrapping the whole method in a dispatch_barrier_async call. The queue is defined as queue_sync = dispatch_queue_create("com.my.queue", DISPATCH_QUEUE_CONCURRENT);. The new method finishes at the same speed as my previous approach. I tried to implement a separate concurrent read of the dictionary mydict = [self.dict objectForKey:mykey]; (as suggested by Mike Ash) but this did not work as the dictionary may be updated while it is being read. The current approach also creates instability to the code where my program eventually crashes with error on <__NSArrayM: 0x7fa93254b210> was mutated while being enumerated. So clearly my lock is not functioning correctly as this does not happen with my original synchronized approach. I am definitely doing something wrong here and I appreciate suggestions that will speed-up and stabilize my code. Eventually I will move towards a better approach than having three separate arrays to keep track of. The reason I need this is because I only want to keep track of children of nodes that fulfill certain requirements. This means I have to keep my own recursive record of children and children's children in a tree structure. Currently this works but its slow.

Suggestions as to what I did wrong in my update based on @Rob s suggestions are greatly welcomed.

UPDATE 21.10.2014

Thanks to @Rob for great comments and suggestions. I did read up on how to best deal with my problem and I particularly liked the Mike Ash blog on the subject, however I am still struggling to get this to work correctly. I tried the following.

-(void) addDictionaryItem:(NSString *) mykey withURL:(NSString *)myurl isDir:(BOOL)  myIsDir andLR:(NSString *)LR
{
    NSDictionary __block *mydict=nil;

     dispatch_barrier_async(queue_sync, ^{
         mydict = [self.dict objectForKey:mykey];
    
    
         if ( mydict !=nil) {
        
             NSMutableArray *myarray = [mydict objectForKey:@"myarray"];
             NSMutableArray *myarrayIsDir = [mydict objectForKey:@"isdir"];
             NSMutableArray *myarrayLR = [mydict objectForKey:@"LR"];
        
             if (![myarray containsObject:myurl]){
                 [myarray addObject:myurl];
            
                 [myarrayLR addObject:LR];
                 [myarrayIsDir addObject:[NSNumber numberWithBool:myIsDir]];
            }
        }
    
        else {
            NSMutableArray *arrayOfFiles = [NSMutableArray array];
            [arrayOfFiles addObject:myurl];
        
            NSMutableArray *arrayIsDir = [NSMutableArray array];
            [arrayIsDir addObject:[NSNumber numberWithBool:myIsDir]];
        
            NSMutableArray *arrayOfLR = [NSMutableArray array];
            [arrayOfLR addObject:LR];
        
            NSMutableDictionary *attrDict = [NSMutableDictionary dictionaryWithObjectsAndKeys:arrayOfLR, @"LR",
                                         arrayOfFiles, @"myarray", arrayIsDir, @"isdir",
                                         nil];
        
            [self.dict setObject:attrDict forKey:mykey];
        }
    });
}

Basically I am just wrapping the whole method in a dispatch_barrier_async call. The queue is defined as queue_sync = dispatch_queue_create("com.my.queue", DISPATCH_QUEUE_CONCURRENT);. The new method finishes at the same speed as my previous approach. I tried to implement a separate concurrent read of the dictionary mydict = [self.dict objectForKey:mykey]; (as suggested by Mike Ash) but this did not work as the dictionary may be updated while it is being read. The current approach also creates instability to the code where my program eventually crashes with error on <__NSArrayM: 0x7fa93254b210> was mutated while being enumerated. So clearly my lock is not functioning correctly as this does not happen with my original synchronized approach. I am definitely doing something wrong here and I appreciate suggestions that will speed-up and stabilize my code. Eventually I will move towards a better approach than having three separate arrays to keep track of. The reason I need this is because I only want to keep track of children of nodes that fulfill certain requirements. This means I have to keep my own recursive record of children and children's children in a tree structure. Currently this works but its slow.

Suggestions as to what I did wrong in my update based on @Rob s suggestions are greatly welcomed.

deleted 62 characters in body
Source Link
Jamal
  • 35.2k
  • 13
  • 134
  • 238
Loading
Typo
Source Link
Loading
Source Link
Loading