举个例子,前面的《有序集合》一章曾经介绍过如何使用有序集合来实现自动补全功能,但是如果我们仔细地分析这个自动补全程序,就会发现它有一个潜在的问题:为了实现自动补全功能,程序需要创建大量自动补全结果,而补全结果的数量越多、体积越大,需要耗费的内存也会越多。

    为了尽可能地节约内存,一个高效的自动补全程序应该只储存热门关键字的自动补全结果,并移除那些无人访问的冷门关键字的自动补全结果。要做到这一点,其中一种方法就是使用《有序集合》里面介绍过的排行榜程序,为用户输入的关键字构建一个排行榜,然后定期地删除排名靠后关键字的自动补全结果。

    排行榜的方法虽然可行,但是却需要使用程序定期删除自动补全结果,使用起来相当麻烦。一个更方便也更优雅的方法,就是使用 EXPIRE 命令和 PEXPIRE 命令的更新特性去实现自动的冷门数据淘汰机制:为此,我们可以修改自动补全程序,让它在每次处理用户输入的时候,为相应关键字的自动补全结果设置生存时间。这样一来,对于用户经常输入的那些关键字,它们的自动补全结果的生存时间将会不断得到更新,从而产生出一种“续期”效果,使得热门关键字的自动补全结果可以不断地存在下去,而冷门关键字的自动补全结果则会由于生存时间得不到更新而自动被移除。


    代码清单 12-5 能够自动淘汰冷门数据的自动补全程序:/expire/auto_complete.py


    在以下代码中,我们同时向自动补全程序输入了 "Redis""Coffee" 这两个关键字,并分别为它们的自动补全结果设置了 10 秒钟的生存时间:

    然后在 10 秒钟之内,我们再次输入 "Redis" 关键字,并同样为它的自动补全结果设置 10 秒钟的生存时间:

    表 12-7 完整地展示了在执行以上代码时,"Redis" 关键字的自动补全结果是如何进行续期的,而 "Coffee" 关键字的自动补全结果又是如何被移除的。在这个表格中,"Redis" 关键字代表的就是热门数据,而 "Coffee" 关键字代表的就是冷门数据:一直有用户访问的热门数据将持续地存在下去,而无人问津的冷门数据则会因为过期而被移除。


    表 12-7 冷门数据淘汰示例


    除了自动补全程序之外,我们还可以把这一机制应用到其他需要淘汰冷门数据的程序上面。为了做到这一点,我们必须理解上面所说的“不断更新键的生存时间,使得它一直存在”这个原理。