美文网首页
侵入式链表实现

侵入式链表实现

作者: wayyyy | 来源:发表于2021-03-27 17:36 被阅读0次

先来看2个宏

#define offset(struct_type, member) (int)(&((struct_type*)0)->member)

假设:
struct Foo
{
    int a;
    int b;
    Foo* next;
};

offset(struct Foo, a);    // 0
offset(struct Foo, b);    // 4
offset(struct Foo, next); // 8 

offset 宏的目的是推算出一个成员的偏移量。

Foo.png

(struct_type*)0 将0x0 强制转为struct_type的首地址。
((struct_type*)0)->member)为目标成员。
(int)(&((struct_type*)0)->member))将目标成员取地址,因为是从0x0开始,所以这个地址也就恰好成为了目标成员的偏移地址。

#define elem2entry(struct_type, struct_member_name, elem_ptr) \
     (struct_type*)((int)elem_ptr - offset(struct_type, struct_member_name))

假设:
struct link 
{
    struct link* next;
};

struct Foo
{
    int a; 
    struct link link_tag;
};

struct Foo foo;
foo.a = 20; foo.link_tag.next = NULL;
    
struct link* linkptr = &(foo.link_tag);
 
struct Foo* fp = elem2entry(struct Foo, link_tag, linkptr);
   
printf("%d\n", fp->a);
image.png
struct list_elem
{
    struct list_elem* prev;
    struct list_elem* next;
};

/* 实现队列 */
struct list
{
    struct list_elem head;  // head 队首,固定不变. 第一个元素是head.next
    struct list_elem tail;  // tail 队尾,固定不变.
};
  • 初始化双向链表
/* 初始化双向链表 */
void list_init(struct list* list)
{
    list->head.prev = NULL;
    list->head.next = &(list->tail);
    list->tail.prev = &(list->head);
    list->tail.next = NULL;
}
image.png
  • 把elem插入在元素before之前
void list_insert_before(struct list_elem* before, struct list_elem* elem)
{
    before->prev->next = elem;

    elem->prev = before->prev;
    elem->next = before;

    before->prev = elem;
}

/* 添加元素到列表队首,类似push_front操作 */
void list_push(struct list* plist, struct list_elem* elem)
{
    list_insert_before(plist->head.next, elem);
}

/* 追加元素到链表队尾,类似队列的先进先出操作 */
void list_append(struct list* plist, struct list_elem* elem)
{
    list_insert_before(&(plist->tail), elem);
}
  • 删除元素pelem脱离链表
/* 使元素pelem脱离链表 */
void list_remove(struct list_elem* pelem)
{
    // 实现原子操作,关掉中断
    enum intr_status old_status = intr_disable();

    pelem->prev->next = pelem->next;
    pelem->next->prev = pelem->prev;

    intr_set_status(old_status);
}

/* 将链表第一个元素弹出并返回 */
struct list_elem* list_pop(struct list* plist)
{
    struct list_elem* elem = plist->head.next;
    list_remove(elem);
    return elem;
}

相关文章

  • 侵入式链表实现

    先来看2个宏 offset 宏的目的是推算出一个成员的偏移量。 (struct_type*)0 将0x0 强制转为...

  • Boost侵入式容器设计

    此篇博客的目标: 1.解释何为boost侵入式容器 2.利用boost侵入式容器实现根据不同变量做键来进行排序 一...

  • APM 探针分析

    概要 APM探针主要有侵入式探针和非侵入式探针。 其中侵入式探针以zipkin为代表,非侵入式探针以pinpoin...

  • Spring Session实现无侵入性Redis缓存

    在之前的小结Redis分布式实现(原生实现)中实现了原生的分布式redis缓存方案,但它的侵入性太强,对于已有的项...

  • AOP

    相关依赖 java动态代理 注解aop(侵入式) 非侵入式 XML配置

  • 非侵入式和侵入式区别

    非侵入式 允许在应用系统中自由选择和组装Spring框架的各个功能模块,并且不强制要求应用系统的类必须从Sprin...

  • 单链表 & 双链表& 单向循环链表的实现

    单链表 具体实现: 双链表 代码实现: 单向循环链表的实现 代码实现:

  • Spring 核心 : IOC 处理器扩展

    非侵入式框架 Spring一直标注自己是一个非侵入式框架。非侵入式设计的概念并不新鲜,目标就是降低使用者和框架代码...

  • Spring核心——IOC处理器扩展

    非侵入式框架 Spring一直标注自己是一个非侵入式框架。非侵入式设计的概念并不新鲜,目标就是降低使用者和框架代码...

  • 链表

    一、单向链表 单向链表的普通实现 Java实现: Kotlin实现: 单向链表的递归实现 Java实现: 二、双向...

网友评论

      本文标题:侵入式链表实现

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