mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-23 05:06:43 +00:00
implemented Api.Modify
This commit is contained in:
parent
a762134519
commit
3113b1cdc9
2 changed files with 64 additions and 23 deletions
33
bzz/api.go
33
bzz/api.go
|
|
@ -122,6 +122,31 @@ func (self *Api) Put(content, contentType string) (string, error) {
|
||||||
return fmt.Sprintf("%064x", key), nil
|
return fmt.Sprintf("%064x", key), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (self *Api) Modify(rootHash, path, contentHash, contentType string) (newRootHash string, err error) {
|
||||||
|
root := common.Hex2Bytes(rootHash)
|
||||||
|
trie, err := loadManifestTrie(self.dpa, root)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if contentHash != "" {
|
||||||
|
entry := &manifestTrieEntry{
|
||||||
|
Path: path,
|
||||||
|
Hash: contentHash,
|
||||||
|
ContentType: contentType,
|
||||||
|
}
|
||||||
|
trie.addEntry(entry)
|
||||||
|
} else {
|
||||||
|
trie.deleteEntry(path)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = trie.recalcAndStore()
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("%064x", trie.hash), nil
|
||||||
|
}
|
||||||
|
|
||||||
// Download replicates the manifest path structure on the local filesystem
|
// Download replicates the manifest path structure on the local filesystem
|
||||||
// under localpath
|
// under localpath
|
||||||
func (self *Api) Download(bzzpath, localpath string) (string, error) {
|
func (self *Api) Download(bzzpath, localpath string) (string, error) {
|
||||||
|
|
@ -205,7 +230,9 @@ func (self *Api) Upload(lpath string) (string, error) {
|
||||||
dcnt++
|
dcnt++
|
||||||
}
|
}
|
||||||
|
|
||||||
trie := &manifestTrie{}
|
trie := &manifestTrie{
|
||||||
|
dpa: self.dpa,
|
||||||
|
}
|
||||||
for i, entry := range list {
|
for i, entry := range list {
|
||||||
if errors[i] != nil {
|
if errors[i] != nil {
|
||||||
return "", errors[i]
|
return "", errors[i]
|
||||||
|
|
@ -214,7 +241,7 @@ func (self *Api) Upload(lpath string) (string, error) {
|
||||||
trie.addEntry(entry)
|
trie.addEntry(entry)
|
||||||
}
|
}
|
||||||
|
|
||||||
err2 := trie.recalcAndStore(self.dpa)
|
err2 := trie.recalcAndStore()
|
||||||
var hs string
|
var hs string
|
||||||
if err2 == nil {
|
if err2 == nil {
|
||||||
hs = fmt.Sprintf("%064x", trie.hash)
|
hs = fmt.Sprintf("%064x", trie.hash)
|
||||||
|
|
@ -290,7 +317,7 @@ func (self *Api) getPath(uri string) (reader SectionReader, mimeType string, sta
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
entry, _ := trie.getEntry(self.dpa, path)
|
entry, _ := trie.getEntry(path)
|
||||||
if entry != nil {
|
if entry != nil {
|
||||||
key = common.Hex2Bytes(entry.Hash)
|
key = common.Hex2Bytes(entry.Hash)
|
||||||
status = entry.Status
|
status = entry.Status
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@ const (
|
||||||
)
|
)
|
||||||
|
|
||||||
type manifestTrie struct {
|
type manifestTrie struct {
|
||||||
|
dpa *DPA
|
||||||
entries [257]*manifestTrieEntry // indexed by first character of path, entries[256] is the empty path entry
|
entries [257]*manifestTrieEntry // indexed by first character of path, entries[256] is the empty path entry
|
||||||
hash Key // if hash != nil, it is stored
|
hash Key // if hash != nil, it is stored
|
||||||
}
|
}
|
||||||
|
|
@ -31,7 +32,7 @@ type manifestTrieEntry struct {
|
||||||
subtrie *manifestTrie
|
subtrie *manifestTrie
|
||||||
}
|
}
|
||||||
|
|
||||||
func loadManifestTrie(dpa *DPA, hash Key) (trie *manifestTrie, err error) {
|
func loadManifestTrie(dpa *DPA, hash Key) (trie *manifestTrie, err error) { // non-recursive, subtrees are downloaded on-demand
|
||||||
|
|
||||||
dpaLogger.Debugf("Swarm: manifest lookup key: '%064x'.", hash)
|
dpaLogger.Debugf("Swarm: manifest lookup key: '%064x'.", hash)
|
||||||
// retrieve manifest via DPA
|
// retrieve manifest via DPA
|
||||||
|
|
@ -59,7 +60,9 @@ func loadManifestTrie(dpa *DPA, hash Key) (trie *manifestTrie, err error) {
|
||||||
|
|
||||||
dpaLogger.Debugf("Swarm: Manifest %064x has %d entries.", hash, len(man.Entries))
|
dpaLogger.Debugf("Swarm: Manifest %064x has %d entries.", hash, len(man.Entries))
|
||||||
|
|
||||||
trie = &manifestTrie{}
|
trie = &manifestTrie{
|
||||||
|
dpa: dpa,
|
||||||
|
}
|
||||||
for _, entry := range man.Entries {
|
for _, entry := range man.Entries {
|
||||||
trie.addEntry(entry)
|
trie.addEntry(entry)
|
||||||
}
|
}
|
||||||
|
|
@ -87,6 +90,9 @@ func (self *manifestTrie) addEntry(entry *manifestTrieEntry) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (oldentry.ContentType == manifestType) && (cpl == len(oldentry.Path)) {
|
if (oldentry.ContentType == manifestType) && (cpl == len(oldentry.Path)) {
|
||||||
|
if self.loadSubTrie(oldentry) != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
entry.Path = entry.Path[cpl:]
|
entry.Path = entry.Path[cpl:]
|
||||||
oldentry.subtrie.addEntry(entry)
|
oldentry.subtrie.addEntry(entry)
|
||||||
oldentry.Hash = ""
|
oldentry.Hash = ""
|
||||||
|
|
@ -95,7 +101,9 @@ func (self *manifestTrie) addEntry(entry *manifestTrieEntry) {
|
||||||
|
|
||||||
commonPrefix := entry.Path[:cpl]
|
commonPrefix := entry.Path[:cpl]
|
||||||
|
|
||||||
subtrie := &manifestTrie{}
|
subtrie := &manifestTrie{
|
||||||
|
dpa: self.dpa,
|
||||||
|
}
|
||||||
entry.Path = entry.Path[cpl:]
|
entry.Path = entry.Path[cpl:]
|
||||||
oldentry.Path = oldentry.Path[cpl:]
|
oldentry.Path = oldentry.Path[cpl:]
|
||||||
subtrie.addEntry(entry)
|
subtrie.addEntry(entry)
|
||||||
|
|
@ -136,6 +144,9 @@ func (self *manifestTrie) deleteEntry(path string) {
|
||||||
|
|
||||||
epl := len(entry.Path)
|
epl := len(entry.Path)
|
||||||
if (entry.ContentType == manifestType) && (len(path) >= epl) && (path[:epl] == entry.Path) {
|
if (entry.ContentType == manifestType) && (len(path) >= epl) && (path[:epl] == entry.Path) {
|
||||||
|
if self.loadSubTrie(entry) != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
entry.subtrie.deleteEntry(path[epl:])
|
entry.subtrie.deleteEntry(path[epl:])
|
||||||
entry.Hash = ""
|
entry.Hash = ""
|
||||||
// remove subtree if it has less than 2 elements
|
// remove subtree if it has less than 2 elements
|
||||||
|
|
@ -149,7 +160,7 @@ func (self *manifestTrie) deleteEntry(path string) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *manifestTrie) recalcAndStore(dpa *DPA) error {
|
func (self *manifestTrie) recalcAndStore() error {
|
||||||
if self.hash != nil {
|
if self.hash != nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
@ -161,7 +172,7 @@ func (self *manifestTrie) recalcAndStore(dpa *DPA) error {
|
||||||
for _, entry := range self.entries {
|
for _, entry := range self.entries {
|
||||||
if entry != nil {
|
if entry != nil {
|
||||||
if entry.Hash == "" { // TODO: paralellize
|
if entry.Hash == "" { // TODO: paralellize
|
||||||
err := entry.subtrie.recalcAndStore(dpa)
|
err := entry.subtrie.recalcAndStore()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -178,13 +189,22 @@ func (self *manifestTrie) recalcAndStore(dpa *DPA) error {
|
||||||
|
|
||||||
sr := io.NewSectionReader(bytes.NewReader(manifest), 0, int64(len(manifest)))
|
sr := io.NewSectionReader(bytes.NewReader(manifest), 0, int64(len(manifest)))
|
||||||
wg := &sync.WaitGroup{}
|
wg := &sync.WaitGroup{}
|
||||||
key, err2 := dpa.Store(sr, wg)
|
key, err2 := self.dpa.Store(sr, wg)
|
||||||
wg.Wait()
|
wg.Wait()
|
||||||
self.hash = key
|
self.hash = key
|
||||||
return err2
|
return err2
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *manifestTrie) findPrefixOf(dpa *DPA, path string) (entry *manifestTrieEntry, pos int) {
|
func (self *manifestTrie) loadSubTrie(entry *manifestTrieEntry) (err error) {
|
||||||
|
if entry.subtrie == nil {
|
||||||
|
hash := common.Hex2Bytes(entry.Hash)
|
||||||
|
entry.subtrie, err = loadManifestTrie(self.dpa, hash)
|
||||||
|
entry.Hash = "" // might not match, should be recalculated
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self *manifestTrie) findPrefixOf(path string) (entry *manifestTrieEntry, pos int) {
|
||||||
if len(path) == 0 {
|
if len(path) == 0 {
|
||||||
return self.entries[256], 0
|
return self.entries[256], 0
|
||||||
}
|
}
|
||||||
|
|
@ -194,16 +214,10 @@ func (self *manifestTrie) findPrefixOf(dpa *DPA, path string) (entry *manifestTr
|
||||||
epl := len(entry.Path)
|
epl := len(entry.Path)
|
||||||
if (len(path) >= epl) && (path[:epl] == entry.Path) {
|
if (len(path) >= epl) && (path[:epl] == entry.Path) {
|
||||||
if entry.ContentType == manifestType {
|
if entry.ContentType == manifestType {
|
||||||
if entry.subtrie == nil {
|
if self.loadSubTrie(entry) != nil {
|
||||||
hash := common.Hex2Bytes(entry.Hash)
|
|
||||||
var err error
|
|
||||||
entry.subtrie, err = loadManifestTrie(dpa, hash)
|
|
||||||
if err != nil {
|
|
||||||
return nil, 0
|
return nil, 0
|
||||||
}
|
}
|
||||||
entry.Hash = "" // might not match, should be recalculated
|
entry, pos = entry.subtrie.findPrefixOf(path[epl:])
|
||||||
}
|
|
||||||
entry, pos = entry.subtrie.findPrefixOf(dpa, path[epl:])
|
|
||||||
if entry != nil {
|
if entry != nil {
|
||||||
pos += epl
|
pos += epl
|
||||||
}
|
}
|
||||||
|
|
@ -216,8 +230,8 @@ func (self *manifestTrie) findPrefixOf(dpa *DPA, path string) (entry *manifestTr
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *manifestTrie) getEntryNLS(dpa *DPA, path string) (entry *manifestTrieEntry, pos int) {
|
func (self *manifestTrie) getEntryNLS(path string) (entry *manifestTrieEntry, pos int) {
|
||||||
entry, pos = self.findPrefixOf(dpa, path)
|
entry, pos = self.findPrefixOf(path)
|
||||||
if entry != nil {
|
if entry != nil {
|
||||||
for (pos < len(path)) && (path[pos] == '/') {
|
for (pos < len(path)) && (path[pos] == '/') {
|
||||||
pos++
|
pos++
|
||||||
|
|
@ -229,10 +243,10 @@ func (self *manifestTrie) getEntryNLS(dpa *DPA, path string) (entry *manifestTri
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *manifestTrie) getEntry(dpa *DPA, path string) (entry *manifestTrieEntry, pos int) {
|
func (self *manifestTrie) getEntry(path string) (entry *manifestTrieEntry, pos int) {
|
||||||
var slash string
|
var slash string
|
||||||
for {
|
for {
|
||||||
entry, pos = self.getEntryNLS(dpa, slash+path)
|
entry, pos = self.getEntryNLS(slash + path)
|
||||||
if pos < len(slash) {
|
if pos < len(slash) {
|
||||||
dpaLogger.Debugf("Path '%s' on manifest not found.", path)
|
dpaLogger.Debugf("Path '%s' on manifest not found.", path)
|
||||||
return nil, 0
|
return nil, 0
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue