美文网首页
双向链表 应用

双向链表 应用

作者: 小小爱笑 | 来源:发表于2019-04-10 13:48 被阅读0次

前言

通过双向链表实现session的过期扫描。

双向链表

go 中实现为 list.List

type List struct {
    root Element // sentinel list element, only &root, root.prev, and root.next are used
    len  int     // current list length excluding (this) sentinel element
}

// Element is an element of a linked list.
type Element struct {
    // Next and previous pointers in the doubly-linked list of elements.
    // To simplify the implementation, internally a list l is implemented
    // as a ring, such that &l.root is both the next element of the last
    // list element (l.Back()) and the previous element of the first list
    // element (l.Front()).
    next, prev *Element

    // The list to which this element belongs.
    list *List

    // The value stored with this element.
    Value interface{}
}

实例

web开发中服务端需要维护session, session的实现可以有多种方式。例如内存,文件,数据库,redis 等。所以,对于不同的实现,抽象出Provider接口,实现有MemProvider FileProvider RedisProvider ...
另外,session通常有过期时间,所以需要服务端定期回收过期session。

provider接口定义如下:

type Provider interface {
    SessionInit(gclifetime int64, config string) error
    SessionRead(sid string) (Store, error)
    SessionExist(sid string) bool
    SessionDestroy(sid string) error
    SessionAll() int //get all active session
    SessionGC()
}

以内存session provider为例,通常通过map保存session,通过map而不是list,因为map保证了查找时间是o(1), 即SessionRead 通过session id 获取session。

type MemProvider struct {
    lock        sync.RWMutex             // locker
    sessions    map[string]*list.Element // map in memory
    list        *list.List               // for gc
    maxlifetime int64
}

如果只有map保存数据,当每次定期清理过期session时,需要遍历 时间复杂度为o(n)。所以为了提高清理效率,使用list维护记录session,当更新session最后使用时间时,将list中的session放到列表首部。list首部是最近使用的session。
当清理过期遍历时,从list尾部遍历,直到遇到第一个没有过期的session结束。

map的value中存储的是*list.Element类型,通过map的key获取element,然后通过element操作list。如果map的value中只存了使用方的value类型,则无法通过map的key快速找到list中的元素。

链表的节点存储key和value,使用节点中的key可以操作map。 类似于java中linkedhashmap 的内部类Entry<k,v>

java中 类似需求 可以使用 LinkedHashMap ,将构造函数第三个参数 设为true

参考资料

思考

  • 使用堆大堆,按session的最后更新时间排序。代替list
    堆 提供添加和删除接口,对于变更session的最后更新时间,无法方便维护堆结构。而双向链表将元素移动到首尾,时间复杂度为o(1)
  • 使用 单向链表,代替。
    将元素移动到首尾,单向链表无法实现o(1)的复杂度。
  • 堆 与 双向链表 使用场景对比
    双向链表维护顺序时,包含3个操作, 新增,删除,更新
    新增,更新操作时,元素都会被放到首部或尾部。不会存在新增元素,排序的结构是放到链表中。
    堆维护顺序时, 包含2个操作,新增,从顶点删除
    新增元素后,堆重新排序,将元素放到符合结构的位置,最终结果元素不一定在顶点。

相关文章

  • 双向链表&双向循环链表

    链表分为:单链表、单向循环链表、双向链表、双向循环链表本节主要说明:双向链表、双向循环链表 定义结点 一、双向链表...

  • 双向链表 应用

    前言 通过双向链表实现session的过期扫描。 双向链表 go 中实现为 list.List 实例 web开发中...

  • 线性表-双向链表与双向循环链表

    双向链表 双向链表示意图如下: 数据结构定义 创建双向链表 双向链表插入元素 双向链表删除元素 双向链表打印元素 ...

  • day03-双向链表

    双向链表: 单向链表只能单向查找,双向链表可以双向查找。 啥是双向链表? 双向链表可以双向查数据,所以就不存在单向...

  • 线性表--链式存储结构--双向链表

    双向链表 一、双向链表结构 双向链表结点结构 既然单链表可以有循环链表,那么双向链表当然也可以有。 由于这是双向链...

  • 双向链表和双向循环链表

    双向链表 线性表-双向链表的结点结构: 带头结点的双向链表: 1.双向链表初始化 2.遍历双向链表 2.双向链表插...

  • 数据结构与算法之双向链表(3.3)

    目录 双向链表简介双向链表重要方法讲解实战检测双向链表,单向链表性能对比 一 双向链表简介 双向链表-只有一个元素...

  • 双向链表&双向循环链表

    一、双向链表 带有前驱结点、后区节点 双向链表的创建 双向链表插入-逻辑 双向链表删除 删除双向链表指定的元素 二...

  • 9.双向链表DoubleLinkList

    目录:1.双向链表的定义2.双向链表的图解3.双向链表定义操作4.双向链表的实现 1.双向链表的定义 2.双向链表...

  • 7.双向链表正确实现方式

    链表是基本的数据结构,尤其双向链表在应用中最为常见,LinkedList 就实现了双向链表。今天我们一起手写一个双...

网友评论

      本文标题:双向链表 应用

      本文链接:https://www.haomeiwen.com/subject/tpjniqtx.html