github.com/Cloud-Foundations/Dominator@v0.3.4/lib/objectserver/filesystem/api.go (about) 1 package filesystem 2 3 import ( 4 "flag" 5 "io" 6 "sync" 7 "time" 8 9 "github.com/Cloud-Foundations/Dominator/lib/flagutil" 10 "github.com/Cloud-Foundations/Dominator/lib/hash" 11 "github.com/Cloud-Foundations/Dominator/lib/lockwatcher" 12 "github.com/Cloud-Foundations/Dominator/lib/log" 13 "github.com/Cloud-Foundations/Dominator/lib/log/debuglogger" 14 "github.com/Cloud-Foundations/Dominator/lib/objectserver" 15 ) 16 17 var ( 18 objectServerCleanupStartPercent = flag.Int( 19 "objectServerCleanupStartPercent", 95, "") 20 objectServerCleanupStartSize flagutil.Size 21 objectServerCleanupStopPercent = flag.Int("objectServerCleanupStopPercent", 22 90, "") 23 objectServerCleanupStopSize flagutil.Size 24 25 // Interface check. 26 _ objectserver.FullObjectServer = (*ObjectServer)(nil) 27 ) 28 29 func init() { 30 flag.Var(&objectServerCleanupStartSize, "objectServerCleanupStartSize", "") 31 flag.Var(&objectServerCleanupStopSize, "objectServerCleanupStopSize", "") 32 } 33 34 type objectType struct { 35 hash hash.Hash 36 newerUnreferenced *objectType 37 olderUnreferenced *objectType 38 refcount uint64 39 size uint64 40 } 41 42 type Config struct { 43 BaseDirectory string 44 LockCheckInterval time.Duration 45 LockLogTimeout time.Duration 46 } 47 48 type ObjectServer struct { 49 addCallback objectserver.AddCallback 50 Config 51 gc objectserver.GarbageCollector 52 lockWatcher *lockwatcher.LockWatcher 53 Params 54 rwLock sync.RWMutex // Protect the following fields. 55 duplicatedBytes uint64 // Sum of refcount*size for all objects. 56 lastGarbageCollection time.Time 57 lastMutationTime time.Time 58 objects map[hash.Hash]*objectType // Only set if object known. 59 newestUnreferenced *objectType 60 numDuplicated uint64 // Sum of refcount for all objects. 61 numReferenced uint64 62 numUnreferenced uint64 63 oldestUnreferenced *objectType 64 referencedBytes uint64 65 totalBytes uint64 66 unreferencedBytes uint64 67 } 68 69 type Params struct { 70 Logger log.DebugLogger 71 } 72 73 func NewObjectServer(baseDir string, logger log.Logger) ( 74 *ObjectServer, error) { 75 return newObjectServer( 76 Config{BaseDirectory: baseDir}, 77 Params{Logger: debuglogger.Upgrade(logger)}, 78 ) 79 } 80 81 func NewObjectServerWithConfigAndParams(config Config, params Params) ( 82 *ObjectServer, error) { 83 return newObjectServer(config, params) 84 } 85 86 // AddObject will add an object. Object data are read from reader (length bytes 87 // are read). The object hash is computed and compared with expectedHash if not 88 // nil. The following are returned: 89 // 90 // computed hash value 91 // a boolean which is true if the object is new 92 // an error or nil if no error. 93 func (objSrv *ObjectServer) AddObject(reader io.Reader, length uint64, 94 expectedHash *hash.Hash) (hash.Hash, bool, error) { 95 return objSrv.addObject(reader, length, expectedHash) 96 } 97 98 // AdjustRefcounts will increment or decrement the refcounts for each object 99 // yielded by the specified objects iterator. If there are missing objects or 100 // the iterator returns an error, the adjustments are reverted and an error is 101 // returned. 102 func (objSrv *ObjectServer) AdjustRefcounts(increment bool, 103 iterator objectserver.ObjectsIterator) error { 104 return objSrv.adjustRefcounts(increment, iterator) 105 } 106 107 func (objSrv *ObjectServer) CheckObjects(hashes []hash.Hash) ([]uint64, error) { 108 return objSrv.checkObjects(hashes) 109 } 110 111 // CommitObject will commit (add) a previously stashed object. 112 func (objSrv *ObjectServer) CommitObject(hashVal hash.Hash) error { 113 return objSrv.commitObject(hashVal) 114 } 115 116 func (objSrv *ObjectServer) DeleteObject(hashVal hash.Hash) error { 117 return objSrv.deleteObject(hashVal, false) 118 } 119 120 func (objSrv *ObjectServer) DeleteStashedObject(hashVal hash.Hash) error { 121 return objSrv.deleteStashedObject(hashVal) 122 } 123 124 // DeleteUnreferenced will delete some or all unreferenced objects. 125 // The oldest unreferenced objects are deleted first, until both the percentage 126 // and bytes thresholds are satisfied. The number of bytes and objects deleted 127 // are returned. 128 func (objSrv *ObjectServer) DeleteUnreferenced(percentage uint8, 129 bytes uint64) (uint64, uint64, error) { 130 return objSrv.deleteUnreferenced(percentage, bytes) 131 } 132 133 func (objSrv *ObjectServer) ListUnreferenced() map[hash.Hash]uint64 { 134 return objSrv.listUnreferenced() 135 } 136 137 func (objSrv *ObjectServer) SetAddCallback(callback objectserver.AddCallback) { 138 objSrv.addCallback = callback 139 } 140 141 // SetGarbageCollector is deprecated. 142 func (objSrv *ObjectServer) SetGarbageCollector( 143 gc objectserver.GarbageCollector) { 144 objSrv.gc = gc 145 } 146 147 func (objSrv *ObjectServer) GetObject(hashVal hash.Hash) ( 148 uint64, io.ReadCloser, error) { 149 return objectserver.GetObject(objSrv, hashVal) 150 } 151 152 func (objSrv *ObjectServer) GetObjects(hashes []hash.Hash) ( 153 objectserver.ObjectsReader, error) { 154 return objSrv.getObjects(hashes) 155 } 156 157 func (objSrv *ObjectServer) LastMutationTime() time.Time { 158 objSrv.rwLock.RLock() 159 defer objSrv.rwLock.RUnlock() 160 return objSrv.lastMutationTime 161 } 162 163 func (objSrv *ObjectServer) ListObjectSizes() map[hash.Hash]uint64 { 164 return objSrv.listObjectSizes() 165 } 166 167 func (objSrv *ObjectServer) ListObjects() []hash.Hash { 168 return objSrv.listObjects() 169 } 170 171 func (objSrv *ObjectServer) NumObjects() uint64 { 172 objSrv.rwLock.RLock() 173 defer objSrv.rwLock.RUnlock() 174 return uint64(len(objSrv.objects)) 175 } 176 177 // StashOrVerifyObject will stash an object if it is new or it will verify if it 178 // already exists. Object data are read from reader (length bytes are read). The 179 // object hash is computed and compared with expectedHash if not nil. 180 // The following are returned: 181 // 182 // computed hash value 183 // the object data if the object is new, otherwise nil 184 // an error or nil if no error. 185 func (objSrv *ObjectServer) StashOrVerifyObject(reader io.Reader, 186 length uint64, expectedHash *hash.Hash) (hash.Hash, []byte, error) { 187 return objSrv.stashOrVerifyObject(reader, length, expectedHash) 188 } 189 190 func (objSrv *ObjectServer) WriteHtml(writer io.Writer) { 191 objSrv.writeHtml(writer) 192 } 193 194 type ObjectsReader struct { 195 objectServer *ObjectServer 196 hashes []hash.Hash 197 nextIndex int64 198 sizes []uint64 199 } 200 201 func (or *ObjectsReader) Close() error { 202 return nil 203 } 204 205 func (or *ObjectsReader) NextObject() (uint64, io.ReadCloser, error) { 206 return or.nextObject() 207 } 208 209 func (or *ObjectsReader) ObjectSizes() []uint64 { 210 return or.sizes 211 }