rdnf-0.2

文章介绍了RDNF0.2的设计思路,它利用IndraDB图数据库进行存储,基于RocksDB的KV引擎。依赖解析采用SAT算法,包括require和provide的语义,以及处理冲突和过时包的规则。系统有三层优先级的软件仓库,并讨论了优化缓存和SAT求解器的必要性,提出了对现有RocksDB的不满意并提及Badger作为可能的替代选项。
摘要由CSDN通过智能技术生成

rdnf 0.2 思路

indradb

indradb图数据库是基于kv存储引擎,主要是基于rocksdb。基本元素主要有三:Edge、Vertex、Property(包含edge_property、vertex_property)。

原理如下

  • VertexManager

    • key:vertex.id
    • value:vertex.identifier
  • EdgeRangeManager

    • key:[edge.outbound_id,edge.identifier,edge.inbound_id]
    • value:null

    因为key是排序过的,故可通过迭代的方式查找对应 inbound_id的集合,即vertex.id集合。

    同理可得ReversedEdgeRangeManager

    • key[edge.inbound_id,edge.identifier,edge.outbound_id]
    • value:null
  • VertexPropertyManager

    • key:[vertex.id,identifier]
    • value:json
  • EdgePropertyManager

    • key:[edge.outbound_id,edge.identifier,edge.inbound_id,identifier]
    • value:json
  • VertexPropertyManager

    • key:[identifier,json,vertex_id]
    • value:null

    通过迭代遍历排序过的key,得到对应的vertex_id,或得到对应的json和vertex_id

  • EdgePropertyManager

    • key:[identifier,json,edge.outbound_id,edge.identifier,edge.inbound]
    • value:null

    同上

图数据库建模

请添加图片描述

最初的方案设计是name、arch单独作为一个(identifer,value),但是这会造成大量kv键值对,数据库的写入压力非常大。故而软件包的元数据信息包装成为pkgdetail和formatdetail。同样的,将requires由类似与provides的边关系,转变为property。

每个package provides多个entry,每个package requires多个entry。

Repo

按照优先级有三层repo

  • cmd_repo:有这样的场景: dnf install file:///…x86_64.rpm https://…i686.rpm 将url的rpm下载到本地,将这些本地的rpm文件,解析其头文件,将元数据导入到cmd_repo,由于是用户指定的rpm文件,故而优先级最高。
  • installed_repo: 操作系统将已经安装后的rpm包的元数据信息,导入到rpmdb.sqlite文件中,路径一般为 /var/lib/rpm/rpmdb.sqlite ,由于操作的不便,目前采用的是将rpmdb.sqlite的数据导入到installed_repo,根据rpmdb.sqlite的sqlite_sequence 和installed_seq中的记载来判断是否需要同步。在使用rdnf的同时,对rpmdb.sqlite文件加锁。
  • repos: 将多个远程的软件包仓库的元数据xml文件解析成Vec<Repo>

SAT依赖解析

每个package requires多个Entry

对每个requier_entry:<rpm:entry name=“0ad-data” flags=“EQ” epoch=“0” ver=“0.0.26”/>,将其解析为SolveItem

pub(self) struct SolveItem {
    entry_name: Arc<String>,
    ver: Version,
    flag: Option<String>,
}
其中,pub struct Version {
    pub epoch: Option<u32>,
    pub version: Option<String>,
    pub release: Option<String>,
}

依次从cmd_repo、installed_repo、repos查找能够提供满足需要的Entry的Package ( P i , i = 1 , 2 , . . m P_i,i=1,2,..m Pi,i=1,2,..m)。

  • provide 语义

( P 1 ∨ P 2 ∨ P 3 . . ∨ P m ∨ ¬ E n t r y 1 ) 当 E n t r y 1 为 T r u e ,则 P 1 . . P m 中至少有一个必须为 T r u e (P_1 \vee P_2 \vee P_3..\vee P_m \vee \neg Entry_1)\\ 当 Entry_1 为True,则P_1..P_m中至少有一个必须为True (P1P2P3..Pm¬Entry1)Entry1True,则P1..Pm中至少有一个必须为True

  • require 语义:对于Package的reuqire Entry

( E n t r y i ∨ ¬ P a c k a g e ) 当 P a c k a g e 为 T r u e , 则 E n t r y i 必为 T r u e 由公式 ( 1 ) 可得,提供 E n t r y i 的多个 p a c k a g e 至少有一个为 T r u e . (Entry_i \vee \neg Package)\\ 当Package为True,则Entry_i必为True \\ 由公式(1)可得,提供Entry_i的多个package至少有一个为True. (Entryi¬Package)PackageTrue,Entryi必为True由公式(1)可得,提供Entryi的多个package至少有一个为True.

  • conflict : P a c k a g e A Package_A PackageA对于conflict entry,满足entry条件的多个package ( P i , i = 1 , 2 , . . m P_i,i=1,2,..m Pi,i=1,2,..m)

( ¬ P A ∨ ¬ P i ) ∧ ( ¬ P A ∨ ¬ P 2 ) . . . ∧ ( ¬ P A ∨ ¬ P m ) (\neg P_A \vee \neg P_i) \wedge (\neg P_A \vee \neg P_2) ...\wedge (\neg P_A \vee \neg P_m) (¬PA¬Pi)(¬PA¬P2)...(¬PA¬Pm)

  • obsolete同上。

当Require为Term时,即类似于**((feh and xrandr) if Xserver)**的
( ¬ P a c k a g e ∨ T e r m o u t ) ∧ ( ¬ T e r m o u t ∨ ¬ E n t r y X s e r v e r ∨ T e r m i n ) ∧ ( ¬ T e r m i n ∨ E n t r y f e h ) ∧ ( ¬ T e r m i n ∨ E n t r y x r a n d r ) (\neg Package \vee Term_{out})\wedge (\neg Term_{out} \vee \neg Entry_{Xserver}\vee Term_{in}) \\ \wedge (\neg Term_{in} \vee Entry_{feh}) \wedge (\neg Term_{in} \vee Entry_{xrandr}) (¬PackageTermout)(¬Termout¬EntryXserverTermin)(¬TerminEntryfeh)(¬TerminEntryxrandr)

  • 对于or 语义 (a or b or c),a、b、c既可以是Entry_id也可以是Term_id

( A ∨ B ∨ C ∨ ¬ T e r m ) (A \vee B \vee C \vee \neg Term) (ABC¬Term)

  • 对于and 语义(a and b and c)
    ( ¬ T e r m ∨ A ) ∧ ( ¬ T e r m ∨ B ) ∧ ( ¬ T e r m ∨ c ) (\neg Term \vee A)\wedge (\neg Term \vee B) \wedge (\neg Term \vee c) (¬TermA)(¬TermB)(¬Termc)

  • 对于 if 语义 (m if p)
    T e r m → ( P → M ) ( ¬ T e r m ∨ ¬ P ∨ M ) Term \rightarrow (P \rightarrow M) \\ (\neg Term \vee \neg P \vee M) Term(PM)(¬Term¬PM)

  • 对于 if else 语义 (m if p else n)
    T e r m → ( P → M ) T e r m → ( ¬ P → N ) ( ¬ T e r m ∨ ¬ P ∨ M ) ∧ ( ¬ T e r m ∨ P ∨ N ) Term \rightarrow (P \rightarrow M) \\ Term \rightarrow (\neg P \rightarrow N) \\ (\neg Term \vee \neg P \vee M) \wedge (\neg Term \vee P \vee N) Term(PM)Term(¬PN)(¬Term¬PM)(¬TermPN)

​ unless unless else 同上。

  • 对于with 语义,通过满足多个Entry的多个pkg 的交集,without 即减集

下一步目标

  • makecache 构建缓存后,再次调用 rdnf其他命令,可能会出现报错(某个文件不存在)(Bug)
  • 目前使用sat算法求解器是 varisat,该求解器的策略是,用最少数量为True的变量满足所有的Clause,不符合要求。在or 语义和provide语义中,package应该是存在优先级的,即先按arch(x86_64一定是优于i686)、然后是按repo排序(cmd_repo > install_repo > repos,其中repos是按配置文件中的priority排序)。需要对sat求解算法改进。
  • 在本地建立缓存,使用的rocksdb效果不是很理想,kv分离的lsm树存储引擎比较理想,例如badger。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值