swarm: localstore hasser (#19230)
This commit is contained in:
		
							parent
							
								
									d45f8d1880
								
							
						
					
					
						commit
						eb199f1fc2
					
				| @ -123,6 +123,17 @@ func (db *DB) Get(key []byte) (value []byte, err error) { | |||||||
| 	return value, nil | 	return value, nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | // Has wraps LevelDB Has method to increment metrics counter.
 | ||||||
|  | func (db *DB) Has(key []byte) (yes bool, err error) { | ||||||
|  | 	yes, err = db.ldb.Has(key, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		metrics.GetOrRegisterCounter("DB.hasFail", nil).Inc(1) | ||||||
|  | 		return false, err | ||||||
|  | 	} | ||||||
|  | 	metrics.GetOrRegisterCounter("DB.has", nil).Inc(1) | ||||||
|  | 	return yes, nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
| // Delete wraps LevelDB Delete method to increment metrics counter.
 | // Delete wraps LevelDB Delete method to increment metrics counter.
 | ||||||
| func (db *DB) Delete(key []byte) (err error) { | func (db *DB) Delete(key []byte) (err error) { | ||||||
| 	err = db.ldb.Delete(key, nil) | 	err = db.ldb.Delete(key, nil) | ||||||
|  | |||||||
| @ -145,6 +145,17 @@ func (f Index) Get(keyFields Item) (out Item, err error) { | |||||||
| 	return out.Merge(keyFields), nil | 	return out.Merge(keyFields), nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | // Has accepts key fields represented as Item to check
 | ||||||
|  | // if there this Item's encoded key is stored in
 | ||||||
|  | // the index.
 | ||||||
|  | func (f Index) Has(keyFields Item) (bool, error) { | ||||||
|  | 	key, err := f.encodeKeyFunc(keyFields) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return false, err | ||||||
|  | 	} | ||||||
|  | 	return f.db.Has(key) | ||||||
|  | } | ||||||
|  | 
 | ||||||
| // Put accepts Item to encode information from it
 | // Put accepts Item to encode information from it
 | ||||||
| // and save it to the database.
 | // and save it to the database.
 | ||||||
| func (f Index) Put(i Item) (err error) { | func (f Index) Put(i Item) (err error) { | ||||||
|  | |||||||
| @ -49,7 +49,7 @@ var retrievalIndexFuncs = IndexFuncs{ | |||||||
| 	}, | 	}, | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // TestIndex validates put, get and delete functions of the Index implementation.
 | // TestIndex validates put, get, has and delete functions of the Index implementation.
 | ||||||
| func TestIndex(t *testing.T) { | func TestIndex(t *testing.T) { | ||||||
| 	db, cleanupFunc := newTestDB(t) | 	db, cleanupFunc := newTestDB(t) | ||||||
| 	defer cleanupFunc() | 	defer cleanupFunc() | ||||||
| @ -177,6 +177,41 @@ func TestIndex(t *testing.T) { | |||||||
| 		checkItem(t, got, want) | 		checkItem(t, got, want) | ||||||
| 	}) | 	}) | ||||||
| 
 | 
 | ||||||
|  | 	t.Run("has", func(t *testing.T) { | ||||||
|  | 		want := Item{ | ||||||
|  | 			Address:        []byte("has-hash"), | ||||||
|  | 			Data:           []byte("DATA"), | ||||||
|  | 			StoreTimestamp: time.Now().UTC().UnixNano(), | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		dontWant := Item{ | ||||||
|  | 			Address:        []byte("do-not-has-hash"), | ||||||
|  | 			Data:           []byte("DATA"), | ||||||
|  | 			StoreTimestamp: time.Now().UTC().UnixNano(), | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		err := index.Put(want) | ||||||
|  | 		if err != nil { | ||||||
|  | 			t.Fatal(err) | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		has, err := index.Has(want) | ||||||
|  | 		if err != nil { | ||||||
|  | 			t.Fatal(err) | ||||||
|  | 		} | ||||||
|  | 		if !has { | ||||||
|  | 			t.Error("item is not found") | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		has, err = index.Has(dontWant) | ||||||
|  | 		if err != nil { | ||||||
|  | 			t.Fatal(err) | ||||||
|  | 		} | ||||||
|  | 		if has { | ||||||
|  | 			t.Error("unwanted item is found") | ||||||
|  | 		} | ||||||
|  | 	}) | ||||||
|  | 
 | ||||||
| 	t.Run("delete", func(t *testing.T) { | 	t.Run("delete", func(t *testing.T) { | ||||||
| 		want := Item{ | 		want := Item{ | ||||||
| 			Address:        []byte("delete-hash"), | 			Address:        []byte("delete-hash"), | ||||||
|  | |||||||
							
								
								
									
										39
									
								
								swarm/storage/localstore/mode_has.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								swarm/storage/localstore/mode_has.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,39 @@ | |||||||
|  | // Copyright 2019 The go-ethereum Authors
 | ||||||
|  | // This file is part of the go-ethereum library.
 | ||||||
|  | //
 | ||||||
|  | // The go-ethereum library is free software: you can redistribute it and/or modify
 | ||||||
|  | // it under the terms of the GNU Lesser General Public License as published by
 | ||||||
|  | // the Free Software Foundation, either version 3 of the License, or
 | ||||||
|  | // (at your option) any later version.
 | ||||||
|  | //
 | ||||||
|  | // The go-ethereum library is distributed in the hope that it will be useful,
 | ||||||
|  | // but WITHOUT ANY WARRANTY; without even the implied warranty of
 | ||||||
|  | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 | ||||||
|  | // GNU Lesser General Public License for more details.
 | ||||||
|  | //
 | ||||||
|  | // You should have received a copy of the GNU Lesser General Public License
 | ||||||
|  | // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
 | ||||||
|  | 
 | ||||||
|  | package localstore | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"github.com/ethereum/go-ethereum/swarm/chunk" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // Hasser provides Has method to retrieve Chunks
 | ||||||
|  | // from database.
 | ||||||
|  | type Hasser struct { | ||||||
|  | 	db *DB | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // NewHasser returns a new Hasser on database.
 | ||||||
|  | func (db *DB) NewHasser() *Hasser { | ||||||
|  | 	return &Hasser{ | ||||||
|  | 		db: db, | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Has returns true if the chunk is stored in database.
 | ||||||
|  | func (h *Hasser) Has(addr chunk.Address) (bool, error) { | ||||||
|  | 	return h.db.retrievalDataIndex.Has(addressToItem(addr)) | ||||||
|  | } | ||||||
							
								
								
									
										55
									
								
								swarm/storage/localstore/mode_has_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								swarm/storage/localstore/mode_has_test.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,55 @@ | |||||||
|  | // Copyright 2019 The go-ethereum Authors
 | ||||||
|  | // This file is part of the go-ethereum library.
 | ||||||
|  | //
 | ||||||
|  | // The go-ethereum library is free software: you can redistribute it and/or modify
 | ||||||
|  | // it under the terms of the GNU Lesser General Public License as published by
 | ||||||
|  | // the Free Software Foundation, either version 3 of the License, or
 | ||||||
|  | // (at your option) any later version.
 | ||||||
|  | //
 | ||||||
|  | // The go-ethereum library is distributed in the hope that it will be useful,
 | ||||||
|  | // but WITHOUT ANY WARRANTY; without even the implied warranty of
 | ||||||
|  | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 | ||||||
|  | // GNU Lesser General Public License for more details.
 | ||||||
|  | //
 | ||||||
|  | // You should have received a copy of the GNU Lesser General Public License
 | ||||||
|  | // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
 | ||||||
|  | 
 | ||||||
|  | package localstore | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"testing" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // TestHas validates that Hasser is returning true for
 | ||||||
|  | // the stored chunk and false for one that is not stored.
 | ||||||
|  | func TestHas(t *testing.T) { | ||||||
|  | 	db, cleanupFunc := newTestDB(t, nil) | ||||||
|  | 	defer cleanupFunc() | ||||||
|  | 
 | ||||||
|  | 	chunk := generateTestRandomChunk() | ||||||
|  | 
 | ||||||
|  | 	err := db.NewPutter(ModePutUpload).Put(chunk) | ||||||
|  | 	if err != nil { | ||||||
|  | 		t.Fatal(err) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	hasser := db.NewHasser() | ||||||
|  | 
 | ||||||
|  | 	has, err := hasser.Has(chunk.Address()) | ||||||
|  | 	if err != nil { | ||||||
|  | 		t.Fatal(err) | ||||||
|  | 	} | ||||||
|  | 	if !has { | ||||||
|  | 		t.Error("chunk not found") | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	missingChunk := generateTestRandomChunk() | ||||||
|  | 
 | ||||||
|  | 	has, err = hasser.Has(missingChunk.Address()) | ||||||
|  | 	if err != nil { | ||||||
|  | 		t.Fatal(err) | ||||||
|  | 	} | ||||||
|  | 	if has { | ||||||
|  | 		t.Error("unexpected chunk is found") | ||||||
|  | 	} | ||||||
|  | } | ||||||
		Loading…
	
		Reference in New Issue
	
	Block a user