-
Notifications
You must be signed in to change notification settings - Fork 0
/
QuickIndexImpl.h
151 lines (111 loc) · 4.2 KB
/
QuickIndexImpl.h
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
#ifndef QUICK_INDEX_IMPL_H_H_H
#define QUICK_INDEX_IMPL_H_H_H
namespace filerepo
{
#define kMaxEntriesCount 65535
#define kMaxShortPath 256
#define kMaxLargePath 4096
#define kInitEntriesCount 1024
#define kInitLargeEntriesCount 16
#define kEntryHashMask 0xFFFF
#define kEntryUseMask 0x1
#define kEntryPositionMask 0xFFFE
#define kEntriesAllocMapCount (kMaxEntriesCount/8 + (kMaxEntriesCount%8 > 0 ? 1 : 0))
typedef unsigned short EntryAddr;
typedef struct __QuickIndexHeader
{
size_t magic; // Magic value to identify the quick index file
size_t version; // Quick index file version
size_t num_entries; // Current entries count that have been stored
size_t num_entries_capacity; // The max entries count in current file
unsigned short entry_size; // Every entry size
unsigned short current_file; // Current index file number
unsigned short next_file; // Next index file number that store EntryShort
unsigned short next_large_file; // Next index file number that store EntryLarge
EntryAddr entries[kMaxEntriesCount]; // This array store entry addr, use path's hash value to locate
char entries_alloc_map[kEntriesAllocMapCount]; // This array used to identify is an entry position is used
}QuickIndexHeader;
typedef struct __EntryShort
{
EntryAddr next; // Next conflict entry position
Entry content;
char path[kMaxShortPath];
}EntryShort;
typedef struct __EntryLarge
{
EntryAddr next; // Next conflict entry position
Entry content;
char path[kMaxLargePath];
}EntryLarge;
class QuickIndexImpl;
class EntryIteratorImpl : public EntryIterator
{
public:
EntryIteratorImpl(QuickIndexImpl *qii);
// Implement EntryIterator
virtual std::string GetPath() OVERRIDE;
virtual Entry GetEntry() OVERRIDE;
virtual void Next() OVERRIDE;
virtual bool IsEnd() OVERRIDE;
virtual void Clear() OVERRIDE;
virtual void Begin() OVERRIDE;
private:
QuickIndexImpl *root_;
QuickIndexImpl *current_index_;
size_t entry_pos_; // Start from 0
};
class QuickIndexImpl : public QuickIndex
{
public:
QuickIndexImpl();
~QuickIndexImpl();
bool Init(const tstring &path, bool read_only);
virtual bool AddEntry(const std::string &path, const Entry &entry) OVERRIDE;
virtual bool RemoveEntry(const std::string &path) OVERRIDE;
virtual EntryIterator *GetEntryIterator() OVERRIDE;
virtual bool FindEntry(const std::string &path, Entry *entry) OVERRIDE;
virtual size_t GetEntriesCount() OVERRIDE;
virtual void Clear() OVERRIDE;
virtual std::string GetEntryPath(const Entry *entry) OVERRIDE;
virtual bool Save() OVERRIDE;
virtual bool CopyTo(const tstring &target_index_path) OVERRIDE;
// Delete all related index file from disk
bool DeleteFiles();
private:
bool GenerateHeader(size_t i, size_t entry_size);
bool IsFileExist(const tstring &path);
bool IsHeaderValid();
bool GrowIndexFile();
bool IsFileFull();
size_t GetEntrySize() const;
bool IsLargeEntry();
bool Init(const tstring &path, size_t file_number, size_t entry_size, bool read_only);
size_t GetHash(const std::string &path);
EntryAddr GetEntryAddr(size_t pos);
EntryAddr GetEmptyEntryAddr();
bool IsAddrUsed(EntryAddr addr);
bool IsAddrValid(EntryAddr addr);
void *GetEntryByAddr(EntryAddr addr);
bool UpdateLastConflictEntry(EntryAddr addr, EntryAddr next);
size_t GetFileSize( LPCTSTR file_path );
QuickIndexImpl *Next();
QuickIndexImpl *NextLarge();
void UpdateEntriesAllocMap(EntryAddr addr, bool is_used);
bool PrepareIndexFile();
void UpdateEntry(EntryAddr addr, const std::string &path, const Entry &entry);
tstring GenerateNextIndexFileName(const tstring &prefix, size_t index_number);
bool FindEntryInCurrentIndex(const std::string &path, EntryAddr &found_addr);
bool UseLargeEntryToStore(const std::string &path);
private:
QuickIndexHeader *header_;
MappedFile index_file_;
tstring index_file_path_;
tstring index_file_path_temp_;
QuickIndexImpl *next_large_index_;
QuickIndexImpl *next_index_;
bool index_file_modify_;
friend class EntryIteratorImpl;
DISALLOW_COPY_AND_ASSIGN(QuickIndexImpl);
};
} // namespace filerepo
#endif