Commit b6700ed6 authored by Yoni Fogel's avatar Yoni Fogel

refs #5280 Add additional warning options and get it to compile cleanly.

Add comments and static asserts for on-disk formats (e.g. leafentries)

git-svn-id: file:///svn/toku/tokudb@45977 c7de825b-a66e-492c-adef-691d508d4ae1
parent 80257dbf
...@@ -35,6 +35,18 @@ endif (USE_GCOV) ...@@ -35,6 +35,18 @@ endif (USE_GCOV)
include(CheckCCompilerFlag) include(CheckCCompilerFlag)
include(CheckCXXCompilerFlag) include(CheckCXXCompilerFlag)
## adds a compiler flag if the compiler supports it
macro(set_cflags_if_supported_named flag flagname)
check_c_compiler_flag("${flag}" HAVE_C_${flagname})
if (HAVE_C_${flagname})
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${flag}")
endif ()
check_cxx_compiler_flag("${flag}" HAVE_CXX_${flagname})
if (HAVE_CXX_${flagname})
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${flag}")
endif ()
endmacro(set_cflags_if_supported_named)
## adds a compiler flag if the compiler supports it ## adds a compiler flag if the compiler supports it
macro(set_cflags_if_supported) macro(set_cflags_if_supported)
foreach(flag ${ARGN}) foreach(flag ${ARGN})
...@@ -64,7 +76,16 @@ endmacro(set_ldflags_if_supported) ...@@ -64,7 +76,16 @@ endmacro(set_ldflags_if_supported)
set_cflags_if_supported( set_cflags_if_supported(
-Wno-missing-field-initializers -Wno-missing-field-initializers
-Wno-error=strict-overflow -Wno-error=strict-overflow
-Wstrict-null-sentinel
-Winit-self
-Wswitch
-Wtrampolines
-Wlogical-op
-Wmissing-format-attribute
-Wno-error=missing-format-attribute
-Wpacked
) )
set_cflags_if_supported_named("-Weffc++" -Weffcpp)
set_ldflags_if_supported( set_ldflags_if_supported(
-Wno-error=strict-overflow -Wno-error=strict-overflow
) )
......
...@@ -48,45 +48,55 @@ ...@@ -48,45 +48,55 @@
// LE_CLEAN means that there is a single committed value in a format that saves disk space // LE_CLEAN means that there is a single committed value in a format that saves disk space
// LE_MVCC means that there may be multiple committed values or there are provisional values // LE_MVCC means that there may be multiple committed values or there are provisional values
// //
enum { LE_CLEAN = 0, LE_MVCC = 1 }; enum { LE_CLEAN = 0, LE_MVCC = 1 };
// This is an on-disk format. static_asserts verify everything is packed and aligned correctly.
struct __attribute__ ((__packed__)) leafentry { struct __attribute__ ((__packed__)) leafentry {
struct leafentry_clean {
uint32_t vallen;
uint8_t key_val[0]; //Actual key, then actual val
}; // For the case where LEAFENTRY->type is LE_CLEAN
static_assert(4 == sizeof(leafentry::leafentry_clean), "leafentry_clean size is wrong");
static_assert(4 == __builtin_offsetof(leafentry::leafentry_clean, key_val), "key_val is in the wrong place");
struct __attribute__ ((__packed__)) leafentry_mvcc {
uint32_t num_cxrs; // number of committed transaction records
uint8_t num_pxrs; // number of provisional transaction records
u_int8_t key_xrs[0]; //Actual key,
//then TXNIDs of XRs relevant for reads:
// if provisional XRs exist, store OUTERMOST TXNID
// store committed TXNIDs, from most recently committed to least recently committed (newest first)
//then lengths of XRs relevant for reads (length is at most 1<<31, MSB is 1 for insert, 0 for delete):
// if provisional XRs exist (num_pxrs>0), store length and insert/delete flag associated with INNERMOST TXNID
// store length and insert/delete flag associated with each committed TXNID, in same order as above (newest first)
//then data of XRs relevant for reads
// if provisional XRs exist (num_pxrs>0), store data associated with INNERMOST provisional TXNID
// store data associated with committed TXNIDs (all committed data, newest committed values first)
//if provisional XRs still exist (that is, num_puxrs > 1, so INNERMOST provisional TXNID != OUTERMOST provisional TXNID):
// for OUTERMOST provisional XR:
// 1 byte: store type (insert/delete/placeholder)
// 4 bytes: length (if type is INSERT, no length stored if placeholder or delete)
// data
// for rest of provisional stack (if num_pxrs > 2), from second-outermost to second-innermost (outermost is stored above, innermost is stored separately):
// 8 bytes: TXNID
// 1 byte: store type (insert/delete/placeholder)
// 4 bytes: length (if type is INSERT)
// data
// for INNERMOST provisional XR:
// 8 bytes: TXNID
// (innermost data and length with insert/delete flag are stored above, cannot be a placeholder)
}; // For the case where LEAFENTRY->type is LE_MVCC
static_assert(5 == sizeof(leafentry::leafentry_mvcc), "leafentry_mvcc size is wrong");
static_assert(5 == __builtin_offsetof(leafentry::leafentry_mvcc, key_xrs), "key_xrs is in the wrong place");
uint8_t type; // type is LE_CLEAN or LE_MVCC uint8_t type; // type is LE_CLEAN or LE_MVCC
uint32_t keylen; uint32_t keylen;
union { union __attribute__ ((__packed__)) {
struct __attribute__ ((__packed__)) leafentry_clean { struct leafentry_clean clean;
uint32_t vallen; struct leafentry_mvcc mvcc;
uint8_t key_val[0]; //Actual key, then actual val
} clean; // For the case where LEAFENTRY->type is LE_CLEAN
struct __attribute__ ((__packed__)) leafentry_mvcc {
uint32_t num_cxrs; // number of committed transaction records
uint8_t num_pxrs; // number of provisional transaction records
u_int8_t key_xrs[0]; //Actual key,
//then TXNIDs of XRs relevant for reads:
// if provisional XRs exist, store OUTERMOST TXNID
// store committed TXNIDs, from most recently committed to least recently committed (newest first)
//then lengths of XRs relevant for reads (length is at most 1<<31, MSB is 1 for insert, 0 for delete):
// if provisional XRs exist (num_pxrs>0), store length and insert/delete flag associated with INNERMOST TXNID
// store length and insert/delete flag associated with each committed TXNID, in same order as above (newest first)
//then data of XRs relevant for reads
// if provisional XRs exist (num_pxrs>0), store data associated with INNERMOST provisional TXNID
// store data associated with committed TXNIDs (all committed data, newest committed values first)
//if provisional XRs still exist (that is, num_puxrs > 1, so INNERMOST provisional TXNID != OUTERMOST provisional TXNID):
// for OUTERMOST provisional XR:
// 1 byte: store type (insert/delete/placeholder)
// 4 bytes: length (if type is INSERT, no length stored if placeholder or delete)
// data
// for rest of provisional stack (if num_pxrs > 2), from second-outermost to second-innermost (outermost is stored above, innermost is stored separately):
// 8 bytes: TXNID
// 1 byte: store type (insert/delete/placeholder)
// 4 bytes: length (if type is INSERT)
// data
// for INNERMOST provisional XR:
// 8 bytes: TXNID
// (innermost data and length with insert/delete flag are stored above, cannot be a placeholder)
} mvcc; // For the case where LEAFENTRY->type is LE_MVCC
} u; } u;
}; };
static_assert(10 == sizeof(leafentry), "leafentry size is wrong");
static_assert(5 == __builtin_offsetof(leafentry, u), "union is in the wrong place");
#if TOKU_WINDOWS #if TOKU_WINDOWS
#pragma pack(pop) #pragma pack(pop)
#endif #endif
......
...@@ -2152,23 +2152,33 @@ le_committed_mvcc(uint8_t *key, uint32_t keylen, ...@@ -2152,23 +2152,33 @@ le_committed_mvcc(uint8_t *key, uint32_t keylen,
#if TOKU_WINDOWS #if TOKU_WINDOWS
#pragma pack(push, 1) #pragma pack(push, 1)
#endif #endif
// This is an on-disk format. static_asserts verify everything is packed and aligned correctly.
struct __attribute__ ((__packed__)) leafentry_13 { struct __attribute__ ((__packed__)) leafentry_13 {
struct leafentry_committed_13 {
u_int8_t key_val[0]; //Actual key, then actual val
};
static_assert(0 == sizeof(leafentry_committed_13), "wrong size");
static_assert(0 == __builtin_offsetof(leafentry_committed_13, key_val), "wrong offset");
struct __attribute__ ((__packed__)) leafentry_provisional_13 {
u_int8_t innermost_type;
TXNID xid_outermost_uncommitted;
u_int8_t key_val_xrs[0]; //Actual key,
//then actual innermost inserted val,
//then transaction records.
};
static_assert(9 == sizeof(leafentry_provisional_13), "wrong size");
static_assert(9 == __builtin_offsetof(leafentry_provisional_13, key_val_xrs), "wrong offset");
u_int8_t num_xrs; u_int8_t num_xrs;
u_int32_t keylen; u_int32_t keylen;
u_int32_t innermost_inserted_vallen; u_int32_t innermost_inserted_vallen;
union { union __attribute__ ((__packed__)) {
struct __attribute__ ((__packed__)) leafentry_committed_13 { struct leafentry_committed_13 comm;
u_int8_t key_val[0]; //Actual key, then actual val struct leafentry_provisional_13 prov;
} comm;
struct __attribute__ ((__packed__)) leafentry_provisional_13 {
u_int8_t innermost_type;
TXNID xid_outermost_uncommitted;
u_int8_t key_val_xrs[]; //Actual key,
//then actual innermost inserted val,
//then transaction records.
} prov;
} u; } u;
}; };
static_assert(18 == sizeof(leafentry_13), "wrong size");
static_assert(9 == __builtin_offsetof(leafentry_13, u), "wrong offset");
#if TOKU_WINDOWS #if TOKU_WINDOWS
#pragma pack(pop) #pragma pack(pop)
#endif #endif
......
...@@ -75,6 +75,7 @@ typedef int64_t toku_off_t; ...@@ -75,6 +75,7 @@ typedef int64_t toku_off_t;
#include <sys/time.h> #include <sys/time.h>
#include <stdio.h> #include <stdio.h>
#define static_assert(foo, bar)
#endif #endif
#if defined(__cplusplus) || defined(__cilkplusplus) #if defined(__cplusplus) || defined(__cilkplusplus)
...@@ -98,6 +99,9 @@ typedef int64_t toku_off_t; ...@@ -98,6 +99,9 @@ typedef int64_t toku_off_t;
#include <stdarg.h> #include <stdarg.h>
#endif #endif
#include <alloca.h> #include <alloca.h>
#if defined(__cplusplus) || defined(__cilkplusplus)
# include <type_traits>
#endif
#if defined(__cplusplus) || defined(__cilkplusplus) #if defined(__cplusplus) || defined(__cilkplusplus)
# define cast_to_typeof(v) (decltype(v)) # define cast_to_typeof(v) (decltype(v))
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment