// Copyright (c) Vitaliy Filippov, 2019+ // License: VNPL-1.1 or GNU GPL-2.0+ (see README.md for details) #pragma once #include #include #define POOL_SCHEME_REPLICATED 1 #define POOL_SCHEME_XOR 2 #define POOL_SCHEME_EC 3 #define POOL_ID_MAX 0x10000 #define POOL_ID_BITS 16 #define INODE_POOL(inode) (pool_id_t)((inode) >> (64 - POOL_ID_BITS)) #define INODE_NO_POOL(inode) (inode_t)((inode) & (((uint64_t)1 << (64-POOL_ID_BITS)) - 1)) #define INODE_WITH_POOL(pool_id, inode) (((inode_t)(pool_id) << (64-POOL_ID_BITS)) | INODE_NO_POOL(inode)) typedef uint64_t inode_t; // Pool ID is 16 bits long typedef uint32_t pool_id_t; typedef uint64_t osd_num_t; typedef uint32_t pg_num_t; struct pool_pg_num_t { pool_id_t pool_id; pg_num_t pg_num; }; // 16 bytes per object/stripe id // stripe = (start of the parity stripe + peer role) // i.e. for example (256KB + one of 0,1,2) struct __attribute__((__packed__)) object_id { inode_t inode; uint64_t stripe; }; inline bool operator == (const object_id & a, const object_id & b) { return a.inode == b.inode && a.stripe == b.stripe; } inline bool operator != (const object_id & a, const object_id & b) { return a.inode != b.inode || a.stripe != b.stripe; } inline bool operator < (const object_id & a, const object_id & b) { return a.inode < b.inode || a.inode == b.inode && a.stripe < b.stripe; } // 56 = 24 + 32 bytes per dirty entry in memory (obj_ver_id => dirty_entry) struct __attribute__((__packed__)) obj_ver_id { object_id oid; uint64_t version; }; inline bool operator == (const obj_ver_id & a, const obj_ver_id & b) { return a.oid == b.oid && a.version == b.version; } inline bool operator < (const obj_ver_id & a, const obj_ver_id & b) { return a.oid < b.oid || a.oid == b.oid && a.version < b.version; } inline bool operator < (const pool_pg_num_t & a, const pool_pg_num_t & b) { return a.pool_id < b.pool_id || a.pool_id == b.pool_id && a.pg_num < b.pg_num; } inline bool operator == (const pool_pg_num_t & a, const pool_pg_num_t & b) { return a.pool_id == b.pool_id && a.pg_num == b.pg_num; } inline bool operator != (const pool_pg_num_t & a, const pool_pg_num_t & b) { return a.pool_id != b.pool_id || a.pg_num != b.pg_num; } namespace std { template<> struct hash { inline size_t operator()(const object_id &s) const { size_t seed = 0; // Copy-pasted from spp::hash_combine() seed ^= (s.inode + 0xc6a4a7935bd1e995 + (seed << 6) + (seed >> 2)); seed ^= (s.stripe + 0xc6a4a7935bd1e995 + (seed << 6) + (seed >> 2)); return seed; } }; template<> struct hash { inline size_t operator()(const obj_ver_id &s) const { size_t seed = 0; // Copy-pasted from spp::hash_combine() seed ^= (s.oid.inode + 0xc6a4a7935bd1e995 + (seed << 6) + (seed >> 2)); seed ^= (s.oid.stripe + 0xc6a4a7935bd1e995 + (seed << 6) + (seed >> 2)); seed ^= (s.version + 0xc6a4a7935bd1e995 + (seed << 6) + (seed >> 2)); return seed; } }; }