DataHoarder
e1d0e27c29
All checks were successful
continuous-integration/drone/push Build is passing
170 lines
3.3 KiB
Go
170 lines
3.3 KiB
Go
package content
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/binary"
|
|
"fmt"
|
|
"git.gammaspectra.live/S.O.N.G/FinalCommander/utilities"
|
|
"github.com/ipfs/go-cid"
|
|
"github.com/multiformats/go-multihash"
|
|
"time"
|
|
)
|
|
|
|
// HashIdentifier Main identifier
|
|
type HashIdentifier multihash.DecodedMultihash
|
|
|
|
func (i *HashIdentifier) IsKey() bool {
|
|
return i.Code == multihash.SHA2_256
|
|
}
|
|
func (i *HashIdentifier) Encode() []byte {
|
|
b, _ := multihash.Encode(i.Digest, i.Code)
|
|
return b
|
|
}
|
|
func (i *HashIdentifier) CID() cid.Cid {
|
|
return cid.NewCidV1(cid.Raw, i.Hash())
|
|
}
|
|
func (i *HashIdentifier) Hash() multihash.Multihash {
|
|
return i.Encode()
|
|
}
|
|
func (i *HashIdentifier) Equals(o *HashIdentifier) bool {
|
|
return i.Code == o.Code && bytes.Compare(i.Digest, o.Digest) == 0
|
|
}
|
|
|
|
func NewHashIdentifierFromMultihash(mh multihash.Multihash) *HashIdentifier {
|
|
d, err := multihash.Decode(mh)
|
|
if err != nil {
|
|
return nil
|
|
}
|
|
i := HashIdentifier(*d)
|
|
return &i
|
|
}
|
|
|
|
type Entry struct {
|
|
Key HashIdentifier
|
|
Version uint64
|
|
// CheckTime indicates relative unix time entry was accessed
|
|
AccessTime int64
|
|
// CheckTime indicates next unix time a check shall be made
|
|
CheckTime int64
|
|
InvalidList []int
|
|
}
|
|
|
|
type Alias struct {
|
|
Key HashIdentifier
|
|
Identifier HashIdentifier
|
|
}
|
|
|
|
func (e *Alias) Encode() []byte {
|
|
return e.Identifier.Encode()
|
|
}
|
|
|
|
func DecodeAlias(key HashIdentifier, message []byte) *Alias {
|
|
buffer := bytes.NewBuffer(message)
|
|
read, mh, err := multihash.MHFromBytes(buffer.Bytes())
|
|
if err != nil {
|
|
return nil
|
|
}
|
|
buffer.Next(read)
|
|
|
|
if buffer.Len() != 0 { //Unknown extra data
|
|
return nil
|
|
}
|
|
|
|
return &Alias{
|
|
Key: key,
|
|
Identifier: *NewHashIdentifierFromMultihash(mh),
|
|
}
|
|
}
|
|
|
|
func (e *Entry) Encode() ([]byte, error) {
|
|
if !e.Valid() {
|
|
return nil, fmt.Errorf("invalid Entry")
|
|
}
|
|
|
|
message := &bytes.Buffer{}
|
|
|
|
buf := make([]byte, binary.MaxVarintLen64)
|
|
|
|
n := binary.PutUvarint(buf, e.Version)
|
|
_, _ = message.Write(buf[:n])
|
|
|
|
if e.Version == 0 {
|
|
n := binary.PutVarint(buf, e.AccessTime)
|
|
_, _ = message.Write(buf[:n])
|
|
n = binary.PutVarint(buf, e.CheckTime)
|
|
_, _ = message.Write(buf[:n])
|
|
message.Write(utilities.EncodeIntegerList(e.InvalidList))
|
|
}
|
|
|
|
return message.Bytes(), nil
|
|
}
|
|
|
|
func DecodeEntry(key HashIdentifier, message []byte) *Entry {
|
|
entry := Entry{
|
|
Key: key,
|
|
}
|
|
var err error
|
|
buffer := bytes.NewBuffer(message)
|
|
|
|
entry.Version, err = binary.ReadUvarint(buffer)
|
|
if err != nil {
|
|
return nil
|
|
}
|
|
|
|
if entry.Version == 0 {
|
|
entry.AccessTime, err = binary.ReadVarint(buffer)
|
|
if err != nil {
|
|
return nil
|
|
}
|
|
entry.CheckTime, err = binary.ReadVarint(buffer)
|
|
if err != nil {
|
|
return nil
|
|
}
|
|
entry.InvalidList = utilities.DecodeIntegerList(buffer.Bytes())
|
|
|
|
return &entry
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (e *Entry) UpdateAccessTime(db *Database) {
|
|
now := time.Now().UTC().Unix()
|
|
|
|
diff := e.AccessTime - now
|
|
e.AccessTime = now
|
|
|
|
if diff < 0 {
|
|
diff = -diff
|
|
}
|
|
|
|
if diff > 3600*24 { //Update max every day
|
|
_ = db.SetEntry(e)
|
|
}
|
|
}
|
|
|
|
func (e *Entry) InInvalidList(i int) bool {
|
|
for _, v := range e.InvalidList {
|
|
if i == v {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
func (e *Entry) NeedsCheck() bool {
|
|
return e.CheckTime < time.Now().UTC().Unix()
|
|
}
|
|
|
|
func (e *Entry) Valid() bool {
|
|
return e.Key.IsKey() && e.AccessTime != 0 && e.CheckTime != 0
|
|
}
|
|
|
|
func (e *Entry) Multihash() multihash.Multihash {
|
|
return e.Key.Hash()
|
|
}
|
|
|
|
func (e *Entry) CID() cid.Cid {
|
|
return e.Key.CID()
|
|
}
|