1 // Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
2 // This source code is licensed under both the GPLv2 (found in the
3 // COPYING file in the root directory) and Apache 2.0 License
4 // (found in the LICENSE.Apache file in the root directory).
11 #include "port/port.h"
12 #include "rocksdb/env.h"
13 #include "rocksdb/options.h"
14 #include "util/file_reader_writer.h"
15 #include "utilities/blob_db/blob_log_format.h"
16 #include "utilities/blob_db/blob_log_reader.h"
17 #include "utilities/blob_db/blob_log_writer.h"
25 friend class BlobDBImpl
;
26 friend struct BlobFileComparator
;
27 friend struct BlobFileComparatorTTL
;
31 const BlobDBImpl
* parent_
;
33 // path to blob directory
34 std::string path_to_dir_
;
36 // the id of the file.
37 // the above 2 are created during file creation and never changed
39 uint64_t file_number_
;
45 uint32_t column_family_id_
;
47 // Compression type of blobs in the file
48 CompressionType compression_
;
50 // If true, the keys in this file all has TTL. Otherwise all keys don't
54 // number of blobs in the file
55 std::atomic
<uint64_t> blob_count_
;
58 std::atomic
<uint64_t> file_size_
;
60 BlobLogHeader header_
;
62 // closed_ = true implies the file is no more mutable
63 // no more blobs will be appended and the footer has been written out
64 std::atomic
<bool> closed_
;
66 // has a pass of garbage collection successfully finished on this file
67 // obsolete_ still needs to do iterator/snapshot checks
68 std::atomic
<bool> obsolete_
;
70 // The last sequence number by the time the file marked as obsolete.
71 // Data in this file is visible to a snapshot taken before the sequence.
72 SequenceNumber obsolete_sequence_
;
74 ExpirationRange expiration_range_
;
76 // Sequential/Append writer for blobs
77 std::shared_ptr
<Writer
> log_writer_
;
79 // random access file reader for GET calls
80 std::shared_ptr
<RandomAccessFileReader
> ra_file_reader_
;
82 // This Read-Write mutex is per file specific and protects
83 // all the datastructures
84 mutable port::RWMutex mutex_
;
86 // time when the random access reader was last created.
87 std::atomic
<std::int64_t> last_access_
;
89 // last time file was fsync'd/fdatasyncd
90 std::atomic
<uint64_t> last_fsync_
;
96 SequenceNumber garbage_collection_finish_sequence_
;
101 BlobFile(const BlobDBImpl
* parent
, const std::string
& bdir
, uint64_t fnum
,
106 uint32_t column_family_id() const;
108 void SetColumnFamilyId(uint32_t cf_id
) {
109 column_family_id_
= cf_id
;
112 // Returns log file's absolute pathname.
113 std::string
PathName() const;
115 // Primary identifier for blob file.
116 // once the file is created, this never changes
117 uint64_t BlobFileNumber() const { return file_number_
; }
119 // the following functions are atomic, and don't need
121 uint64_t BlobCount() const {
122 return blob_count_
.load(std::memory_order_acquire
);
125 std::string
DumpState() const;
127 // if the file is not taking any more appends.
128 bool Immutable() const { return closed_
.load(); }
130 // Mark the file as immutable.
131 // REQUIRES: write lock held, or access from single thread (on DB open).
132 void MarkImmutable() { closed_
= true; }
134 // if the file has gone through GC and blobs have been relocated
135 bool Obsolete() const {
136 assert(Immutable() || !obsolete_
.load());
137 return obsolete_
.load();
140 // Mark file as obsolete by garbage collection. The file is not visible to
141 // snapshots with sequence greater or equal to the given sequence.
142 void MarkObsolete(SequenceNumber sequence
);
144 SequenceNumber
GetObsoleteSequence() const {
146 return obsolete_sequence_
;
149 // we will assume this is atomic
150 bool NeedsFsync(bool hard
, uint64_t bytes_per_sync
) const;
154 uint64_t GetFileSize() const {
155 return file_size_
.load(std::memory_order_acquire
);
158 // All Get functions which are not atomic, will need ReadLock on the mutex
160 ExpirationRange
GetExpirationRange() const { return expiration_range_
; }
162 void ExtendExpirationRange(uint64_t expiration
) {
163 expiration_range_
.first
= std::min(expiration_range_
.first
, expiration
);
164 expiration_range_
.second
= std::max(expiration_range_
.second
, expiration
);
167 bool HasTTL() const { return has_ttl_
; }
169 void SetHasTTL(bool has_ttl
) { has_ttl_
= has_ttl
; }
171 CompressionType
compression() const { return compression_
; }
173 void SetCompression(CompressionType c
) {
177 std::shared_ptr
<Writer
> GetWriter() const { return log_writer_
; }
179 // Read blob file header and footer. Return corruption if file header is
180 // malform or incomplete. If footer is malform or incomplete, set
181 // footer_valid_ to false and return Status::OK.
182 Status
ReadMetadata(Env
* env
, const EnvOptions
& env_options
);
184 Status
GetReader(Env
* env
, const EnvOptions
& env_options
,
185 std::shared_ptr
<RandomAccessFileReader
>* reader
,
189 std::shared_ptr
<Reader
> OpenRandomAccessReader(
190 Env
* env
, const DBOptions
& db_options
,
191 const EnvOptions
& env_options
) const;
193 Status
ReadFooter(BlobLogFooter
* footer
);
195 Status
WriteFooterAndCloseLocked();
197 void CloseRandomAccessLocked();
199 // this is used, when you are reading only the footer of a
200 // previously closed file
201 Status
SetFromFooterLocked(const BlobLogFooter
& footer
);
203 void set_expiration_range(const ExpirationRange
& expiration_range
) {
204 expiration_range_
= expiration_range
;
207 // The following functions are atomic, and don't need locks
208 void SetFileSize(uint64_t fs
) { file_size_
= fs
; }
210 void SetBlobCount(uint64_t bc
) { blob_count_
= bc
; }
212 } // namespace blob_db
213 } // namespace rocksdb
214 #endif // ROCKSDB_LITE