代码拉取完成,页面将自动刷新
同步操作将从 Gitee 极速下载/curve 强制同步,此操作会覆盖自 Fork 仓库以来所做的任何修改,且无法恢复!!!
确定后同步将在后台操作,完成时将刷新页面,请耐心等待。
/*
* Copyright (c) 2020 NetEase Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* Project: curve
* File Created: Monday, 15th October 2018 10:52:48 am
* Author: tongguangxun
*/
#ifndef SRC_CLIENT_METACACHE_STRUCT_H_
#define SRC_CLIENT_METACACHE_STRUCT_H_
#include <atomic>
#include <string>
#include <unordered_map>
#include <vector>
#include "include/curve_compiler_specific.h"
#include "src/client/client_common.h"
#include "src/common/concurrent/spinlock.h"
namespace curve {
namespace client {
using curve::common::SpinLock;
// copyset内的chunkserver节点的基本信息
// 包含当前chunkserver的id信息,以及chunkserver的地址信息
struct CURVE_CACHELINE_ALIGNMENT CopysetPeerInfo {
// 当前chunkserver节点的ID
ChunkServerID chunkserverID = 0;
// 当前chunkserver节点的内部地址
ChunkServerAddr internalAddr;
// 当前chunkserver节点的外部地址
ChunkServerAddr externalAddr;
CopysetPeerInfo() = default;
CopysetPeerInfo& operator=(const CopysetPeerInfo& other) = default;
CopysetPeerInfo(const ChunkServerID& cid,
const ChunkServerAddr& internal,
const ChunkServerAddr& external)
: chunkserverID(cid), internalAddr(internal), externalAddr(external) {}
bool operator==(const CopysetPeerInfo& other) const {
return this->internalAddr == other.internalAddr &&
this->externalAddr == other.externalAddr;
}
bool IsEmpty() const {
return this->chunkserverID == 0 && this->internalAddr.IsEmpty() &&
this->externalAddr.IsEmpty();
}
};
// copyset的基本信息,包含peer信息、leader信息、appliedindex信息
struct CURVE_CACHELINE_ALIGNMENT CopysetInfo {
// leader存在变更可能标志位
bool leaderMayChange_ = false;
// 当前copyset的节点信息
std::vector<CopysetPeerInfo> csinfos_;
// 当前节点的apply信息,在read的时候需要,用来避免读IO进入raft
std::atomic<uint64_t> lastappliedindex_{0};
// leader在本copyset信息中的索引,用于后面避免重复尝试同一个leader
int16_t leaderindex_ = -1;
// 当前copyset的id信息
CopysetID cpid_ = 0;
// 用于保护对copyset信息的修改
SpinLock spinlock_;
CopysetInfo() = default;
~CopysetInfo() = default;
CopysetInfo& operator=(const CopysetInfo& other) {
this->cpid_ = other.cpid_;
this->csinfos_ = other.csinfos_;
this->leaderindex_ = other.leaderindex_;
this->lastappliedindex_.store(other.lastappliedindex_);
this->leaderMayChange_ = other.leaderMayChange_;
return *this;
}
CopysetInfo(const CopysetInfo& other)
: leaderMayChange_(other.leaderMayChange_),
csinfos_(other.csinfos_),
lastappliedindex_(other.lastappliedindex_.load()),
leaderindex_(other.leaderindex_),
cpid_(other.cpid_) {}
uint64_t GetAppliedIndex() const {
return lastappliedindex_.load(std::memory_order_acquire);
}
void SetLeaderUnstableFlag() {
leaderMayChange_ = true;
}
void ResetSetLeaderUnstableFlag() {
leaderMayChange_ = false;
}
bool LeaderMayChange() const {
return leaderMayChange_;
}
/**
* read,write返回时,会携带最新的appliedindex更新当前的appliedindex
* 如果read,write失败,那么会将appliedindex更新为0
* @param: appliedindex为待更新的值
*/
void UpdateAppliedIndex(uint64_t appliedindex) {
uint64_t curIndex = lastappliedindex_.load(std::memory_order_acquire);
if (appliedindex != 0 && appliedindex <= curIndex) {
return;
}
while (!lastappliedindex_.compare_exchange_strong(
curIndex, appliedindex, std::memory_order_acq_rel)) {
if (curIndex >= appliedindex) {
break;
}
}
}
/**
* 获取当前leader的索引
*/
int16_t GetCurrentLeaderIndex() const {
return leaderindex_;
}
bool GetCurrentLeaderServerID(ChunkServerID* id) const {
if (leaderindex_ >= 0) {
if (csinfos_.size() < leaderindex_) {
return false;
} else {
*id = csinfos_[leaderindex_].chunkserverID;
return true;
}
} else {
return false;
}
}
/**
* 更新leaderindex,如果leader不在当前配置组中,则返回-1
* @param: addr为新的leader的地址信息
*/
int UpdateLeaderInfo(const ChunkServerAddr& addr,
CopysetPeerInfo csInfo = CopysetPeerInfo()) {
spinlock_.Lock();
bool exists = false;
uint16_t tempindex = 0;
for (auto iter : csinfos_) {
if (iter.internalAddr == addr || iter.externalAddr == addr) {
exists = true;
break;
}
tempindex++;
}
// 新的addr不在当前copyset内,如果csInfo不为空,那么将其插入copyset
if (!exists && !csInfo.IsEmpty()) {
csinfos_.push_back(csInfo);
} else if (exists == false) {
LOG(WARNING) << addr.ToString() << " not in current copyset and "
<< "its chunkserver info not supplied";
spinlock_.UnLock();
return -1;
}
leaderindex_ = tempindex;
spinlock_.UnLock();
return 0;
}
/**
* 获取leader信息
* @param: chunkserverid是出参
* @param: ep是出参
*/
int GetLeaderInfo(ChunkServerID* chunkserverid, EndPoint* ep) {
// 第一次获取leader,如果当前leader信息没有确定,返回-1,由外部主动发起更新leader
if (leaderindex_ < 0 || leaderindex_ >= csinfos_.size()) {
return -1;
}
*chunkserverid = csinfos_[leaderindex_].chunkserverID;
*ep = csinfos_[leaderindex_].externalAddr.addr_;
return 0;
}
/**
* 添加copyset的peerinfo
* @param: csinfo为待添加的peer信息
*/
void AddCopysetPeerInfo(const CopysetPeerInfo& csinfo) {
spinlock_.Lock();
csinfos_.push_back(csinfo);
spinlock_.UnLock();
}
/**
* 当前CopysetInfo是否合法
*/
bool IsValid() const {
return !csinfos_.empty();
}
/**
* 更新leaderindex
*/
void UpdateLeaderIndex(int index) {
leaderindex_ = index;
}
/**
* 当前copyset是否存在对应的chunkserver address
* @param: addr需要检测的chunkserver
* @return: true存在;false不存在
*/
bool HasChunkServerInCopyset(const ChunkServerAddr& addr) const {
for (const auto& peer : csinfos_) {
if (peer.internalAddr == addr || peer.externalAddr == addr) {
return true;
}
}
return false;
}
};
struct CopysetIDInfo {
LogicPoolID lpid = 0;
CopysetID cpid = 0;
CopysetIDInfo(LogicPoolID logicpoolid, CopysetID copysetid)
: lpid(logicpoolid), cpid(copysetid) {}
CopysetIDInfo(const CopysetIDInfo& other) = default;
CopysetIDInfo& operator=(const CopysetIDInfo& other) = default;
};
inline bool operator<(const CopysetIDInfo& cpidinfo1,
const CopysetIDInfo& cpidinfo2) {
return cpidinfo1.lpid <= cpidinfo2.lpid && cpidinfo1.cpid < cpidinfo2.cpid;
}
inline bool operator==(const CopysetIDInfo& cpidinfo1,
const CopysetIDInfo& cpidinfo2) {
return cpidinfo1.cpid == cpidinfo2.cpid && cpidinfo1.lpid == cpidinfo2.lpid;
}
} // namespace client
} // namespace curve
#endif // SRC_CLIENT_METACACHE_STRUCT_H_
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。