-
-
Notifications
You must be signed in to change notification settings - Fork 130
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
14 changed files
with
644 additions
and
516 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,117 +1,164 @@ | ||
#include "CommitDetailGetter.h" | ||
#include "ApplicationGlobal.h" | ||
|
||
CommitDetailGetter::~CommitDetailGetter() | ||
{ | ||
stop(); | ||
} | ||
|
||
/** | ||
* @brief CommitDetailGetter::start | ||
* @param git | ||
* | ||
* コミットの詳細情報を取得するためのスレッドを開始する | ||
*/ | ||
void CommitDetailGetter::start(GitPtr git) | ||
{ | ||
interrupted_ = false; | ||
stop(); | ||
git_ = git; | ||
thread_ = std::make_shared<std::thread>([&](){ | ||
while (1) { | ||
Item item; | ||
{ | ||
std::unique_lock lock(mutex_); | ||
if (interrupted_) return; | ||
condition_.wait(lock); | ||
if (interrupted_) return; | ||
for (size_t i = 0; i < requests_.size(); i++) { | ||
if (!requests_[i].done && !requests_[i].busy) { | ||
requests_[i].busy = true; | ||
item = requests_[i]; | ||
break; | ||
threads_.clear(); | ||
threads_.resize(4); | ||
for (int i = 0; i < threads_.size(); i++) { | ||
std::thread th([&](){ | ||
while (1) { | ||
Request item; | ||
{ | ||
std::unique_lock lock(mutex_); | ||
if (interrupted_) return; | ||
|
||
auto NextQuery = [&](){ | ||
for (size_t i = requests_.size(); i > 0; i--) { | ||
Request *r = &requests_[i - 1]; | ||
if (!r->done && !r->busy) { | ||
r->busy = true; | ||
item = *r; | ||
break; | ||
} | ||
} | ||
}; | ||
|
||
NextQuery(); | ||
if (!item.id) { | ||
condition_.wait(lock); | ||
if (interrupted_) return; | ||
NextQuery(); | ||
} | ||
} | ||
} | ||
if (item.id) { | ||
auto c = git_->log_signature(item.id); | ||
if (c) { | ||
bool ok = false; | ||
Git::CommitItem const &commit = *c; | ||
item.value = commit.sign.verify; | ||
if (item.id) { | ||
auto c = git_->log_signature(item.id); | ||
if (c) { | ||
Git::CommitItem const &commit = *c; | ||
item.data.sign_verify = commit.sign.verify; | ||
} | ||
item.done = true; | ||
item.busy = false; | ||
bool em = false; | ||
{ | ||
std::lock_guard lock(mutex_); | ||
if (interrupted_) return; | ||
for (size_t i = 0; i < requests_.size(); i++) { | ||
if (item.id == requests_[i].id) { | ||
requests_.erase(requests_.begin() + i); | ||
requests_.push_back(item); | ||
requests_[i] = item; | ||
ok = true; | ||
cache_[item.id] = item.data; | ||
em = true; | ||
break; | ||
} | ||
} | ||
} | ||
if (ok) { | ||
if (em) { | ||
emit ready(); | ||
} | ||
} | ||
} | ||
} | ||
}); | ||
}); | ||
threads_[i] = std::move(th); | ||
} | ||
} | ||
|
||
/** | ||
* @brief CommitDetailGetter::stop | ||
* | ||
* スレッドを停止する | ||
*/ | ||
void CommitDetailGetter::stop() | ||
{ | ||
{ | ||
std::lock_guard lock(mutex_); | ||
interrupted_ = true; | ||
condition_.notify_all(); | ||
requests_.clear(); | ||
cache_.clear(); | ||
} | ||
if (thread_) { | ||
if (thread_->joinable()) { | ||
thread_->join(); | ||
for (int i = 0; i < threads_.size(); i++) { | ||
if (threads_[i].joinable()) { | ||
threads_[i].join(); | ||
} | ||
thread_.reset(); | ||
} | ||
threads_.clear(); | ||
interrupted_ = false; | ||
} | ||
|
||
CommitDetailGetter::Item CommitDetailGetter::request(Git::CommitID id) | ||
/** | ||
* @brief CommitDetailGetter::query | ||
* @param id | ||
* @param request_if_not_found | ||
* @param lock | ||
* @return | ||
* | ||
* コミットの詳細情報を取得する | ||
* 情報が存在しない場合はリクエスト予約を行う | ||
*/ | ||
CommitDetailGetter::Data CommitDetailGetter::query(Git::CommitID const &id, bool request_if_not_found, bool lock) | ||
{ | ||
if (lock) { | ||
std::lock_guard l(mutex_); | ||
return query(id, request_if_not_found, false); | ||
} | ||
if (id.isValid()) { | ||
std::lock_guard lock(mutex_); | ||
for (size_t i = 0; i < requests_.size(); i++) { | ||
if (id == requests_[i].id) { | ||
if (requests_[i].done) { | ||
Item item = requests_[i]; | ||
auto it = cache_.find(id); | ||
if (it != cache_.end()) { | ||
return it->second; | ||
} | ||
|
||
if (request_if_not_found) { | ||
for (size_t i = 0; i < requests_.size(); i++) { | ||
auto item = requests_[i]; | ||
if (item.id == id) { | ||
requests_.erase(requests_.begin() + i); | ||
requests_.push_back(item); | ||
return item; | ||
if (item.done) { | ||
cache_[item.id] = item.data; | ||
return item.data; | ||
} | ||
return {}; | ||
} | ||
} | ||
} | ||
|
||
Item item; | ||
item.id = id; | ||
requests_.push_back(item); | ||
Request item; | ||
item.id = id; | ||
requests_.push_back(item); | ||
|
||
size_t n = requests_.size(); | ||
if (n > 100) { | ||
n -= 100; | ||
requests_.erase(requests_.begin(), requests_.begin() + n); | ||
} | ||
const int MAX = std::min(1000, global->appsettings.maximum_number_of_commit_item_acquisitions); | ||
|
||
condition_.notify_all(); | ||
} | ||
return {}; | ||
} | ||
size_t n = requests_.size(); | ||
if (n > MAX) { | ||
n -= MAX; | ||
|
||
void CommitDetailGetter::apply(Git::CommitItemList *logs) | ||
{ | ||
std::lock_guard lock(mutex_); | ||
for (size_t i = 0; i < requests_.size(); i++) { | ||
if (requests_[i].done) { | ||
Git::CommitID const &id = requests_[i].id; | ||
for (size_t j = 0; j < logs->size(); j++) { | ||
if (id == (*logs)[j].commit_id) { | ||
(*logs)[j].sign.verify = requests_[i].value; | ||
break; | ||
for (size_t i = 0; i < n; i++) { | ||
auto it = cache_.find(requests_[i].id); | ||
if (it != cache_.end()) { | ||
cache_.erase(it); | ||
} | ||
} | ||
|
||
requests_.erase(requests_.begin(), requests_.begin() + n); | ||
} | ||
|
||
condition_.notify_all(); | ||
} | ||
} | ||
return {}; | ||
} | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.