Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

YYMemoryCache sync set method bug #54

Closed
maquannene opened this issue Jun 15, 2016 · 2 comments
Closed

YYMemoryCache sync set method bug #54

maquannene opened this issue Jun 15, 2016 · 2 comments

Comments

@maquannene
Copy link

maquannene commented Jun 15, 2016

YY 大神你好,最近我也在完善我自己写的一个 SwiftCache,在对比测试各个 cache 库时,发现了一个问题,不知是有意为之增加同步效率,还是疏漏。

- (void)setObject:(id)object forKey:(id)key withCost:(NSUInteger)cost {
...
    if (_lru->_totalCost > _costLimit) {
        dispatch_async(_queue, ^{
            [self trimToCost:_costLimit];
        });
    }
...
}

具体问题在 memoryCache 的同步写入的操作(上述代码),同步写入完成之后,有一个淘汰的过程,这时在淘汰 cost 时采用的是异步主线程淘汰,潜在问题在于如果紧接着做同步的读 cache,可能会出现异步主线程的 cost 淘汰还没有执行的情况。

我试图去更改您的代码,想要 PR,如下:

- (void)setObject:(id)object forKey:(id)key withCost:(NSUInteger)cost {
   ...
    pthread_mutex_unlock(&_lock); // 这里解锁,因为 trimToCost 中有锁

    if (_lru->_totalCost > _costLimit) {
       // 去掉异步 trim
        [self trimToCost:_costLimit];
    }

    pthread_mutex_lock(&_lock); // 这里再次加锁
    ...
}

但发现 if 中的 _lru _totalCost _costLimit 又变成了非线程安全,所以可能需要改的地方比较多,希望您看下是是否需要更正。
不胜感激。

@ibireme
Copy link
Owner

ibireme commented Jun 15, 2016

这块儿是优先保证调用线程的效率,至于淘汰没有完成这个重要性不高,这时即使读取到了也是正常现象。

调用 removeObjectForKey 时,调用者是明确要移除某个对象的,这时就会是同步操作了。

@maquannene
Copy link
Author

恩,确实有道理。
某种角度来说 count 的淘汰保证实时性是必要的,cost 就不是很必要了。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants