* Copyright (c) Huawei Technologies Co., Ltd. 2025. All rights reserved.
* ubs-io is licensed under the Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
#ifndef BOOSTIO_WCACHE_H
#define BOOSTIO_WCACHE_H
#include <set>
#include <unordered_map>
#include "bio_execution.h"
#include "bio_ref.h"
#include "cache_def.h"
#include "cache_slice.h"
#include "cache_slice_operator.h"
#include "cm.h"
#include "flow.h"
#include "rcache_manager.h"
#include "underfs.h"
#include "wcache_tier.h"
namespace ock {
namespace bio {
class WCache;
using WCachePtr = Ref<WCache>;
class WCache {
public:
WCache(uint64_t procId, uint64_t flowId, uint16_t ptId, uint64_t ptv, uint16_t diskId, bool isDegrade)
: mProcId(procId),
mFlowId(flowId),
mPtId(ptId),
mPtv(ptv),
mDiskId(diskId),
mIsDegrade(isDegrade)
{
}
using EvictCallback = std::function<BResult(uint16_t ptId, const Key &key, WCacheSliceRefPtr sliceRef)>;
using RetryCallback = std::function<void(uint64_t flowId, WCacheTierType cacheTier)>;
BResult Init(const ExecutorServicePtr evictNegoService, const ExecutorServicePtr evictService[MAX_WCACHE_TIER],
const RCacheManagerPtr rCacheManager, bool isRecover);
void Exit();
void RegOp(GetLocDiskStatus getLocDiskStatus, CheckLocRole locRole, const GetGlobEvictOffset evictOffset,
EvictCallback evictCallback, const RetryCallback retryCallback);
static void GetCacheResource(uint64_t &memCap, uint64_t &memUsed, uint64_t &diskCap, uint64_t &diskUsed);
BResult GetWCacheSlice(const SliceKey &sliceKey, WCacheSlicePtr &slice);
BResult Put(const Key &key, const WCacheSlicePtr &srcSlice, const SliceReader &sliceReader,
WCacheSliceRefPtr &destSliceRef, CacheAttr &attr);
BResult PutImpl(const Key &key, const WCacheSlicePtr &srcSlice, const SliceReader &sliceReader,
WCacheSliceRefPtr &destSliceRef, CacheAttr &attr);
BResult Delete(const Key &key, const WCacheSliceRefPtr &sliceRef);
BResult Seal(WCacheTierType type);
void Destroy();
inline void SetDegradeState(bool flag)
{
mIsDegrade = flag;
}
inline bool GetDegradeState() const
{
return mIsDegrade;
}
inline void SetState(bool isNormal)
{
mIsNormal = isNormal;
}
inline bool GetState() const
{
return mIsNormal;
}
void StartEvictTask(WCacheTierType type);
BResult StartEvictNegotiateTask();
void RetryEvictTask(WCacheTierType type);
uint64_t GetCapacity(WCacheTierType type);
uint64_t GetVirCapacity(WCacheTierType type);
uint64_t GetEvictOffset();
inline uint64_t GetProcId() const
{
return mProcId;
}
inline uint64_t GetFlowId() const
{
return mFlowId;
}
inline uint16_t GetPtId() const
{
return mPtId;
}
inline uint64_t GetPtv() const
{
return mPtv;
}
inline void IncFlyIo()
{
mOnFlyRef += 1;
}
inline void DecFlyIo()
{
mOnFlyRef -= 1;
}
std::map<uint64_t, std::array<uint8_t, NO_256>> *GetEvictNegotiateIndexMap()
{
return mCacheTiers[WCACHE_MEMORY]->GetEvictMapPtr();
}
inline void NegotiateIndexMapLockRead()
{
mCacheTiers[WCACHE_MEMORY]->NegotiateIndexMapLockRead();
}
inline void NegotiateIndexMapUnLock()
{
mCacheTiers[WCACHE_MEMORY]->NegotiateIndexMapUnLock();
}
using RecoverCallback = std::function<BResult(uint16_t ptId, const Key &key, const WCacheSliceRefPtr &sliceRef)>;
BResult Recover(RecoverCallback recoverCallback);
void Flush(const WCachePtr &self);
void ExpiredClear(const WCachePtr &self);
void ProcAndCacheBrokenExpiredClear();
bool IsEmptyEvict(WCacheTierType type);
bool IsEmptyNegotiate();
void MasterEvictNegotiate(uint64_t indexs[], std::vector<bool> &result, uint32_t count);
DEFINE_REF_COUNT_FUNCTIONS;
private:
BResult EvictAllMemSliceToDisk();
BResult EvictAllDiskSliceToUnderFs();
BResult EvictFromMemToDisk(WCacheSliceRefPtr sliceRef, bool isFront = false);
BResult EvictFromDiskToUnderFs(WCacheSliceRefPtr sliceRef, bool isMaster, bool isFront = false);
BResult EvictFromMemToDiskImpl(WCacheSliceRefPtr sliceRef, bool isFront);
BResult EvictFromDiskToUnderFsImpl(WCacheSliceRefPtr sliceRef, bool isMaster, bool isFront);
BResult EvictSlice(WCacheSliceRefPtr &sliceRef);
BResult EvictToRcache(const WCacheSlicePtr &slice, const Key &key, void *value);
void EvictNegotiate();
void AddEvictNegotiateQueue(WCacheSliceRefPtr sliceRef, uint8_t refNum);
bool EvictMemSatisfiedCond();
bool EvictDiskSatisfiedCond();
BResult FlushMem();
BResult FlushDisk();
BResult ExpiredClearMemImpl(WCacheSliceRefPtr sliceRef);
BResult ExpiredClearMem();
BResult ExpiredClearDiskImpl(WCacheSliceRefPtr sliceRef);
BResult ExpiredClearDisk();
void PutSetIoStrategy(RealIoStrategy &ioStrategy, CacheAttr &attr);
BResult PutByPass(const Key &key, const WCacheSlicePtr &srcSlice, const SliceReader &sliceReader,
WCacheSliceRefPtr &destSliceRef, CacheAttr &attr);
BResult GetPtMasterNode(uint32_t &masterNid);
BResult StartEvictSlice(const Key &key, WCacheSliceRefPtr &destSliceRef, CacheAttr &attr);
private:
uint64_t mProcId;
uint64_t mFlowId;
uint16_t mPtId;
uint64_t mPtv;
uint16_t mDiskId;
uint16_t mCopyNum{0};
bool mIsDegrade;
bool mIsMaster{true};
bool mIsNormal{true};
bool mIsForced{false};
std::atomic<bool> mIsStartEvictNegotiate{false};
std::atomic<bool> mIsMasterStartEvictNegotiate{false};
EvictCallback mEvictCallback;
RetryCallback mRetryCallback;
WCacheTierPtr mCacheTiers[MAX_WCACHE_TIER];
CacheSliceOperator mSliceOperator;
ExecutorServicePtr mEvictService[MAX_WCACHE_TIER];
ExecutorServicePtr mEvictNegotiateService;
std::atomic<bool> mEvictRef[MAX_WCACHE_TIER];
GetLocDiskStatus mGetLocDiskStatus{nullptr};
CheckLocRole mLocRole{nullptr};
GetGlobEvictOffset mGlobEvictOffset{nullptr};
RCacheManagerPtr mRCacheManager;
UnderFsPtr mUnderFs;
std::atomic<uint64_t> mOnFlyRef;
DEFINE_REF_COUNT_VARIABLE;
};
}
}
#endif