持久性内存编程——类型

2024-02-29 21:48
文章标签 类型 内存 编程 持久性

本文主要是介绍持久性内存编程——类型,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

在之前的所有关于持久化内存编程的文章中,代码片段和示例都有持久指针(pmemoid),没有任何类型信息——它们是简单的C结构。在pmem库开发的早期,开发者发现使用类似的东西非常容易出错,而且通常很困难。他们在用类型安全容器封装pmemoids时付出了相当大的努力,最终结果可以与C++11中的SydDypTr等进行比较,之后的所有内容将只使用类型安全特性。

目录

布局声明

类型化持久指针

PMEMoid和TOID操作

运行时类型安全

用例


布局声明

所有使用pmemobj的持久内存程序都应该有一个明确定义的内存布局,最好是在自己的文件中进行布局的定义。为了提供运行时和编译时类型的安全性,除了声明结构之外,还需要使用特殊的宏。例如,我们的字符串存储示例的布局如下所示:

POBJ_LAYOUT_BEGIN(string_store);
POBJ_LAYOUT_ROOT(string_store, struct my_root);
POBJ_LAYOUT_END(string_store);#define	MAX_BUF_LEN 10
struct my_root {char buf[MAX_BUF_LEN];
};

现在可以在代码中使用类型化的持久指针。此代码中的字符串存储只是一个名称,创建或打开具有特定布局的池时,建议使用pobj_layout_name宏,如下所示:

pmemobj_create(path, POBJ_LAYOUT_NAME(string_store), PMEMOBJ_MIN_POOL, 0666);
...
pmemobj_open(path, POBJ_LAYOUT_NAME(string_store));

如果你觉得所有这些都令人困惑,请先阅读这篇文章( this ),这对该内容有深入解释。

类型化持久指针

使用以下构造来代替pmemoids指针:

TOID(struct my_root) root;

要取消引用,不再需要将另一个变量与pmemobj_direct结合使用,首选的方法是使用d_rw进行写入,使用d_ro进行读取。如下所示:

if (D_RO(root)->buf[0] != 0)D_RW(root)->buf[0] = 0;

大多数IDE都会正确地评估这些宏,并自动完成类型代码。

PMEMoid和TOID操作

一般来说,有两种类型的安全宏可以区分:在原始pmemoid上操作的宏(前缀为OID_),在类型TOID上操作的宏(前缀为TOID_)。

所有pmemobj_函数只接受原始pmemoids作为参数。我们通常建议只使用宏,但如果需要将TOID“强制转换”为pmemoid,可以这样做:

TOID(struct foo) data;
pmemobj_direct(data.oid);

所有没有TOID_或OID_前缀的宏通常都采用类型化指针,并将其作为结果返回(如POBJ_ROOT宏)。

运行时类型安全

布局中的每种类型都在内部分配了一个唯一的编号,然后可以用于验证。

例如,对现有软件的更新可能改变了布局,如下所示:

struct my_root_v1 {TOID(struct foo) data;
}
struct my_root_v2 {TOID(struct bar) data;
}

要检查布局的版本是否与现有对象对应,可以使用以下表达式:

if (TOID_VALID(D_RO(root)->data)) {/* can use the data ptr safely */
} else {/* declared type doesn't match the object */
}

如果不确定对象类型,也可以依赖嵌入的类型号,如:

PMEMoid data;
TOID(struct foo) foo;
TOID(struct bar) bar;
if (OID_INSTANCEOF(data, struct foo)) {TOID_ASSIGN(foo, data);
} else if (OID_INSTANCEOF(data, struct bar)) {TOID_ASSIGN(bar, data);
} else {/* error */
}

与高级语言的相似性并非偶然。

用例

这是最后一次修改字符串存储示例。layout.h修改可以在上面看到。首先,从root对象开始。可以使用以下行,而不是首先使用pmemobj_root函数,然后使用pmemobj_direct作为实际指针:

TOID(struct my_root) root = POBJ_ROOT(pop, struct my_root);

还记得怎么保证代码会变短的吗?writer.c:

TX_BEGIN(pop) {TX_MEMCPY(D_RW(root)->buf, buf, strlen(buf));
} TX_END

因为不再有rootp了,这个也变得简单了,reader.c

printf("%s\n", D_RO(root)->buf);

完整代码:repository

原文来自:http://pmem.io/2015/06/16/types.html

这篇关于持久性内存编程——类型的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/760200

相关文章

在Spring Boot中浅尝内存泄漏的实战记录

《在SpringBoot中浅尝内存泄漏的实战记录》本文给大家分享在SpringBoot中浅尝内存泄漏的实战记录,结合实例代码给大家介绍的非常详细,感兴趣的朋友一起看看吧... 目录使用静态集合持有对象引用,阻止GC回收关键点:可执行代码:验证:1,运行程序(启动时添加JVM参数限制堆大小):2,访问 htt

shell编程之函数与数组的使用详解

《shell编程之函数与数组的使用详解》:本文主要介绍shell编程之函数与数组的使用,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录shell函数函数的用法俩个数求和系统资源监控并报警函数函数变量的作用范围函数的参数递归函数shell数组获取数组的长度读取某下的

MySQL 中查询 VARCHAR 类型 JSON 数据的问题记录

《MySQL中查询VARCHAR类型JSON数据的问题记录》在数据库设计中,有时我们会将JSON数据存储在VARCHAR或TEXT类型字段中,本文将详细介绍如何在MySQL中有效查询存储为V... 目录一、问题背景二、mysql jsON 函数2.1 常用 JSON 函数三、查询示例3.1 基本查询3.2

Pydantic中Optional 和Union类型的使用

《Pydantic中Optional和Union类型的使用》本文主要介绍了Pydantic中Optional和Union类型的使用,这两者在处理可选字段和多类型字段时尤为重要,文中通过示例代码介绍的... 目录简介Optional 类型Union 类型Optional 和 Union 的组合总结简介Pyd

Oracle数据库常见字段类型大全以及超详细解析

《Oracle数据库常见字段类型大全以及超详细解析》在Oracle数据库中查询特定表的字段个数通常需要使用SQL语句来完成,:本文主要介绍Oracle数据库常见字段类型大全以及超详细解析,文中通过... 目录前言一、字符类型(Character)1、CHAR:定长字符数据类型2、VARCHAR2:变长字符数

揭秘Python Socket网络编程的7种硬核用法

《揭秘PythonSocket网络编程的7种硬核用法》Socket不仅能做聊天室,还能干一大堆硬核操作,这篇文章就带大家看看Python网络编程的7种超实用玩法,感兴趣的小伙伴可以跟随小编一起... 目录1.端口扫描器:探测开放端口2.简易 HTTP 服务器:10 秒搭个网页3.局域网游戏:多人联机对战4.

Java并发编程必备之Synchronized关键字深入解析

《Java并发编程必备之Synchronized关键字深入解析》本文我们深入探索了Java中的Synchronized关键字,包括其互斥性和可重入性的特性,文章详细介绍了Synchronized的三种... 目录一、前言二、Synchronized关键字2.1 Synchronized的特性1. 互斥2.

Spring Boot 配置文件之类型、加载顺序与最佳实践记录

《SpringBoot配置文件之类型、加载顺序与最佳实践记录》SpringBoot的配置文件是灵活且强大的工具,通过合理的配置管理,可以让应用开发和部署更加高效,无论是简单的属性配置,还是复杂... 目录Spring Boot 配置文件详解一、Spring Boot 配置文件类型1.1 applicatio

Python如何使用__slots__实现节省内存和性能优化

《Python如何使用__slots__实现节省内存和性能优化》你有想过,一个小小的__slots__能让你的Python类内存消耗直接减半吗,没错,今天咱们要聊的就是这个让人眼前一亮的技巧,感兴趣的... 目录背景:内存吃得满满的类__slots__:你的内存管理小助手举个大概的例子:看看效果如何?1.

Python异步编程中asyncio.gather的并发控制详解

《Python异步编程中asyncio.gather的并发控制详解》在Python异步编程生态中,asyncio.gather是并发任务调度的核心工具,本文将通过实际场景和代码示例,展示如何结合信号量... 目录一、asyncio.gather的原始行为解析二、信号量控制法:给并发装上"节流阀"三、进阶控制