mirror of https://github.com/trapexit/mergerfs.git
Browse Source
Merge pull request #815 from trapexit/policy-pfrd
Merge pull request #815 from trapexit/policy-pfrd
add {,ep,msp}pfrd policiespull/817/head
trapexit
4 years ago
committed by
GitHub
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 729 additions and 17 deletions
-
23README.md
-
23man/mergerfs.1
-
18src/policy.cpp
-
9src/policy.hpp
-
273src/policy_eppfrd.cpp
-
172src/policy_msppfrd.cpp
-
140src/policy_pfrd.cpp
-
55src/rnd.cpp
-
33src/rnd.hpp
@ -0,0 +1,273 @@ |
|||
/*
|
|||
Copyright (c) 2016, Antonio SJ Musumeci <trapexit@spawn.link> |
|||
|
|||
Permission to use, copy, modify, and/or distribute this software for any |
|||
purpose with or without fee is hereby granted, provided that the above |
|||
copyright notice and this permission notice appear in all copies. |
|||
|
|||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
|||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
|||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR |
|||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
|||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |
|||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |
|||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
|||
*/ |
|||
|
|||
#include "errno.hpp"
|
|||
#include "fs_exists.hpp"
|
|||
#include "fs_info.hpp"
|
|||
#include "fs_path.hpp"
|
|||
#include "fs_statvfs_cache.hpp"
|
|||
#include "policy.hpp"
|
|||
#include "policy_error.hpp"
|
|||
#include "rnd.hpp"
|
|||
#include "rwlock.hpp"
|
|||
|
|||
#include <string>
|
|||
#include <vector>
|
|||
|
|||
using std::string; |
|||
using std::vector; |
|||
|
|||
struct BranchInfo |
|||
{ |
|||
uint64_t spaceavail; |
|||
const string *basepath; |
|||
}; |
|||
|
|||
typedef vector<BranchInfo> BranchInfoVec; |
|||
|
|||
namespace eppfrd |
|||
{ |
|||
static |
|||
int |
|||
get_branchinfo_create(const Branches &branches_, |
|||
const char *fusepath_, |
|||
const uint64_t minfreespace_, |
|||
BranchInfoVec *branchinfo_, |
|||
uint64_t *sum_) |
|||
{ |
|||
int rv; |
|||
int error; |
|||
BranchInfo bi; |
|||
fs::info_t info; |
|||
const Branch *branch; |
|||
rwlock::ReadGuard guard(&branches_.lock); |
|||
|
|||
*sum_ = 0; |
|||
error = ENOENT; |
|||
for(size_t i = 0, ei = branches_.size(); i < ei; i++) |
|||
{ |
|||
branch = &branches_[i]; |
|||
|
|||
if(branch->ro_or_nc()) |
|||
error_and_continue(error,EROFS); |
|||
if(!fs::exists(branch->path,fusepath_)) |
|||
error_and_continue(error,ENOENT); |
|||
rv = fs::info(branch->path,&info); |
|||
if(rv == -1) |
|||
error_and_continue(error,ENOENT); |
|||
if(info.readonly) |
|||
error_and_continue(error,EROFS); |
|||
if(info.spaceavail < minfreespace_) |
|||
error_and_continue(error,ENOSPC); |
|||
|
|||
*sum_ += info.spaceavail; |
|||
|
|||
bi.spaceavail = info.spaceavail; |
|||
bi.basepath = &branch->path; |
|||
branchinfo_->push_back(bi); |
|||
} |
|||
|
|||
return error; |
|||
} |
|||
|
|||
static |
|||
int |
|||
get_branchinfo_action(const Branches &branches_, |
|||
const char *fusepath_, |
|||
const uint64_t minfreespace_, |
|||
BranchInfoVec *branchinfo_, |
|||
uint64_t *sum_) |
|||
{ |
|||
int rv; |
|||
int error; |
|||
BranchInfo bi; |
|||
fs::info_t info; |
|||
const Branch *branch; |
|||
rwlock::ReadGuard guard(&branches_.lock); |
|||
|
|||
*sum_ = 0; |
|||
error = ENOENT; |
|||
for(size_t i = 0, ei = branches_.size(); i < ei; i++) |
|||
{ |
|||
branch = &branches_[i]; |
|||
|
|||
if(branch->ro()) |
|||
error_and_continue(error,EROFS); |
|||
if(!fs::exists(branch->path,fusepath_)) |
|||
error_and_continue(error,ENOENT); |
|||
rv = fs::info(branch->path,&info); |
|||
if(rv == -1) |
|||
error_and_continue(error,ENOENT); |
|||
if(info.readonly) |
|||
error_and_continue(error,EROFS); |
|||
|
|||
*sum_ += info.spaceavail; |
|||
|
|||
bi.spaceavail = info.spaceavail; |
|||
bi.basepath = &branch->path; |
|||
branchinfo_->push_back(bi); |
|||
} |
|||
|
|||
return error; |
|||
} |
|||
|
|||
static |
|||
int |
|||
get_branchinfo_search(const Branches &branches_, |
|||
const char *fusepath_, |
|||
const uint64_t minfreespace_, |
|||
BranchInfoVec *branchinfo_, |
|||
uint64_t *sum_) |
|||
{ |
|||
int rv; |
|||
BranchInfo bi; |
|||
uint64_t spaceavail; |
|||
const Branch *branch; |
|||
rwlock::ReadGuard guard(&branches_.lock); |
|||
|
|||
*sum_ = 0; |
|||
for(size_t i = 0, ei = branches_.size(); i < ei; i++) |
|||
{ |
|||
branch = &branches_[i]; |
|||
|
|||
if(!fs::exists(branch->path,fusepath_)) |
|||
continue; |
|||
rv = fs::statvfs_cache_spaceavail(branch->path,&spaceavail); |
|||
if(rv == -1) |
|||
continue; |
|||
|
|||
*sum_ += spaceavail; |
|||
|
|||
bi.spaceavail = spaceavail; |
|||
bi.basepath = &branch->path; |
|||
branchinfo_->push_back(bi); |
|||
} |
|||
|
|||
return ENOENT; |
|||
} |
|||
|
|||
static |
|||
const |
|||
string* |
|||
get_branch(const BranchInfoVec &branchinfo_, |
|||
const uint64_t sum_) |
|||
{ |
|||
uint64_t idx; |
|||
uint64_t threshold; |
|||
|
|||
idx = 0; |
|||
threshold = RND::rand64(sum_); |
|||
for(size_t i = 0; i < branchinfo_.size(); i++) |
|||
{ |
|||
idx += branchinfo_[i].spaceavail; |
|||
|
|||
if(idx < threshold) |
|||
continue; |
|||
|
|||
return branchinfo_[i].basepath; |
|||
} |
|||
|
|||
return NULL; |
|||
} |
|||
|
|||
static |
|||
int |
|||
create(const Branches &branches_, |
|||
const char *fusepath_, |
|||
const uint64_t minfreespace_, |
|||
vector<string> *paths_) |
|||
{ |
|||
int error; |
|||
uint64_t sum; |
|||
const string *basepath; |
|||
BranchInfoVec branchinfo; |
|||
|
|||
branchinfo.reserve(branches_.size()); |
|||
error = eppfrd::get_branchinfo_create(branches_,fusepath_,minfreespace_,&branchinfo,&sum); |
|||
basepath = eppfrd::get_branch(branchinfo,sum); |
|||
if(basepath == NULL) |
|||
return (errno=error,-1); |
|||
|
|||
paths_->push_back(*basepath); |
|||
|
|||
return 0; |
|||
} |
|||
|
|||
static |
|||
int |
|||
action(const Branches &branches_, |
|||
const char *fusepath_, |
|||
const uint64_t minfreespace_, |
|||
vector<string> *paths_) |
|||
{ |
|||
int error; |
|||
uint64_t sum; |
|||
const string *basepath; |
|||
BranchInfoVec branchinfo; |
|||
|
|||
branchinfo.reserve(branches_.size()); |
|||
error = eppfrd::get_branchinfo_action(branches_,fusepath_,minfreespace_,&branchinfo,&sum); |
|||
basepath = eppfrd::get_branch(branchinfo,sum); |
|||
if(basepath == NULL) |
|||
return (errno=error,-1); |
|||
|
|||
paths_->push_back(*basepath); |
|||
|
|||
return 0; |
|||
} |
|||
|
|||
static |
|||
int |
|||
search(const Branches &branches_, |
|||
const char *fusepath_, |
|||
const uint64_t minfreespace_, |
|||
vector<string> *paths_) |
|||
{ |
|||
int error; |
|||
uint64_t sum; |
|||
const string *basepath; |
|||
BranchInfoVec branchinfo; |
|||
|
|||
branchinfo.reserve(branches_.size()); |
|||
error = eppfrd::get_branchinfo_search(branches_,fusepath_,minfreespace_,&branchinfo,&sum); |
|||
basepath = eppfrd::get_branch(branchinfo,sum); |
|||
if(basepath == NULL) |
|||
return (errno=error,-1); |
|||
|
|||
paths_->push_back(*basepath); |
|||
|
|||
return 0; |
|||
} |
|||
} |
|||
|
|||
int |
|||
Policy::Func::eppfrd(const Category type_, |
|||
const Branches &branches_, |
|||
const char *fusepath_, |
|||
const uint64_t minfreespace_, |
|||
vector<string> *paths_) |
|||
{ |
|||
switch(type_) |
|||
{ |
|||
case Category::CREATE: |
|||
return eppfrd::create(branches_,fusepath_,minfreespace_,paths_); |
|||
case Category::ACTION: |
|||
return eppfrd::action(branches_,fusepath_,minfreespace_,paths_); |
|||
default: |
|||
case Category::SEARCH: |
|||
return eppfrd::search(branches_,fusepath_,minfreespace_,paths_); |
|||
} |
|||
} |
@ -0,0 +1,172 @@ |
|||
/*
|
|||
ISC License |
|||
|
|||
Copyright (c) 2020, Antonio SJ Musumeci <trapexit@spawn.link> |
|||
|
|||
Permission to use, copy, modify, and/or distribute this software for any |
|||
purpose with or without fee is hereby granted, provided that the above |
|||
copyright notice and this permission notice appear in all copies. |
|||
|
|||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
|||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
|||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR |
|||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
|||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |
|||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |
|||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
|||
*/ |
|||
|
|||
#include "errno.hpp"
|
|||
#include "fs_exists.hpp"
|
|||
#include "fs_info.hpp"
|
|||
#include "fs_path.hpp"
|
|||
#include "fs_statvfs_cache.hpp"
|
|||
#include "policy.hpp"
|
|||
#include "policy_error.hpp"
|
|||
#include "rnd.hpp"
|
|||
#include "rwlock.hpp"
|
|||
|
|||
#include <string>
|
|||
#include <vector>
|
|||
|
|||
using std::string; |
|||
using std::vector; |
|||
|
|||
struct BranchInfo |
|||
{ |
|||
uint64_t spaceavail; |
|||
const string *basepath; |
|||
}; |
|||
|
|||
typedef vector<BranchInfo> BranchInfoVec; |
|||
|
|||
namespace msppfrd |
|||
{ |
|||
static |
|||
int |
|||
create_1(const Branches &branches_, |
|||
const string &fusepath_, |
|||
const uint64_t minfreespace_, |
|||
BranchInfoVec *branchinfo_, |
|||
uint64_t *sum_) |
|||
{ |
|||
int rv; |
|||
int error; |
|||
BranchInfo bi; |
|||
fs::info_t info; |
|||
const Branch *branch; |
|||
rwlock::ReadGuard guard(&branches_.lock); |
|||
|
|||
*sum_ = 0; |
|||
error = ENOENT; |
|||
for(size_t i = 0, ei = branches_.size(); i < ei; i++) |
|||
{ |
|||
branch = &branches_[i]; |
|||
|
|||
if(branch->ro_or_nc()) |
|||
error_and_continue(error,EROFS); |
|||
if(!fs::exists(branch->path,fusepath_)) |
|||
error_and_continue(error,ENOENT); |
|||
rv = fs::info(branch->path,&info); |
|||
if(rv == -1) |
|||
error_and_continue(error,ENOENT); |
|||
if(info.readonly) |
|||
error_and_continue(error,EROFS); |
|||
if(info.spaceavail < minfreespace_) |
|||
error_and_continue(error,ENOSPC); |
|||
|
|||
*sum_ += info.spaceavail; |
|||
|
|||
bi.spaceavail = info.spaceavail; |
|||
bi.basepath = &branch->path; |
|||
branchinfo_->push_back(bi); |
|||
} |
|||
|
|||
return error; |
|||
} |
|||
|
|||
static |
|||
int |
|||
get_branchinfo(const Branches &branches_, |
|||
const char *fusepath_, |
|||
const uint64_t minfreespace_, |
|||
BranchInfoVec *branchinfo_, |
|||
uint64_t *sum_) |
|||
{ |
|||
int error; |
|||
string fusepath; |
|||
|
|||
fusepath = fusepath_; |
|||
do |
|||
{ |
|||
error = msppfrd::create_1(branches_,fusepath,minfreespace_,branchinfo_,sum_); |
|||
if(branchinfo_->size()) |
|||
return error; |
|||
|
|||
fusepath = fs::path::dirname(fusepath); |
|||
} |
|||
while(!fusepath.empty()); |
|||
|
|||
return error; |
|||
} |
|||
|
|||
static |
|||
const |
|||
string* |
|||
get_branch(const BranchInfoVec &branchinfo_, |
|||
const uint64_t sum_) |
|||
{ |
|||
uint64_t idx; |
|||
uint64_t threshold; |
|||
|
|||
idx = 0; |
|||
threshold = RND::rand64(sum_); |
|||
for(size_t i = 0; i < branchinfo_.size(); i++) |
|||
{ |
|||
idx += branchinfo_[i].spaceavail; |
|||
|
|||
if(idx < threshold) |
|||
continue; |
|||
|
|||
return branchinfo_[i].basepath; |
|||
} |
|||
|
|||
return NULL; |
|||
} |
|||
|
|||
static |
|||
int |
|||
create(const Branches &branches_, |
|||
const char *fusepath_, |
|||
const uint64_t minfreespace_, |
|||
vector<string> *paths_) |
|||
{ |
|||
int error; |
|||
uint64_t sum; |
|||
const string *basepath; |
|||
BranchInfoVec branchinfo; |
|||
|
|||
branchinfo.reserve(branches_.size()); |
|||
error = msppfrd::get_branchinfo(branches_,fusepath_,minfreespace_,&branchinfo,&sum); |
|||
basepath = msppfrd::get_branch(branchinfo,sum); |
|||
if(basepath == NULL) |
|||
return (errno=error,-1); |
|||
|
|||
paths_->push_back(*basepath); |
|||
|
|||
return 0; |
|||
} |
|||
} |
|||
|
|||
int |
|||
Policy::Func::msppfrd(const Category type_, |
|||
const Branches &branches_, |
|||
const char *fusepath_, |
|||
const uint64_t minfreespace_, |
|||
vector<string> *paths_) |
|||
{ |
|||
if(type_ == Category::CREATE) |
|||
return msppfrd::create(branches_,fusepath_,minfreespace_,paths_); |
|||
|
|||
return Policy::Func::eppfrd(type_,branches_,fusepath_,minfreespace_,paths_); |
|||
} |
@ -0,0 +1,140 @@ |
|||
/*
|
|||
Copyright (c) 2016, Antonio SJ Musumeci <trapexit@spawn.link> |
|||
|
|||
Permission to use, copy, modify, and/or distribute this software for any |
|||
purpose with or without fee is hereby granted, provided that the above |
|||
copyright notice and this permission notice appear in all copies. |
|||
|
|||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
|||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
|||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR |
|||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
|||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |
|||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |
|||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
|||
*/ |
|||
|
|||
#include "errno.hpp"
|
|||
#include "fs_info.hpp"
|
|||
#include "fs_path.hpp"
|
|||
#include "policy.hpp"
|
|||
#include "policy_error.hpp"
|
|||
#include "rnd.hpp"
|
|||
#include "rwlock.hpp"
|
|||
|
|||
#include <string>
|
|||
#include <vector>
|
|||
|
|||
using std::string; |
|||
using std::vector; |
|||
|
|||
struct BranchInfo |
|||
{ |
|||
uint64_t spaceavail; |
|||
const string *basepath; |
|||
}; |
|||
|
|||
typedef vector<BranchInfo> BranchInfoVec; |
|||
|
|||
namespace pfrd |
|||
{ |
|||
static |
|||
int |
|||
get_branchinfo(const Branches &branches_, |
|||
const uint64_t minfreespace_, |
|||
BranchInfoVec *branchinfo_, |
|||
uint64_t *sum_) |
|||
{ |
|||
int rv; |
|||
int error; |
|||
BranchInfo bi; |
|||
fs::info_t info; |
|||
const Branch *branch; |
|||
rwlock::ReadGuard guard(&branches_.lock); |
|||
|
|||
*sum_ = 0; |
|||
error = ENOENT; |
|||
for(size_t i = 0, ei = branches_.size(); i < ei; i++) |
|||
{ |
|||
branch = &branches_[i]; |
|||
|
|||
if(branch->ro_or_nc()) |
|||
error_and_continue(error,EROFS); |
|||
rv = fs::info(branch->path,&info); |
|||
if(rv == -1) |
|||
error_and_continue(error,ENOENT); |
|||
if(info.readonly) |
|||
error_and_continue(error,EROFS); |
|||
if(info.spaceavail < minfreespace_) |
|||
error_and_continue(error,ENOSPC); |
|||
|
|||
*sum_ += info.spaceavail; |
|||
|
|||
bi.spaceavail = info.spaceavail; |
|||
bi.basepath = &branch->path; |
|||
branchinfo_->push_back(bi); |
|||
} |
|||
|
|||
return error; |
|||
} |
|||
|
|||
static |
|||
const |
|||
string* |
|||
get_branch(const BranchInfoVec &branchinfo_, |
|||
const uint64_t sum_) |
|||
{ |
|||
uint64_t idx; |
|||
uint64_t threshold; |
|||
|
|||
idx = 0; |
|||
threshold = RND::rand64(sum_); |
|||
for(size_t i = 0; i < branchinfo_.size(); i++) |
|||
{ |
|||
idx += branchinfo_[i].spaceavail; |
|||
|
|||
if(idx < threshold) |
|||
continue; |
|||
|
|||
return branchinfo_[i].basepath; |
|||
} |
|||
|
|||
return NULL; |
|||
} |
|||
|
|||
static |
|||
int |
|||
create(const Branches &branches_, |
|||
const char *fusepath_, |
|||
const uint64_t minfreespace_, |
|||
vector<string> *paths_) |
|||
{ |
|||
int error; |
|||
uint64_t sum; |
|||
const string *basepath; |
|||
BranchInfoVec branchinfo; |
|||
|
|||
branchinfo.reserve(branches_.size()); |
|||
error = pfrd::get_branchinfo(branches_,minfreespace_,&branchinfo,&sum); |
|||
basepath = pfrd::get_branch(branchinfo,sum); |
|||
if(basepath == NULL) |
|||
return (errno=error,-1); |
|||
|
|||
paths_->push_back(*basepath); |
|||
|
|||
return 0; |
|||
} |
|||
} |
|||
|
|||
int |
|||
Policy::Func::pfrd(const Category type_, |
|||
const Branches &branches_, |
|||
const char *fusepath_, |
|||
const uint64_t minfreespace_, |
|||
vector<string> *paths_) |
|||
{ |
|||
if(type_ == Category::CREATE) |
|||
return pfrd::create(branches_,fusepath_,minfreespace_,paths_); |
|||
|
|||
return Policy::Func::eppfrd(type_,branches_,fusepath_,minfreespace_,paths_); |
|||
} |
@ -0,0 +1,55 @@ |
|||
/*
|
|||
ISC License |
|||
|
|||
Copyright (c) 2020, Antonio SJ Musumeci <trapexit@spawn.link> |
|||
|
|||
Permission to use, copy, modify, and/or distribute this software for any |
|||
purpose with or without fee is hereby granted, provided that the above |
|||
copyright notice and this permission notice appear in all copies. |
|||
|
|||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
|||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
|||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR |
|||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
|||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |
|||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |
|||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
|||
*/ |
|||
|
|||
#include "rnd.hpp"
|
|||
|
|||
#include "wyhash.h"
|
|||
|
|||
#include <stdint.h>
|
|||
#include <sys/time.h>
|
|||
|
|||
static uint64_t G_SEED; |
|||
static RND G_RND; |
|||
|
|||
RND::RND() |
|||
{ |
|||
struct timeval tv; |
|||
|
|||
gettimeofday(&tv,NULL); |
|||
|
|||
G_SEED = ((tv.tv_sec << 32) | (tv.tv_usec)); |
|||
} |
|||
|
|||
uint64_t |
|||
RND::rand64(void) |
|||
{ |
|||
return wyrand(&G_SEED); |
|||
} |
|||
|
|||
uint64_t |
|||
RND::rand64(const uint64_t max_) |
|||
{ |
|||
return (wyrand(&G_SEED) % max_); |
|||
} |
|||
|
|||
uint64_t |
|||
RND::rand64(const uint64_t min_, |
|||
const uint64_t max_) |
|||
{ |
|||
return (min_ + (wyrand(&G_SEED) % (max_ - min_))); |
|||
} |
@ -0,0 +1,33 @@ |
|||
/*
|
|||
ISC License |
|||
|
|||
Copyright (c) 2020, Antonio SJ Musumeci <trapexit@spawn.link> |
|||
|
|||
Permission to use, copy, modify, and/or distribute this software for any |
|||
purpose with or without fee is hereby granted, provided that the above |
|||
copyright notice and this permission notice appear in all copies. |
|||
|
|||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
|||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
|||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR |
|||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
|||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |
|||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |
|||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
|||
*/ |
|||
|
|||
#pragma once
|
|||
|
|||
#include <stdint.h>
|
|||
|
|||
class RND |
|||
{ |
|||
public: |
|||
RND(); |
|||
|
|||
public: |
|||
static uint64_t rand64(void); |
|||
static uint64_t rand64(const uint64_t max_); |
|||
static uint64_t rand64(const uint64_t min_, |
|||
const uint64_t max_); |
|||
}; |
Write
Preview
Loading…
Cancel
Save
Reference in new issue