Skip to content

Commit 0972e27

Browse files
authored
Merge pull request #84 from mcarmonaa/improvement/siva-reload-metadata
siva: reload metadata
2 parents 63019a4 + b4407c0 commit 0972e27

File tree

5 files changed

+411
-270
lines changed

5 files changed

+411
-270
lines changed

siva/library.go

+31-45
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"fmt"
66
"io"
77
"io/ioutil"
8+
"os"
89
"path/filepath"
910
"strings"
1011
"sync"
@@ -31,7 +32,7 @@ type Library struct {
3132
locReg *locationRegistry
3233
locMu sync.Mutex
3334
options *LibraryOptions
34-
metadata *LibraryMetadata
35+
metadata *libMetadata
3536
}
3637

3738
// LibraryOptions hold configuration options for the library.
@@ -61,23 +62,20 @@ type LibraryOptions struct {
6162
// Performance enables performance options in read only git repositories
6263
// (ExclusiveAccess and KeepDescriptors).
6364
Performance bool
64-
// DontGenerateID stops the library from generating a library ID if it's
65-
// not provided or already in metadata.
66-
DontGenerateID bool
65+
// MetadataReadOnly doesn't create or modify metadata for the library.
66+
MetadataReadOnly bool
6767
}
6868

6969
var _ borges.Library = (*Library)(nil)
7070

7171
const (
72-
timeout = 20 * time.Second
73-
// txTimeout is the default transaction TransactionTimeout.
72+
timeout = 20 * time.Second
7473
txTimeout = 60 * time.Second
7574
registryCacheSize = 10000
7675
)
7776

78-
// NewLibrary creates a new siva.Library. If id is not provided the library ID
79-
// is read from the existing metadata or generated if not available and the
80-
// option DontGenerateID is not set.
77+
// NewLibrary creates a new siva.Library. When is not in MetadataReadOnly it
78+
// will generate an id if not provided the first time the metadata is created.
8179
func NewLibrary(
8280
id string,
8381
fs billy.Filesystem,
@@ -90,24 +88,23 @@ func NewLibrary(
9088
ops = &(*options)
9189
}
9290

93-
metadata, err := loadLibraryMetadata(fs)
94-
if err != nil {
95-
// TODO: skip metadata if corrupted?
96-
return nil, err
97-
}
91+
var (
92+
metadata *libMetadata
93+
err error
94+
)
9895

99-
if metadata == nil {
100-
metadata = NewLibraryMetadata("", -1)
96+
if ops.MetadataReadOnly {
97+
metadata, err = loadLibraryMetadata(fs)
98+
} else {
99+
metadata, err = loadOrCreateLibraryMetadata(id, fs)
101100
}
102101

103-
if id == "" {
104-
if metadata.ID == "" && !ops.DontGenerateID {
105-
metadata.GenerateID()
106-
}
102+
if err != nil && !os.IsNotExist(err) {
103+
return nil, err
104+
}
107105

106+
if metadata != nil && id == "" {
108107
id = metadata.ID
109-
} else {
110-
metadata.SetID(id)
111108
}
112109

113110
if ops.RegistryCache <= 0 {
@@ -137,21 +134,14 @@ func NewLibrary(
137134
tmp = osfs.New(dir)
138135
}
139136

140-
lib := &Library{
137+
return &Library{
141138
id: borges.LibraryID(id),
142139
fs: fs,
143140
tmp: tmp,
144141
locReg: lr,
145142
options: ops,
146143
metadata: metadata,
147-
}
148-
149-
err = lib.SaveMetadata()
150-
if err != nil {
151-
return nil, err
152-
}
153-
154-
return lib, nil
144+
}, nil
155145
}
156146

157147
// ID implements borges.Library interface.
@@ -349,24 +339,20 @@ func (l *Library) locations(ctx context.Context) ([]borges.Location, error) {
349339
}
350340

351341
// Version returns version stored in metadata or -1 if not defined.
352-
func (l *Library) Version() int {
353-
return l.metadata.Version()
354-
}
355-
356-
// SetVersion sets the current version to the given number.
357-
func (l *Library) SetVersion(n int) {
358-
if l.metadata == nil {
359-
l.metadata = NewLibraryMetadata(string(l.id), -1)
342+
func (l *Library) Version() (int, error) {
343+
if l.metadata != nil {
344+
return l.metadata.version()
360345
}
361346

362-
l.metadata.SetVersion(n)
347+
return -1, nil
363348
}
364349

365-
// SaveMetadata writes the metadata to the library yaml file.
366-
func (l *Library) SaveMetadata() error {
367-
if l.metadata != nil && l.metadata.dirty {
368-
return l.metadata.Save(l.fs)
350+
// SetVersion sets the current version to the given number.
351+
func (l *Library) SetVersion(n int) error {
352+
if l.metadata == nil {
353+
return nil
369354
}
370355

371-
return nil
356+
l.metadata.setVersion(n)
357+
return l.metadata.save()
372358
}

siva/location.go

+44-27
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ type Location struct {
3636
lib *Library
3737
checkpoint *checkpoint
3838
txer *transactioner
39-
metadata *LocationMetadata
39+
metadata *locationMetadata
4040

4141
// references and config cache
4242
refs memory.ReferenceStorage
@@ -58,10 +58,14 @@ func newLocation(
5858
path string,
5959
create bool,
6060
) (*Location, error) {
61-
metadata, err := loadLocationMetadata(lib.fs, locationMetadataPath(path))
62-
if err != nil {
63-
// TODO: skip metadata if corrupted? log a warning?
64-
return nil, err
61+
var metadata *locationMetadata
62+
if lib.metadata != nil {
63+
var err error
64+
metadata, err = loadOrCreateLocationMetadata(lib.fs, string(id))
65+
if err != nil {
66+
// TODO: skip metadata if corrupted? log a warning?
67+
return nil, err
68+
}
6569
}
6670

6771
cp, err := newCheckpoint(lib.fs, path, create)
@@ -104,7 +108,11 @@ func (l *Location) checkAndUpdate() error {
104108
return err
105109
}
106110

107-
version := l.lib.Version()
111+
version, err := l.lib.Version()
112+
if err != nil {
113+
return err
114+
}
115+
108116
if l.fSize == stat.Size() && l.fTime == stat.ModTime() &&
109117
l.version == version && l.checkpoint.Offset() == cp.Offset() {
110118
return nil
@@ -175,9 +183,18 @@ func (l *Location) fs(mode borges.Mode, cp *checkpoint) (sivafs.SivaFS, error) {
175183
return nil, borges.ErrLocationNotExists.New(string(l.id))
176184
}
177185

178-
if l.metadata != nil {
179-
version := l.lib.Version()
180-
if o := l.metadata.Offset(version); o > 0 {
186+
if l.lib.metadata != nil {
187+
version, err := l.lib.Version()
188+
if err != nil {
189+
return nil, err
190+
}
191+
192+
o, err := l.metadata.offset(version)
193+
if err != nil {
194+
return nil, err
195+
}
196+
197+
if o > 0 {
181198
offset = o
182199
}
183200
}
@@ -561,40 +578,40 @@ func (l *Location) repository(
561578
return newRepository(id, sto, fs, mode, l.lib.options.Transactional, l)
562579
}
563580

564-
func (l *Location) createMetadata() {
565-
if l.metadata == nil {
566-
l.metadata = NewLocationMetadata(make(map[int]Version))
567-
}
568-
}
569-
570581
// LastVersion returns the last defined version number in metadata or -1 if
571582
// there are not versions.
572583
func (l *Location) LastVersion() int {
573-
return l.metadata.Last()
584+
return l.metadata.last()
574585
}
575586

576-
// Version returns an specific version. Second return value is false if the
577-
// version does not exist.
578-
func (l *Location) Version(v int) (Version, bool) {
579-
return l.metadata.Version(v)
587+
// Version returns an specific version. If the given version does not exist
588+
// an error is returned.
589+
func (l *Location) Version(v int) (*Version, error) {
590+
if l.lib.metadata != nil {
591+
return l.metadata.version(v)
592+
}
593+
594+
return nil, errLocVersionNotExists.New()
580595
}
581596

582597
// SetVersion adds or changes a version to the location.
583-
func (l *Location) SetVersion(n int, v Version) {
584-
l.createMetadata()
585-
l.metadata.SetVersion(n, v)
598+
func (l *Location) SetVersion(n int, v *Version) {
599+
if l.lib.metadata != nil {
600+
l.metadata.setVersion(n, v)
601+
}
586602
}
587603

588604
// DeleteVersion removes the given version number.
589605
func (l *Location) DeleteVersion(n int) {
590-
l.createMetadata()
591-
l.metadata.DeleteVersion(n)
606+
if l.lib.metadata != nil {
607+
l.metadata.deleteVersion(n)
608+
}
592609
}
593610

594611
// SaveMetadata writes the location metadata to disk.
595612
func (l *Location) SaveMetadata() error {
596-
if l.metadata != nil && l.metadata.Dirty() {
597-
return l.metadata.Save(l.lib.fs, l.path)
613+
if l.metadata != nil {
614+
return l.metadata.save()
598615
}
599616

600617
return nil

0 commit comments

Comments
 (0)