Skip to content

Commit

Permalink
Fix: multi reverse links by chunks
Browse files Browse the repository at this point in the history
  • Loading branch information
stelzo committed Nov 21, 2022
1 parent 145719a commit 08f2681
Show file tree
Hide file tree
Showing 2 changed files with 119 additions and 26 deletions.
83 changes: 57 additions & 26 deletions ankabuffer.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,13 @@ type Chunk struct {
}

type File struct {
Name string `json:"name"`
Size int64 `json:"size"`
Hash string `json:"hash"`
Chunks []Chunk `json:"chunks"`
Executable bool `json:"executable"`
Symlink string `json:",omitempty"`
ReverseBundle *Bundle `json:"reverse_bundle"` // bundle that contains this file
Name string `json:"name"`
Size int64 `json:"size"`
Hash string `json:"hash"`
Chunks []Chunk `json:"chunks"`
Executable bool `json:"executable"`
Symlink string `json:",omitempty"`
ReverseBundles []Bundle `json:"reverse_bundles"` // bundle that contains this file
}

type Bundle struct {
Expand Down Expand Up @@ -56,14 +56,9 @@ func ParseManifest(data []byte) *Manifest {
manifest := Manifest{}
manifest.Fragments = make(map[string]Fragment)

bundleLookup := make(map[string]Bundle)
for i := 0; i < flatbManifest.FragmentsLength(); i++ {
fragment := AnkamaGames.Fragment{}
flatbManifest.Fragments(&fragment, i)

fragmentJson := Fragment{}
fragmentJson.Files = make(map[string]File)
fragmentJson.Name = string(fragment.Name())
fragmentJson.Bundles = make([]Bundle, fragment.BundlesLength())
for j := 0; j < fragment.BundlesLength(); j++ {
bundle := AnkamaGames.Bundle{}
fragment.Bundles(&bundle, j)
Expand All @@ -79,7 +74,22 @@ func ParseManifest(data []byte) *Manifest {
chunkJson.Size = chunk.Size()
bundleJson.Chunks[k] = chunkJson
}
fragmentJson.Bundles[j] = bundleJson
bundleLookup[bundleJson.Hash] = bundleJson
}
}

for i := 0; i < flatbManifest.FragmentsLength(); i++ {
fragment := AnkamaGames.Fragment{}
flatbManifest.Fragments(&fragment, i)

fragmentJson := Fragment{}
fragmentJson.Files = make(map[string]File)
fragmentJson.Name = string(fragment.Name())
fragmentJson.Bundles = make([]Bundle, fragment.BundlesLength())
for j := 0; j < fragment.BundlesLength(); j++ {
bundle := AnkamaGames.Bundle{}
fragment.Bundles(&bundle, j)
fragmentJson.Bundles[j] = bundleLookup[getHash(&bundle)]
}

for j := 0; j < fragment.FilesLength(); j++ {
Expand All @@ -103,15 +113,32 @@ func ParseManifest(data []byte) *Manifest {
if file.Symlink() != nil {
fileJson.Symlink = string(file.Symlink())
}
fileJson.ReverseBundle = nil
bundles := NewSet[string]()
for _, bundle := range fragmentJson.Bundles {
for _, chunk := range bundle.Chunks {
if chunk.Hash == fileJson.Hash {
fileJson.ReverseBundle = &bundle
break
if len(fileJson.Chunks) == 0 {
if chunk.Hash == fileJson.Hash {
fileJson.ReverseBundles = []Bundle{bundle}
break
}
} else {
for _, fileChunk := range fileJson.Chunks {
if chunk.Hash == fileChunk.Hash {
bundles.Add(bundle.Hash)
}
}
}
}
}
fileJson.ReverseBundles = make([]Bundle, bundles.Size())
i := 0
for _, hash := range bundles.Slice() {
fileJson.ReverseBundles[i] = bundleLookup[hash]
i++
}
if len(fileJson.ReverseBundles) == 0 {
fileJson.ReverseBundles = nil
}
fragmentJson.Files[fileJson.Name] = fileJson
}
manifest.Fragments[fragmentJson.Name] = fragmentJson
Expand All @@ -120,17 +147,21 @@ func ParseManifest(data []byte) *Manifest {
}

func GetNeededBundles(files []File) []Bundle {
bundles := make(map[string]Bundle)
bundles := NewSet[string]()
bundleLookup := make(map[string]Bundle)
for _, file := range files {
if file.ReverseBundle != nil {
bundles[file.ReverseBundle.Hash] = *file.ReverseBundle
if file.ReverseBundles != nil {
for _, bundle := range file.ReverseBundles {
bundles.Add(bundle.Hash)
bundleLookup[bundle.Hash] = bundle
}
}
}
result := make([]Bundle, len(bundles))
res := make([]Bundle, bundles.Size())
i := 0
for _, bundle := range bundles {
result[i] = bundle
for _, hash := range bundles.Slice() {
res[i] = bundleLookup[hash]
i++
}
return result
}
return res
}
62 changes: 62 additions & 0 deletions set.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package ankabuffer

// based on string only https://gist.github.com/bgadrian/cb8b9344d9c66571ef331a14eb7a2e80
// rewritten to be generic

type Set[T comparable] struct {
list map[T]struct{} //empty structs occupy 0 memory
}

func (s *Set[T]) Has(v T) bool {
_, ok := s.list[v]
return ok
}

func (s *Set[T]) Add(v T) {
s.list[v] = struct{}{}
}

func (s *Set[T]) Remove(v T) {
delete(s.list, v)
}

func (s *Set[T]) Clear() {
s.list = make(map[T]struct{})
}

func (s *Set[T]) Size() int {
return len(s.list)
}

func NewSet[T comparable]() *Set[T] {
s := &Set[T]{}
s.list = make(map[T]struct{})
return s
}

func (s *Set[T]) Slice() []T {
var res []T
for v := range s.list {
res = append(res, v)
}
return res
}

func (s *Set[T]) AddMulti(list ...T) {
for _, v := range list {
s.Add(v)
}
}

// fp

func Map[T, U any](data []T, f func(T) U) []U {

res := make([]U, 0, len(data))

for _, e := range data {
res = append(res, f(e))
}

return res
}

0 comments on commit 08f2681

Please sign in to comment.