1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196
|
// -*- mode: cpp; mode: fold -*-
// Description /*{{{*/
/* ######################################################################
CacheDB
Simple uniform interface to a cache database.
##################################################################### */
/*}}}*/
#ifndef CACHEDB_H
#define CACHEDB_H
#include <apt-pkg/debfile.h>
#include <apt-pkg/hashes.h>
#include <db.h>
#include <cerrno>
#include <cstdint>
#include <cstdio>
#include <cstring>
#include <string>
#include "contents.h"
#include "sources.h"
class FileFd;
class CacheDB
{
protected:
// Database state/access
DBT Key;
DBT Data;
std::string TmpKey;
DB *Dbp;
bool DBLoaded;
bool ReadOnly;
std::string DBFile;
// Generate a key for the DB of a given type
void _InitQuery(const char *Type)
{
memset(&Key,0,sizeof(Key));
memset(&Data,0,sizeof(Data));
TmpKey.assign(FileName).append(":").append(Type);
Key.data = TmpKey.data();
Key.size = TmpKey.size();
}
void InitQueryStats() {
_InitQuery("st");
}
void InitQuerySource() {
_InitQuery("cs");
}
void InitQueryControl() {
_InitQuery("cl");
}
void InitQueryContent() {
_InitQuery("cn");
}
inline bool Get()
{
return Dbp->get(Dbp,0,&Key,&Data,0) == 0;
};
inline bool Put(const void *In,unsigned long const &Length)
{
if (ReadOnly == true)
return true;
Data.size = Length;
Data.data = (void *)In;
if (DBLoaded == true && (errno = Dbp->put(Dbp,0,&Key,&Data,0)) != 0)
{
DBLoaded = false;
return false;
}
return true;
}
bool OpenFile();
void CloseFile();
bool OpenDebFile();
void CloseDebFile();
// GetCurStat needs some compat code, see lp #1274466)
bool GetCurStatCompatOldFormat();
bool GetCurStatCompatNewFormat();
bool GetCurStat();
bool GetFileStat(bool const &doStat = false);
bool LoadControl();
bool LoadContents(bool const &GenOnly);
bool LoadSource();
bool GetHashes(bool const GenOnly, unsigned int const DoHashes);
// Stat info stored in the DB, Fixed types since it is written to disk.
enum FlagList {FlControl = (1<<0),FlMD5=(1<<1),FlContents=(1<<2),
FlSize=(1<<3), FlSHA1=(1<<4), FlSHA256=(1<<5),
FlSHA512=(1<<6), FlSource=(1<<7)
};
// the on-disk format changed (FileSize increased to 64bit) in
// commit 650faab0 which will lead to corruption with old caches
struct StatStoreOldFormat
{
uint32_t Flags;
uint32_t mtime;
uint32_t FileSize;
uint8_t MD5[16];
uint8_t SHA1[20];
uint8_t SHA256[32];
} CurStatOldFormat;
// WARNING: this struct is read/written to the DB so do not change the
// layout of the fields (see lp #1274466), only append to it
struct StatStore
{
uint32_t Flags;
uint32_t mtime;
uint64_t FileSize;
uint8_t MD5[16];
uint8_t SHA1[20];
uint8_t SHA256[32];
uint8_t SHA512[64];
} CurStat;
struct StatStore OldStat;
// 'set' state
std::string FileName;
FileFd *Fd;
debDebFile *DebFile;
public:
// Data collection helpers
debDebFile::MemControlExtract Control;
ContentsExtract Contents;
DscExtract Dsc;
HashStringList HashesList;
// Runtime statistics
struct Stats
{
double Bytes;
double MD5Bytes;
double SHA1Bytes;
double SHA256Bytes;
double SHA512Bytes;
unsigned long Packages;
unsigned long Misses;
unsigned long long DeLinkBytes;
inline void Add(const Stats &S) {
Bytes += S.Bytes;
MD5Bytes += S.MD5Bytes;
SHA1Bytes += S.SHA1Bytes;
SHA256Bytes += S.SHA256Bytes;
SHA512Bytes += S.SHA512Bytes;
Packages += S.Packages;
Misses += S.Misses;
DeLinkBytes += S.DeLinkBytes;
};
Stats() : Bytes(0), MD5Bytes(0), SHA1Bytes(0), SHA256Bytes(0),
SHA512Bytes(0),Packages(0), Misses(0), DeLinkBytes(0) {};
} Stats;
bool ReadyDB(std::string const &DB = "");
inline bool DBFailed() {return Dbp != 0 && DBLoaded == false;};
inline bool Loaded() {return DBLoaded == true;};
inline unsigned long long GetFileSize(void) {return CurStat.FileSize;}
bool SetFile(std::string const &FileName,struct stat St,FileFd *Fd);
// terrible old overloaded interface
bool GetFileInfo(std::string const &FileName,
bool const &DoControl,
bool const &DoContents,
bool const &GenContentsOnly,
bool const DoSource,
unsigned int const DoHashes,
bool const &checkMtime = false);
bool Finish();
bool Clean();
explicit CacheDB(std::string const &DB);
~CacheDB();
};
#endif
|