Skip to content

Commit 46dc417

Browse files
authored
fix: optimize LRU cache (#985)
1 parent 4f0dfee commit 46dc417

File tree

4 files changed

+55
-1
lines changed

4 files changed

+55
-1
lines changed

WebDriverAgentLib/Routing/FBElementCache.m

+11-1
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,17 @@ - (XCUIElement *)elementForUUID:(NSString *)uuid checkStaleness:(BOOL)checkStale
7373
@throw [NSException exceptionWithName:FBStaleElementException reason:reason userInfo:@{}];
7474
}
7575
if (checkStaleness) {
76-
[element fb_takeSnapshot:NO];
76+
@try {
77+
[element fb_takeSnapshot:NO];
78+
} @catch (NSException *exception) {
79+
// if the snapshot method threw FBStaleElementException (implying the element is stale) we need to explicitly remove it from the cache, PR: https://github.com/appium/WebDriverAgent/pull/985
80+
if ([exception.name isEqualToString:FBStaleElementException]) {
81+
@synchronized (self.elementCache) {
82+
[self.elementCache removeObjectForKey:uuid];
83+
}
84+
}
85+
@throw exception;
86+
}
7787
}
7888
return element;
7989
}

WebDriverAgentLib/Utilities/LRUCache/LRUCache.h

+7
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,13 @@ NS_ASSUME_NONNULL_BEGIN
5454
*/
5555
- (NSArray *)allObjects;
5656

57+
/**
58+
Removes the object associated with the specified key from the cache.
59+
60+
@param key The key identifying the object to remove.
61+
*/
62+
- (void)removeObjectForKey:(id<NSCopying>)key;
63+
5764
@end
5865

5966
NS_ASSUME_NONNULL_END

WebDriverAgentLib/Utilities/LRUCache/LRUCache.m

+8
Original file line numberDiff line numberDiff line change
@@ -135,4 +135,12 @@ - (void)alignSize
135135
}
136136
}
137137

138+
- (void)removeObjectForKey:(id<NSCopying>)key
139+
{
140+
LRUCacheNode *node = self.store[key];
141+
if (node != nil) {
142+
[self removeNode:node];
143+
}
144+
}
145+
138146
@end

WebDriverAgentTests/UnitTests/FBLRUCacheTests.m

+29
Original file line numberDiff line numberDiff line change
@@ -96,4 +96,33 @@ - (void)testInsertionLoop
9696
XCTAssertEqualObjects(@[@(count)], cache.allObjects);
9797
}
9898

99+
- (void)testRemoveExistingObjectForKey {
100+
LRUCache *cache = [[LRUCache alloc] initWithCapacity:3];
101+
[cache setObject:@"foo" forKey:@"bar"];
102+
[cache setObject:@"foo2" forKey:@"bar2"];
103+
[cache setObject:@"foo3" forKey:@"bar3"];
104+
[self assertArray:@[@"foo3", @"foo2", @"foo"] equalsTo:cache.allObjects];
105+
[cache removeObjectForKey:@"bar2"];
106+
XCTAssertNil([cache objectForKey:@"bar2"]);
107+
[self assertArray:@[@"foo3", @"foo"] equalsTo:cache.allObjects];
108+
}
109+
110+
- (void)testRemoveNonExistingObjectForKey {
111+
LRUCache *cache = [[LRUCache alloc] initWithCapacity:2];
112+
[cache setObject:@"foo" forKey:@"bar"];
113+
[cache removeObjectForKey:@"nonExisting"];
114+
XCTAssertNotNil([cache objectForKey:@"bar"]);
115+
[self assertArray:@[@"foo"] equalsTo:cache.allObjects];
116+
}
117+
118+
- (void)testRemoveAndInsertFlow {
119+
LRUCache *cache = [[LRUCache alloc] initWithCapacity:2];
120+
[cache setObject:@"foo" forKey:@"bar"];
121+
[cache setObject:@"foo2" forKey:@"bar2"];
122+
[cache removeObjectForKey:@"bar"];
123+
XCTAssertNil([cache objectForKey:@"bar"]);
124+
[cache setObject:@"foo3" forKey:@"bar3"];
125+
[self assertArray:@[@"foo3", @"foo2"] equalsTo:cache.allObjects];
126+
}
127+
99128
@end

0 commit comments

Comments
 (0)