mirror of
https://github.com/vee1e/gittuf.git
synced 2026-09-03 03:07:10 +00:00
This commit adds support for persistent cache searching as well as explicit populating. Signed-off-by: Aditya Sirish <aditya@saky.in>
129 lines
4.5 KiB
Go
129 lines
4.5 KiB
Go
// Copyright The gittuf Authors
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
package cache
|
|
|
|
import (
|
|
"fmt"
|
|
"log/slog"
|
|
"slices"
|
|
|
|
"github.com/gittuf/gittuf/internal/gitinterface"
|
|
)
|
|
|
|
func (p *Persistent) GetPolicyEntries() []RSLEntryIndex {
|
|
return p.PolicyEntries
|
|
}
|
|
|
|
func (p *Persistent) HasPolicyEntryNumber(entryNumber uint64) (gitinterface.Hash, bool) {
|
|
if len(p.PolicyEntries) == 0 || entryNumber == 0 {
|
|
return gitinterface.ZeroHash, false
|
|
}
|
|
|
|
index, has := slices.BinarySearchFunc(p.PolicyEntries, RSLEntryIndex{EntryNumber: entryNumber}, binarySearch)
|
|
if !has {
|
|
return gitinterface.ZeroHash, false
|
|
}
|
|
|
|
// Unlike Find... we're actively checking if a policy number has been
|
|
// inserted into the cache before, so we return the ID from that index
|
|
// exactly
|
|
return p.PolicyEntries[index].GetEntryID(), true
|
|
}
|
|
|
|
func (p *Persistent) FindPolicyEntryNumberForEntry(entryNumber uint64) RSLEntryIndex {
|
|
if len(p.PolicyEntries) == 0 {
|
|
return RSLEntryIndex{EntryNumber: 0} // this is a special case
|
|
}
|
|
|
|
slog.Debug(fmt.Sprintf("Finding policy entry in cache before entry %d...", entryNumber))
|
|
|
|
index, has := slices.BinarySearchFunc(p.PolicyEntries, RSLEntryIndex{EntryNumber: entryNumber}, binarySearch)
|
|
if has {
|
|
// The entry number given to us is the first entry which happens
|
|
// to be the start of verification as well
|
|
// This can happen for full verification
|
|
return p.PolicyEntries[index]
|
|
}
|
|
|
|
if !has && index == 0 {
|
|
// this happens when a policy entry doesn't exist before the specified
|
|
// entryNumber
|
|
return RSLEntryIndex{EntryNumber: 0}
|
|
}
|
|
|
|
// When !has, index is point of insertion, but we want the applicable
|
|
// entry which is index-1
|
|
return p.PolicyEntries[index-1]
|
|
}
|
|
|
|
func (p *Persistent) FindPolicyEntriesInRange(firstNumber, lastNumber uint64) ([]RSLEntryIndex, error) {
|
|
if len(p.PolicyEntries) == 0 {
|
|
return nil, ErrNoPersistentCache // TODO: check if custom error makes sense
|
|
}
|
|
|
|
firstIndex, has := slices.BinarySearchFunc(p.PolicyEntries, RSLEntryIndex{EntryNumber: firstNumber}, binarySearch)
|
|
if !has {
|
|
// When !has, index is point of insertion, but we want the applicable
|
|
// entry which is index-1
|
|
firstIndex--
|
|
}
|
|
|
|
lastIndex, has := slices.BinarySearchFunc(p.PolicyEntries, RSLEntryIndex{EntryNumber: lastNumber}, binarySearch)
|
|
if has {
|
|
// When has, lastIndex is an entry we want to return, so we increment
|
|
// lastIndex to ensure the corresponding entry is included in the return
|
|
lastIndex++
|
|
}
|
|
|
|
return p.PolicyEntries[firstIndex:lastIndex], nil
|
|
}
|
|
|
|
func (p *Persistent) InsertPolicyEntryNumber(entryNumber uint64, entryID gitinterface.Hash) {
|
|
if entryNumber == 0 {
|
|
// For now, we don't have a way to track non-numbered entries
|
|
// We likely never want to track non-numbered entries in this
|
|
// cache as this is very dependent on numbering
|
|
return
|
|
}
|
|
|
|
// TODO: check this is for the right ref?
|
|
|
|
slog.Debug(fmt.Sprintf("Inserting policy entry with ID '%s' and number %d into persistent cache...", entryID.String(), entryNumber))
|
|
|
|
if len(p.PolicyEntries) == 0 {
|
|
// No entries yet, just add the current entry
|
|
slog.Debug("No policy entries in cache, adding current entry as sole item...")
|
|
p.PolicyEntries = []RSLEntryIndex{{EntryNumber: entryNumber, EntryID: entryID.String()}}
|
|
return
|
|
}
|
|
|
|
if p.PolicyEntries[len(p.PolicyEntries)-1].GetEntryNumber() < entryNumber {
|
|
// Current entry clearly belongs at the very end
|
|
slog.Debug("Current entry belongs at the end of ordered list of attestations entry, appending...")
|
|
p.PolicyEntries = append(p.PolicyEntries, RSLEntryIndex{EntryNumber: entryNumber, EntryID: entryID.String()})
|
|
return
|
|
}
|
|
|
|
// We don't check the converse where the current entry is less than the
|
|
// first entry because we're inserting as entries are encountered
|
|
// chronologically. Worst case, binary search fallthrough below will still
|
|
// handle it
|
|
|
|
slog.Debug("Searching for insertion point...")
|
|
index, has := slices.BinarySearchFunc(p.PolicyEntries, RSLEntryIndex{EntryNumber: entryNumber}, binarySearch)
|
|
if has {
|
|
// We could assume that if we've seen an entry with a number greater
|
|
// than this, we should have seen this one too, but for now...
|
|
slog.Debug("Entry with same number found, skipping addition of entry...")
|
|
return
|
|
}
|
|
slog.Debug(fmt.Sprintf("Found insertion point %d", index))
|
|
|
|
newSlice := make([]RSLEntryIndex, 0, len(p.PolicyEntries)+1)
|
|
newSlice = append(newSlice, p.PolicyEntries[:index]...)
|
|
newSlice = append(newSlice, RSLEntryIndex{EntryNumber: entryNumber, EntryID: entryID.String()})
|
|
newSlice = append(newSlice, p.PolicyEntries[index:]...)
|
|
|
|
p.PolicyEntries = newSlice
|
|
}
|