adbncfs  0.9.1
fileinfoCache.cpp
Go to the documentation of this file.
1 /*
2  * $Id: fileinfoCache.cpp 2 2015-12-03 19:46:25Z wejaeger $
3  *
4  * File: fileinfCache.cpp
5  * Author: Werner Jaeger
6  *
7  * Copyright 2015 Werner Jaeger.
8  *
9  * This program is free software: you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation, either version 3 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program. If not, see <http://www.gnu.org/licenses/>.
21  */
22 #include "fileInfoCache.h"
23 #include <errno.h>
24 
26 static const int iFileDataCacheSecondsValid(120);
27 
28 int adbncPush(const string& strLocalSource, const string& strRemoteDestination);
29 int adbncShell(const string& strCommand);
30 
34 FileCache::Entry::Entry(const Entry& orig) : m_Timestamp(orig.m_Timestamp), m_pStatOutput(NULL), m_pReadLinkOutput(NULL)
35 {
36  if (orig.m_pStatOutput)
37  m_pStatOutput = new deque<string>(*orig.m_pStatOutput);
38 
39  if (orig.m_pReadLinkOutput)
40  m_pReadLinkOutput = new deque<string>(*orig.m_pReadLinkOutput);
41 }
42 
51 {
52  if(this != &orig) // protect against invalid self-assignment
53  {
54  if (m_pStatOutput)
55  delete m_pStatOutput;
56 
57  if (m_pReadLinkOutput)
58  delete m_pReadLinkOutput;
59 
60  m_pStatOutput = NULL;
61  m_pReadLinkOutput = NULL;
62 
63  if (orig.m_pStatOutput)
64  m_pStatOutput = new deque<string>(*orig.m_pStatOutput);
65 
66 
67  if (orig.m_pReadLinkOutput)
68  m_pReadLinkOutput = new deque<string>(*orig.m_pReadLinkOutput);
69 
70  m_Timestamp = orig.m_Timestamp;
71  }
72 
73  return(*this);
74 }
75 
80 {
81  if (m_pStatOutput)
82  delete m_pStatOutput;
83 
84  if (m_pReadLinkOutput)
85  delete m_pReadLinkOutput;
86 }
87 
88 void FileCache::Entry::statOutput(const deque<string>& output)
89 {
90  if (m_pStatOutput)
91  delete m_pStatOutput;
92 
93  m_pStatOutput = new deque<string>(output);
94 }
95 
96 void FileCache::Entry::readLinkOutput(const deque<string>& output)
97 {
98  if (m_pReadLinkOutput)
99  delete m_pReadLinkOutput;
100 
101  m_pReadLinkOutput = new deque<string>(output);
102 }
103 
111 void FileCache::putStat(const char *pcPath, const deque<string>& statOutput)
112 {
113  const map<string, Entry>::iterator it(m_Entries.find(pcPath));
114  if (it == m_Entries.end())
115  {
116  Entry entry;
117  entry.statOutput(statOutput);
118  m_Entries[pcPath] = entry;
119  }
120  else
121  {
122  it->second.statOutput(statOutput);
123  it->second.timeStamp(::time(NULL));
124  }
125 }
126 
134 void FileCache::putReadLink(const char *pcPath, const deque<string>& readLinkOutput)
135 {
136  const map<string, Entry>::iterator it(m_Entries.find(pcPath));
137  if (it == m_Entries.end())
138  {
139  Entry entry;
140  entry.readLinkOutput(readLinkOutput);
141  m_Entries[pcPath] = entry;
142  }
143  else
144  {
145  it->second.readLinkOutput(readLinkOutput);
146  it->second.timeStamp(::time(NULL));
147  }
148 }
149 
150 const deque<string>* FileCache::getStat(const char *pcPath) const
151 {
152  const deque<string>* pOut(NULL);
153 
154  const map<string, Entry>::const_iterator it(m_Entries.find(pcPath));
155  if (it != m_Entries.end())
156  {
157  if (isValid(it->second))
158  pOut = it->second.statOutput();
159  }
160 
161  return(pOut);
162 }
163 
164 const deque<string>* FileCache::getReadLink(const char *pcPath) const
165 {
166  const deque<string>* pOut(NULL);
167 
168  const map<string, Entry>::const_iterator it(m_Entries.find(pcPath));
169  if (it != m_Entries.end())
170  {
171  if (isValid(it->second))
172  pOut = it->second.readLinkOutput();
173  }
174 
175  return(pOut);
176 }
177 
183 void FileCache::invalidate(const char *pcPath)
184 {
185  const map<string, Entry>::iterator it(m_Entries.find(pcPath));
186  if (it != m_Entries.end())
187  m_Entries.erase(it);
188 }
189 
195 bool FileCache::isValid(const Entry& entry) const
196 {
197  const time_t current = ::time(NULL);
198  return(entry.timeStamp() + iFileDataCacheSecondsValid > current);
199 }
200 
201  int FileStatus::Entry::release(const int iFh)
202  {
203  int iRes(-EBADF);
204 
205  if (iFh != -1)
206  {
207  if (::close(iFh) == -1)
208  iRes = -errno;
209  }
210 
211  m_fPendingOpen = false;
212  m_fForWrite = false;
213 
214  return(iRes);
215  }
216 
217 int FileStatus::Entry::flush(const string& strFromLocalPath, const string& strToPath)
218 {
219  int iRes(0);
220 
221  if (pendingOpen())
222  {
223  if (!m_strRenamedFromLocal.empty())
224  {
225  if (m_fForWrite)
226  iRes = adbncPush(m_strRenamedFromLocal, strToPath);
227 
228  m_strRenamedFromLocal.clear();
229  }
230  else
231  {
232  if (m_fForWrite)
233  iRes = adbncPush(strFromLocalPath, strToPath);
234  }
235 
236  pendingOpen(false, false);
237 
238 // if (!iRes)
239 // adbncShell(string("sync"));
240  }
241 
242  return(iRes);
243 }
244 
267 void FileStatus::pendingOpen(const char *pcPath, const bool fPendingOpen, const bool fForWrite)
268 {
269  const map<string, Entry>::iterator it(m_Entries.find(pcPath));
270 
271  if (it == m_Entries.end())
272  {
273  Entry entry;
274  entry.pendingOpen(fPendingOpen, fForWrite);
275  m_Entries.insert(make_pair(pcPath, entry));
276  }
277  else
278  it->second.pendingOpen(fPendingOpen, fForWrite);
279 }
280 
287 void FileStatus::pendingOpen(const char *pcPath, const string& strRenamedFromLocal)
288 {
289  const map<string, Entry>::iterator it(m_Entries.find(pcPath));
290 
291  if (it == m_Entries.end())
292  {
293  Entry entry;
294  entry.pendingOpen(strRenamedFromLocal);
295  m_Entries.insert(make_pair(pcPath, entry));
296  }
297  else
298  it->second.pendingOpen(strRenamedFromLocal);
299 }
300 
301 void FileStatus::truncated(const char *pcPath, const bool fTruncated)
302 {
303  const map<string, Entry>::iterator it(m_Entries.find(pcPath));
304 
305  if (it == m_Entries.end())
306  {
307  Entry entry;
308  entry.truncated(fTruncated);
309  m_Entries.insert(make_pair(pcPath, entry));
310  }
311  else
312  it->second.truncated(fTruncated);
313 }
314 
315 bool FileStatus::pendingOpen(const char *pcPath) const
316 {
317  bool fRet(false);
318 
319  const map<string, Entry>::const_iterator it(m_Entries.find(pcPath));
320 
321  if (it != m_Entries.end())
322  fRet = it->second.pendingOpen();
323 
324  return(fRet);
325 }
326 
327 bool FileStatus::truncated(const char *pcPath) const
328 {
329  bool fRet(false);
330 
331  const map<string, Entry>::const_iterator it(m_Entries.find(pcPath));
332 
333  if (it != m_Entries.end())
334  fRet = it->second.truncated();
335 
336  return(fRet);
337 }
338 
339 int FileStatus::flush(const char *pcPath, const string& strFromLocalPath)
340 {
341  int iRes(0);
342 
343  const map<string, Entry>::iterator it(m_Entries.find(pcPath));
344 
345  if (it != m_Entries.end())
346  iRes = it->second.flush(strFromLocalPath, pcPath);
347 
348  return(iRes);
349 }
350 
351 int FileStatus::release(const char *pcPath, const int iFh)
352 {
353  int iRet(0);
354 
355  const map<string, Entry>::iterator it(m_Entries.find(pcPath));
356 
357  if (it != m_Entries.end())
358  iRet = it->second.release(iFh);
359 
360  return(iRet);
361 }
362 
363 
364 
deque< string > * m_pStatOutput
Definition: fileInfoCache.h:87
void putStat(const char *pcPath, const deque< string > &statOutput)
Caches the output of doStat().
void putReadLink(const char *pcPath, const deque< string > &readLinkOutput)
Caches the output of adbnc_readlink().
void statOutput(const deque< string > &output)
void pendingOpen(const char *pcPath, const bool fPendingOpen, const bool fForWrite)
Notes that on the given path a read or write operation has been performed.
deque< string > * m_pReadLinkOutput
Definition: fileInfoCache.h:88
Entry()
Default constructor.
Definition: fileInfoCache.h:66
const deque< string > * statOutput() const
Definition: fileInfoCache.h:82
int release(const int iFh)
bool isValid(const Entry &entry) const
Tests if the given cache entry is valid.
void truncated(const bool fTruncated)
void readLinkOutput(const deque< string > &output)
virtual ~Entry()
Virtual destructor.
int adbncShell(const string &strCommand)
void timeStamp(const time_t &time)
Set the entries time stamp.
Definition: fileInfoCache.h:76
Represents an entry of FileStatus.
int adbncPush(const string &strLocalSource, const string &strRemoteDestination)
Copy (using adb push) a file from the local host to the Android device.
Definition: adbncfs.cpp:528
Represents an entry of FileCache.
Definition: fileInfoCache.h:62
Entry & operator=(const Entry &orig)
Assignment operator.
void invalidate(const char *pcPath)
Renders the cashed data for the given file as invalid.
const deque< string > * getReadLink(const char *pcPath) const
int flush(const string &strFromLocalPath, const string &strToPat)
static const int iFileDataCacheSecondsValid(120)
Keep cache entries valid for 120 seconds.
const deque< string > * readLinkOutput() const
Definition: fileInfoCache.h:83
int release(const char *pcPath, const int iFh)
void pendingOpen(const bool fPendingOpen, const bool fForWrite)
const deque< string > * getStat(const char *pcPath) const
int flush(const char *pcPath, const string &strFromLocalPath)
map< string, Entry > m_Entries
Definition: fileInfoCache.h:99
void truncated(const char *pcPath, const bool fTruncated)