/************************************************************************
* EOS - the CERN Disk Storage System *
* Copyright (C) 2018 CERN/Switzerland *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see .*
************************************************************************/
#include "namespace/ns_quarkdb/accounting/QuotaNodeCore.hh"
#include
#include
EOSNSNAMESPACE_BEGIN
//----------------------------------------------------------------------------
// Get the amount of space occupied by the given user
//----------------------------------------------------------------------------
uint64_t QuotaNodeCore::getUsedSpaceByUser(uid_t uid) const
{
std::shared_lock lock(mtx);
auto it = mUserInfo.find(uid);
if (it == mUserInfo.end()) {
return 0;
}
return it->second.space;
}
//------------------------------------------------------------------------------
// Get the amount of space occupied by the given group
//------------------------------------------------------------------------------
uint64_t QuotaNodeCore::getUsedSpaceByGroup(gid_t gid) const
{
std::shared_lock lock(mtx);
auto it = mGroupInfo.find(gid);
if (it == mGroupInfo.end()) {
return 0;
}
return it->second.space;
}
//------------------------------------------------------------------------------
// Get the amount of space occupied by the given user
//------------------------------------------------------------------------------
uint64_t QuotaNodeCore::getPhysicalSpaceByUser(uid_t uid) const
{
std::shared_lock lock(mtx);
auto it = mUserInfo.find(uid);
if (it == mUserInfo.end()) {
return 0;
}
return it->second.physicalSpace;
}
//------------------------------------------------------------------------------
// Get the amount of space occupied by the given group
//------------------------------------------------------------------------------
uint64_t QuotaNodeCore::getPhysicalSpaceByGroup(gid_t gid) const
{
std::shared_lock lock(mtx);
auto it = mGroupInfo.find(gid);
if (it == mGroupInfo.end()) {
return 0;
}
return it->second.physicalSpace;
}
//------------------------------------------------------------------------------
// Get the amount of space occupied by the given user
//------------------------------------------------------------------------------
uint64_t QuotaNodeCore::getNumFilesByUser(uid_t uid) const
{
std::shared_lock lock(mtx);
auto it = mUserInfo.find(uid);
if (it == mUserInfo.end()) {
return 0;
}
return it->second.files;
}
//------------------------------------------------------------------------------
// Get the amount of space occupied by the given group
//------------------------------------------------------------------------------
uint64_t QuotaNodeCore::getNumFilesByGroup(gid_t gid) const
{
std::shared_lock lock(mtx);
auto it = mGroupInfo.find(gid);
if (it == mGroupInfo.end()) {
return 0;
}
return it->second.files;
}
//------------------------------------------------------------------------------
// Account a new file.
//------------------------------------------------------------------------------
void QuotaNodeCore::addFile(uid_t uid, gid_t gid, uint64_t size,
uint64_t physicalSize)
{
std::unique_lock lock(mtx);
UsageInfo& user = mUserInfo[uid];
UsageInfo& group = mGroupInfo[gid];
user.physicalSpace += physicalSize;
group.physicalSpace += physicalSize;
user.space += size;
group.space += size;
user.files++;
group.files++;
}
//------------------------------------------------------------------------------
// Remove a file.
//------------------------------------------------------------------------------
void QuotaNodeCore::removeFile(uid_t uid, gid_t gid, uint64_t size,
uint64_t physicalSize)
{
std::unique_lock lock(mtx);
UsageInfo& user = mUserInfo[uid];
UsageInfo& group = mGroupInfo[gid];
user.physicalSpace -= physicalSize;
group.physicalSpace -= physicalSize;
user.space -= size;
group.space -= size;
user.files--;
group.files--;
}
//------------------------------------------------------------------------------
// Meld in another quota node core
//------------------------------------------------------------------------------
void QuotaNodeCore::meld(const QuotaNodeCore& other)
{
std::lock(mtx, other.mtx);
for (auto it = other.mUserInfo.begin(); it != other.mUserInfo.end(); it++) {
mUserInfo[it->first] += it->second;
}
for (auto it = other.mGroupInfo.begin(); it != other.mGroupInfo.end(); it++) {
mGroupInfo[it->first] += it->second;
}
mtx.unlock();
other.mtx.unlock();
}
//----------------------------------------------------------------------------
// Get the set of uids for which information is stored in the current quota
// node.
//----------------------------------------------------------------------------
std::unordered_set QuotaNodeCore::getUids() const
{
std::shared_lock lock(mtx);
std::unordered_set uids;
for (auto it = mUserInfo.begin(); it != mUserInfo.end(); ++it) {
uids.insert(it->first);
}
return uids;
}
//----------------------------------------------------------------------------
// Get the set of gids for which information is stored in the current quota
// node.
//----------------------------------------------------------------------------
std::unordered_set QuotaNodeCore::getGids() const
{
std::shared_lock lock(mtx);
std::unordered_set gids;
for (auto it = mGroupInfo.begin(); it != mGroupInfo.end(); ++it) {
gids.insert(it->first);
}
return gids;
}
//------------------------------------------------------------------------------
// operator=
//------------------------------------------------------------------------------
QuotaNodeCore& QuotaNodeCore::operator=(const QuotaNodeCore& other)
{
std::lock(mtx, other.mtx);
mUserInfo = other.mUserInfo;
mGroupInfo = other.mGroupInfo;
mtx.unlock();
other.mtx.unlock();
return *this;
}
//------------------------------------------------------------------------------
// operator<< (replacing all entries from update in core)
//------------------------------------------------------------------------------
QuotaNodeCore& QuotaNodeCore::operator<< (const QuotaNodeCore &other)
{
std::lock(mtx, other.mtx);
for (auto it = other.mUserInfo.begin(); it != other.mUserInfo.end(); it++) {
mUserInfo[it->first] = it->second;
}
for (auto it = other.mGroupInfo.begin(); it != other.mGroupInfo.end(); it++) {
mGroupInfo[it->first] = it->second;
}
mtx.unlock();
other.mtx.unlock();
return *this;
}
//------------------------------------------------------------------------------
// equality operator==
//------------------------------------------------------------------------------
bool QuotaNodeCore::operator==(const QuotaNodeCore& other) const
{
std::lock(mtx, other.mtx);
bool result = mUserInfo == other.mUserInfo && mGroupInfo == other.mGroupInfo;
mtx.unlock();
other.mtx.unlock();
return result;
}
//----------------------------------------------------------------------------
//! set usage info by uid
//----------------------------------------------------------------------------
void QuotaNodeCore::setByUid(uid_t uid, const UsageInfo& info)
{
std::unique_lock lock(mtx);
mUserInfo[uid] = info;
}
//----------------------------------------------------------------------------
//! set usage info by gid
//----------------------------------------------------------------------------
void QuotaNodeCore::setByGid(gid_t gid, const UsageInfo& info)\
{
std::unique_lock lock(mtx);
mGroupInfo[gid] = info;
}
//----------------------------------------------------------------------------
//! filter usage info by uid
//----------------------------------------------------------------------------
void QuotaNodeCore::filterByUid(uid_t uid)
{
std::unique_lock lock(mtx);
std::set uidv;
for ( auto it : mUserInfo ) {
uidv.insert(it.first);
}
for ( auto it : uidv ) {
if ( it != uid ) {
mUserInfo.erase(it);
}
}
}
//----------------------------------------------------------------------------
//! filter usage info by gid
//----------------------------------------------------------------------------
void QuotaNodeCore::filterByGid(gid_t gid)
{
std::unique_lock lock(mtx);
std::set gidv;
for ( auto it : mGroupInfo ) {
gidv.insert(it.first);
}
for ( auto it : gidv ) {
if ( it != gid ) {
mGroupInfo.erase(it);
}
}
}
EOSNSNAMESPACE_END