📇 CPE Index
index 模块提供 CPEIndex——对一组 CPE 的并发安全内存索引,支持按厂商、产品、part 或 PURL 进行 O(1) 平均复杂度的查询。专为批处理扫描场景设计:同一组 CPE 会被反复查询。sync.RWMutex 保护所有 map,因此读写可并发进行。
类型:CPEIndex
type CPEIndex struct {
mu sync.RWMutex // 保护所有 map 字段
byVendor map[string][]*CPE // 按厂商名索引
byProduct map[string][]*CPE // 按产品名索引
byPart map[string][]*CPE // 按 part(a/h/o)索引
byPURL map[string]*CPE // 按 PURL 字符串索引
all []*CPE // 索引中所有 CPE
}所有字段均为非导出。厂商或产品为空或等于 ValueANY 的 CPE 不会被加入对应索引(但仍保留在 all 中);PURL 映射需通过 IndexPURL 显式添加。
🆕 NewCPEIndex
func NewCPEIndex(cpes []*CPE) *CPEIndex从 CPE 切片创建新索引,构建厂商、产品、part 索引。cpes 中的 nil 条目会被跳过。byPURL map 初始为空(使用 IndexPURL 填充)。
| 参数 | 类型 | 说明 |
|---|---|---|
cpes | []*CPE | 要索引的初始 CPE |
| 返回值 | 类型 | 说明 |
|---|---|---|
| #1 | *CPEIndex | 已填充的新索引 |
cpes, _ := cpeskills.NewFileStorage("/tmp/cpe-data", false).SearchCPE(nil, nil)
idx := cpeskills.NewCPEIndex(cpes)
fmt.Println(idx.Size())🔍 Lookup
func (idx *CPEIndex) Lookup(criteria *CPE) []*CPE使用最快的可用索引返回匹配 criteria 的 CPE。优先顺序:厂商(再按产品进一步过滤)、产品、part。若 criteria 为 nil 或无可用字段,返回所有 CPE 的副本。并发读取安全。
| 参数 | 类型 | 说明 |
|---|---|---|
| 接收者 | *CPEIndex | 索引 |
criteria | *CPE | 匹配条件;nil 返回全部 |
| 返回值 | 类型 | 说明 |
|---|---|---|
| #1 | []*CPE | 匹配的 CPE(或全部的副本) |
results := idx.Lookup(&cpeskills.CPE{
Vendor: cpeskills.Vendor("apache"),
ProductName: cpeskills.Product("log4j"),
})🔍 LookupByPURL
func (idx *CPEIndex) LookupByPURL(purl *PackageURL) *CPE返回映射到 purl 的 CPE,无则返回 nil。并发读取安全。
| 参数 | 类型 | 说明 |
|---|---|---|
| 接收者 | *CPEIndex | 索引 |
purl | *PackageURL | 要查询的 Package URL |
| 返回值 | 类型 | 说明 |
|---|---|---|
| #1 | *CPE | 映射的 CPE,或 nil |
cpe := idx.LookupByPURL(purl)➕ IndexPURL
func (idx *CPEIndex) IndexPURL(purl *PackageURL, cpe *CPE)将 purl(按其字符串形式)映射到 cpe,覆盖任何已有映射。任一参数为 nil 时空操作。并发写入安全。
| 参数 | 类型 | 说明 |
|---|---|---|
| 接收者 | *CPEIndex | 索引 |
purl | *PackageURL | Package URL |
cpe | *CPE | 要关联的 CPE |
| 返回值 | 类型 | 说明 |
|---|---|---|
| (无) |
idx.IndexPURL(purl, cpe)📏 Size
func (idx *CPEIndex) Size() int返回索引中 CPE 的数量(all 的长度)。
| 参数 | 类型 | 说明 |
|---|---|---|
| 接收者 | *CPEIndex | 索引 |
| 返回值 | 类型 | 说明 |
|---|---|---|
| #1 | int | 已索引的 CPE 数 |
fmt.Println(idx.Size())📋 All
func (idx *CPEIndex) All() []*CPE返回索引中所有 CPE 的副本。返回的切片可安全修改,不影响索引。
| 参数 | 类型 | 说明 |
|---|---|---|
| 接收者 | *CPEIndex | 索引 |
| 返回值 | 类型 | 说明 |
|---|---|---|
| #1 | []*CPE | 所有已索引 CPE 的副本 |
all := idx.All()🏷️ GetByVendor
func (idx *CPEIndex) GetByVendor(vendor string) []*CPE返回 vendor 下索引的所有 CPE(直接返回底层切片,非副本)。
| 参数 | 类型 | 说明 |
|---|---|---|
| 接收者 | *CPEIndex | 索引 |
vendor | string | 厂商名 |
| 返回值 | 类型 | 说明 |
|---|---|---|
| #1 | []*CPE | 该厂商的 CPE(无则 nil) |
cpes := idx.GetByVendor("apache")🏷️ GetByProduct
func (idx *CPEIndex) GetByProduct(product string) []*CPE返回 product 下索引的所有 CPE(直接返回底层切片,非副本)。
| 参数 | 类型 | 说明 |
|---|---|---|
| 接收者 | *CPEIndex | 索引 |
product | string | 产品名 |
| 返回值 | 类型 | 说明 |
|---|---|---|
| #1 | []*CPE | 该产品的 CPE(无则 nil) |
cpes := idx.GetByProduct("log4j")🏷️ GetByPart
func (idx *CPEIndex) GetByPart(part string) []*CPE返回 part 下索引的所有 CPE(part 短名:a、h 或 o)。
| 参数 | 类型 | 说明 |
|---|---|---|
| 接收者 | *CPEIndex | 索引 |
part | string | part 短名 |
| 返回值 | 类型 | 说明 |
|---|---|---|
| #1 | []*CPE | 该 part 的 CPE(无则 nil) |
apps := idx.GetByPart("a")📊 VendorCount
func (idx *CPEIndex) VendorCount() int返回索引中不同厂商的数量。
| 参数 | 类型 | 说明 |
|---|---|---|
| 接收者 | *CPEIndex | 索引 |
| 返回值 | 类型 | 说明 |
|---|---|---|
| #1 | int | 不同厂商数 |
fmt.Println(idx.VendorCount())📊 ProductCount
func (idx *CPEIndex) ProductCount() int返回索引中不同产品的数量。
| 参数 | 类型 | 说明 |
|---|---|---|
| 接收者 | *CPEIndex | 索引 |
| 返回值 | 类型 | 说明 |
|---|---|---|
| #1 | int | 不同产品数 |
fmt.Println(idx.ProductCount())➕ Add
func (idx *CPEIndex) Add(cpe *CPE)将 cpe 加入索引:追加到 all 并插入厂商、产品、part 索引(受空/ValueANY 规则约束)。cpe 为 nil 时空操作。并发写入安全。
| 参数 | 类型 | 说明 |
|---|---|---|
| 接收者 | *CPEIndex | 索引 |
cpe | *CPE | 要添加的 CPE |
| 返回值 | 类型 | 说明 |
|---|---|---|
| (无) |
idx.Add(cpe)➖ Remove
func (idx *CPEIndex) Remove(cpeURI string)从 all、厂商、产品、PURL 索引中移除 Cpe23 等于 cpeURI 的 CPE。未找到时空操作。并发写入安全。
| 参数 | 类型 | 说明 |
|---|---|---|
| 接收者 | *CPEIndex | 索引 |
cpeURI | string | 要移除 CPE 的 2.3 URI |
| 返回值 | 类型 | 说明 |
|---|---|---|
| (无) |
idx.Remove("cpe:2.3:a:apache:log4j:2.0:*:*:*:*:*:*:*")🧹 Clear
func (idx *CPEIndex) Clear()清空所有索引项,重置所有 map 并将 all 置为 nil。
| 参数 | 类型 | 说明 |
|---|---|---|
| 接收者 | *CPEIndex | 索引 |
| 返回值 | 类型 | 说明 |
|---|---|---|
| (无) |
idx.Clear()