• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (C) 2019 Google LLC
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //      http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include "icing/legacy/index/icing-storage-file.h"
16 
17 #include <unistd.h>
18 
19 #include <cinttypes>
20 #include <string>
21 
22 #include "icing/legacy/core/icing-compat.h"
23 #include "icing/legacy/core/icing-string-util.h"
24 #include "icing/legacy/core/icing-timer.h"
25 #include "icing/util/logging.h"
26 
27 namespace icing {
28 namespace lib {
29 
IcingStorageFile(const std::string & filename,const IcingFilesystem * filesystem)30 IcingStorageFile::IcingStorageFile(const std::string &filename,
31                                    const IcingFilesystem *filesystem)
32     : IIcingStorage(), filesystem_(filesystem), filename_(filename) {}
33 
Init()34 bool IcingStorageFile::Init() {
35   if (!is_initialized_) {
36     // Ensure the storage directory exists
37     std::string storage_dir = filesystem_->GetDirname(filename_.c_str());
38     if (!filesystem_->CreateDirectoryRecursively(storage_dir.c_str())) {
39       return false;
40     }
41 
42     is_initialized_ = OnInit();
43 
44     if (is_initialized_ && fd_.get() < 0) {  // if initalized, fd better be set
45       ICING_LOG(FATAL)
46           << "Storage file descriptor not set after initialization";
47     }
48   }
49   return is_initialized_;
50 }
51 
Close()52 void IcingStorageFile::Close() {
53   if (is_initialized_) {
54     OnClose();
55     fd_.reset();
56     is_initialized_ = false;
57   }
58 }
59 
Remove()60 bool IcingStorageFile::Remove() {
61   Close();
62   return filesystem_->DeleteFile(filename_.c_str());
63 }
64 
Sync()65 bool IcingStorageFile::Sync() {
66   if (!is_initialized_) {
67     ICING_LOG(FATAL) << "Storage file not initialized";
68   }
69 
70   IcingTimer timer;
71   if (!PreSync()) {
72     ICING_LOG(ERROR) << "Pre-sync " << filename_ << " failed";
73     return false;
74   }
75   if (!filesystem_->DataSync(fd_.get())) {
76     ICING_LOG(ERROR) << "Sync " << filename_ << " failed";
77     return false;
78   }
79   if (!PostSync()) {
80     ICING_LOG(ERROR) << "Post-sync " << filename_ << " failed";
81     return false;
82   }
83   ICING_VLOG(1) << "Syncing " << filename_ << " took " << timer.Elapsed() * 1000 << "ms";
84   return true;
85 }
86 
GetDiskUsage() const87 uint64_t IcingStorageFile::GetDiskUsage() const {
88   return filesystem_->GetDiskUsage(fd_.get());
89 }
90 
PreSync()91 bool IcingStorageFile::PreSync() {
92   // Default implementation is a no-op.
93   return true;
94 }
95 
PostSync()96 bool IcingStorageFile::PostSync() {
97   // Default implementation is a no-op.
98   return true;
99 }
100 
GetDebugInfo(int verbosity,std::string * out) const101 void IcingStorageFile::GetDebugInfo(int verbosity, std::string *out) const {
102   if (!is_initialized_) {
103     ICING_LOG(FATAL) << "Storage file not initialized";
104   }
105 
106   if (verbosity >= 0) {  // Always
107     uint64_t size = filesystem_->GetFileSize(fd_.get());
108     IcingStringUtil::SStringAppendF(
109         out, 1000, "Filename: %s Size: %" PRIu64 "\n", filename_.c_str(), size);
110   }
111 }
112 
113 }  // namespace lib
114 }  // namespace icing
115