zoukankan      html  css  js  c++  java
  • 深入了解Redis(4)-类型检查与命令多态

    Redis 中用于操作键的命令基本上可以分为两种类型。

    其中一种命令可以对任何类型的键执行, 比如说 DEL 命令、 EXPIRE 命令、 RENAME 命令、 TYPE 命令、 OBJECT 命令, 等等。

    而另一种命令只能对特定类型的键执行, 比如说:

    • SET 、 GET 、 APPEND 、 STRLEN 等命令只能对字符串键执行;
    • HDEL 、 HSET 、 HGET 、 HLEN 等命令只能对哈希键执行;
    • RPUSH 、 LPOP 、 LINSERT 、 LLEN 等命令只能对列表键执行;
    • SADD 、 SPOP 、 SINTER 、 SCARD 等命令只能对集合键执行;
    • ZADD 、 ZCARD 、 ZRANK 、 ZSCORE 等命令只能对有序集合键执行;

    类型检查的实现

    在执行一个类型特定的命令之前, Redis 会先检查输入键的类型是否正确, 然后再决定是否执行给定的命令。

    类型特定命令所进行的类型检查是通过 redisObject 结构的 type 属性来实现的:

    • 在执行一个类型特定命令之前, 服务器会先检查输入数据库键的值对象是否为执行命令所需的类型, 如果是的话, 服务器就对键执行指定的命令;
    • 否则, 服务器将拒绝执行命令, 并向客户端返回一个类型错误。

    举个例子, 对于 LLEN 命令来说:

    • 在执行 LLEN 命令之前, 服务器会先检查输入数据库键的值对象是否为列表类型, 也即是, 检查值对象 redisObject 结构 type 属性的值是否为 REDIS_LIST , 如果是的话, 服务器就对键执行 LLEN 命令;
    • 否则的话, 服务器就拒绝执行命令并向客户端返回一个类型错误;

    过程如图:

    多态命令

    Redis 除了会根据值对象的类型来判断键是否能够执行指定命令之外, 还会根据值对象的编码方式, 选择正确的命令实现代码来执行命令。

    举个例子, 在前面介绍列表对象的编码时我们说过, 列表对象有 ziplist 和 linkedlist 两种编码可用, 其中前者使用压缩列表 API 来实现列表命令, 而后者则使用双端链表 API 来实现列表命令。

    现在, 考虑这样一个情况, 如果我们对一个键执行 LLEN 命令, 那么服务器除了要确保执行命令的是列表键之外, 还需要根据键的值对象所使用的编码来选择正确的 LLEN 命令实现:

    • 如果列表对象的编码为 ziplist , 那么说明列表对象的实现为压缩列表, 程序将使用 ziplistLen 函数来返回列表的长度;
    • 如果列表对象的编码为 linkedlist , 那么说明列表对象的实现为双端链表, 程序将使用 listLength 函数来返回双端链表的长度;

    借用面向对象方面的术语来说, 我们可以认为 LLEN 命令是多态(polymorphism)的: 只要执行 LLEN 命令的是列表键, 那么无论值对象使用的是 ziplist 编码还是 linkedlist 编码, 命令都可以正常执行。

    图 8-19 展示了 LLEN 命令从类型检查到根据编码选择实现函数的整个执行过程, 其他类型特定命令的执行过程也是类似的。

  • 相关阅读:
    461. Hamming Distance
    342. Power of Four
    326. Power of Three
    368. Largest Divisible Subset java solutions
    95. Unique Binary Search Trees II java solutions
    303. Range Sum Query
    160. Intersection of Two Linked Lists java solutions
    88. Merge Sorted Array java solutions
    67. Add Binary java solutions
    14. Longest Common Prefix java solutions
  • 原文地址:https://www.cnblogs.com/iceggboom/p/13664224.html
Copyright © 2011-2022 走看看