Autonomy Software C++ 24.5.1
Welcome to the Autonomy Software repository of the Mars Rover Design Team (MRDT) at Missouri University of Science and Technology (Missouri S&T)! API reference contains the source code and other resources for the development of the autonomy software for our Mars rover. The Autonomy Software project aims to compete in the University Rover Challenge (URC) by demonstrating advanced autonomous capabilities and robust navigation algorithms.
Loading...
Searching...
No Matches
duckdb::BignumIntermediate Struct Reference

Public Member Functions

 BignumIntermediate (const bignum_t &value)
 
 BignumIntermediate (uint8_t *value, idx_t size)
 
void Print () const
 
AbsoluteNumberComparison IsAbsoluteBigger (const BignumIntermediate &rhs) const
 
uint8_t GetAbsoluteByte (int64_t index) const
 Get the absolute value of a byte.
 
bool IsMSBSet () const
 If the most significant bit of the first byte is set.
 
void Initialize (ArenaAllocator &allocator)
 Initializes our bignum to 0 and 1 byte.
 
void Reallocate (ArenaAllocator &allocator, idx_t min_size)
 If necessary, we reallocate our intermediate to the next power of 2.
 
uint32_t GetStartDataPos () const
 
void Trim ()
 
void AddInPlace (ArenaAllocator &allocator, const BignumIntermediate &rhs)
 Add a BignumIntermediate to another BignumIntermediate, equivalent of a +=.
 
string_t Negate (Vector &result_vector) const
 Negates a value, e.g., -x.
 
void NegateInPlace ()
 
bignum_t ToBignum (ArenaAllocator &allocator)
 Exports to a bignum, either arena allocated.
 
bool OverOrUnderflow () const
 

Static Public Member Functions

static uint32_t GetStartDataPos (data_ptr_t data, idx_t size, bool is_negative)
 
static idx_t Trim (data_ptr_t data, uint32_t &size, bool is_negative)
 In case we have unnecessary extra 0's or 1's in our bignum we trim them.
 
static string_t Add (Vector &result, const BignumIntermediate &lhs, const BignumIntermediate &rhs)
 Adds two BignumIntermediates and returns a string_t result, equivalent of a +.
 
static bool OverOrUnderflow (data_ptr_t data, idx_t size, bool is_negative)
 Check if an over/underflow has occurred.
 

Public Attributes

bool is_negative
 Information on the header.
 
uint32_t size
 
data_ptr_t data
 The actual data.
 

Constructor & Destructor Documentation

◆ BignumIntermediate() [1/3]

duckdb::BignumIntermediate::BignumIntermediate ( )
inline
46445: is_negative(false), size(0), data(nullptr) {};
bool is_negative
Information on the header.
Definition duckdb.cpp:46450
data_ptr_t data
The actual data.
Definition duckdb.cpp:46453

◆ BignumIntermediate() [2/3]

duckdb::BignumIntermediate::BignumIntermediate ( const bignum_t value)
explicit
46682 {
46683 is_negative = (value.data.GetData()[0] & 0x80) == 0;
46684 data = reinterpret_cast<data_ptr_t>(value.data.GetDataWriteable() + Bignum::BIGNUM_HEADER_SIZE);
46685 size = static_cast<uint32_t>(value.data.GetSize()) - Bignum::BIGNUM_HEADER_SIZE;
46686}
static DUCKDB_API constexpr uint8_t BIGNUM_HEADER_SIZE
Header size of a Bignum is always 3 bytes.
Definition duckdb.cpp:46515
::uint32_t uint32_t

◆ BignumIntermediate() [3/3]

duckdb::BignumIntermediate::BignumIntermediate ( uint8_t value,
idx_t  size 
)
46688 {
46689 is_negative = (value[0] & 0x80) == 0;
46691 size = static_cast<uint32_t>(ptr_size) - Bignum::BIGNUM_HEADER_SIZE;
46692}

Member Function Documentation

◆ Print()

void duckdb::BignumIntermediate::Print ( ) const
46671 {
46672 string result;
46673 for (idx_t i = 0; i < size; ++i) {
46674 for (int j = 7; j >= 0; --j) {
46675 result += to_string((data[i] >> j) & 1);
46676 }
46677 result += " ";
46678 }
46679 Printer::Print(OutputStream::STREAM_STDOUT, result);
46680}
static DUCKDB_API void Print(OutputStream stream, const string &str)
Print the object to the stream.

◆ IsAbsoluteBigger()

AbsoluteNumberComparison duckdb::BignumIntermediate::IsAbsoluteBigger ( const BignumIntermediate rhs) const

If the absolute number is bigger than the absolute rhs 1 = true, 0 = equal, -1 = false

46702 {
46703 idx_t actual_start_pos = GetStartDataPos();
46704 idx_t actual_size = size - actual_start_pos;
46705
46706 idx_t rhs_actual_start_pos = rhs.GetStartDataPos();
46707 idx_t rhs_actual_size = rhs.size - rhs_actual_start_pos;
46708
46709 // we have opposing signs, gotta do a bunch of checks to figure out who is the biggest
46710 // check sizes
46711 if (actual_size > rhs_actual_size) {
46712 return GREATER;
46713 }
46714 if (actual_size < rhs_actual_size) {
46715 return SMALLER;
46716 } else {
46717 // they have the same size then
46718 idx_t target_idx = actual_start_pos;
46719 idx_t source_idx = rhs_actual_start_pos;
46720 while (target_idx < size) {
46721 auto data_byte = GetAbsoluteByte(static_cast<int64_t>(target_idx));
46722 auto rhs_byte = rhs.GetAbsoluteByte(static_cast<int64_t>(source_idx));
46723 if (data_byte > rhs_byte) {
46724 return GREATER;
46725 } else if (data_byte < rhs_byte) {
46726 return SMALLER;
46727 }
46728 target_idx++;
46729 source_idx++;
46730 }
46731 }
46732 // If we got here, the values are equal.
46733 return EQUAL;
46734}
::int64_t int64_t
uint8_t GetAbsoluteByte(int64_t index) const
Get the absolute value of a byte.
Definition duckdb.cpp:46694
Here is the call graph for this function:
Here is the caller graph for this function:

◆ GetAbsoluteByte()

uint8_t duckdb::BignumIntermediate::GetAbsoluteByte ( int64_t  index) const

Get the absolute value of a byte.

46694 {
46695 if (index < 0) {
46696 // byte-extension
46697 return 0;
46698 }
46699 return is_negative ? static_cast<uint8_t>(~data[index]) : static_cast<uint8_t>(data[index]);
46700}
index
::uint8_t uint8_t
Here is the caller graph for this function:

◆ IsMSBSet()

bool duckdb::BignumIntermediate::IsMSBSet ( ) const

If the most significant bit of the first byte is set.

46736 {
46737 if (is_negative) {
46738 return (data[0] & 0x80) == 0;
46739 }
46740 return (data[0] & 0x80) != 0;
46741}
Here is the caller graph for this function:

◆ Initialize()

void duckdb::BignumIntermediate::Initialize ( ArenaAllocator allocator)

Initializes our bignum to 0 and 1 byte.

46742 {
46743 is_negative = false;
46744 size = 1;
46745 data = allocator.Allocate(size);
46746 // initialize the data
46747 data[0] = 0;
46748}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ Reallocate()

void duckdb::BignumIntermediate::Reallocate ( ArenaAllocator allocator,
idx_t  min_size 
)

If necessary, we reallocate our intermediate to the next power of 2.

46767 {
46768 if (min_size < size) {
46769 return;
46770 }
46771 uint32_t new_size = size;
46772 while (new_size <= min_size) {
46773 new_size *= 2;
46774 }
46775 auto new_data = allocator.Allocate(new_size);
46776 // Then we initialize to 0's until we have valid data again
46777 memset(new_data, is_negative ? 0xFF : 0x00, new_size - size);
46778 // Copy the old data to the new data
46779 memcpy(new_data + new_size - size, data, size);
46780 // Set size and pointer
46781 data = new_data;
46782 size = new_size;
46783}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ GetStartDataPos() [1/2]

uint32_t duckdb::BignumIntermediate::GetStartDataPos ( data_ptr_t  data,
idx_t  size,
bool  is_negative 
)
static
46750 {
46751 uint8_t non_initialized = is_negative ? 0xFF : 0x00;
46752 uint32_t actual_start = 0;
46753 for (idx_t i = 0; i < size; ++i) {
46754 if (data[i] == non_initialized) {
46755 actual_start++;
46756 } else {
46757 break;
46758 }
46759 }
46760 return actual_start;
46761}

◆ GetStartDataPos() [2/2]

uint32_t duckdb::BignumIntermediate::GetStartDataPos ( ) const
46763 {
46764 return GetStartDataPos(data, size, is_negative);
46765}

◆ Trim() [1/2]

idx_t duckdb::BignumIntermediate::Trim ( data_ptr_t  data,
uint32_t size,
bool  is_negative 
)
static

In case we have unnecessary extra 0's or 1's in our bignum we trim them.

46785 {
46786 auto actual_start = GetStartDataPos(data, size, is_negative);
46787 if (actual_start == 0) {
46788 return 0;
46789 }
46790 // This bad-boy is wearing shoe lifts, time to prune it.
46791 D_ASSERT(actual_start <= size);
46792 size -= actual_start;
46793 if (size == 0) {
46794 // Always keep at least one byte
46795 actual_start = 0;
46796 size++;
46797 }
46798 memmove(data, data + actual_start, size);
46799 return actual_start;
46800}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ Trim() [2/2]

void duckdb::BignumIntermediate::Trim ( )
46802 {
46803 Trim(data, size, is_negative);
46804}
static idx_t Trim(data_ptr_t data, uint32_t &size, bool is_negative)
In case we have unnecessary extra 0's or 1's in our bignum we trim them.
Definition duckdb.cpp:46785

◆ AddInPlace()

void duckdb::BignumIntermediate::AddInPlace ( ArenaAllocator allocator,
const BignumIntermediate rhs 
)

Add a BignumIntermediate to another BignumIntermediate, equivalent of a +=.

46980 {
46981 const bool same_sign = is_negative == rhs.is_negative;
46982 idx_t actual_size = size - GetStartDataPos();
46983 idx_t actual_rhs_size = rhs.size - rhs.GetStartDataPos();
46984 if (actual_size < actual_rhs_size || (same_sign && (IsMSBSet() || (rhs.IsMSBSet() && size == rhs.size)))) {
46985 // We must reallocate
46986 idx_t min_size = actual_size < actual_rhs_size ? actual_rhs_size + 1 : size + 1;
46987 Reallocate(allocator, min_size);
46988 }
46989 bool is_target_absolute_bigger = true;
46990 if (rhs.is_negative != is_negative) {
46991 auto is_absolute_bigger = IsAbsoluteBigger(rhs);
46992 if (is_absolute_bigger == EQUAL) {
46993 // We set this value to 0
46994 *this = BignumIntermediate();
46995 Initialize(allocator);
46996 return;
46997 } else if (is_absolute_bigger == SMALLER) {
46998 is_target_absolute_bigger = false;
46999 }
47000 }
47001
47002 bool is_result_negative = is_target_absolute_bigger ? is_negative : rhs.is_negative;
47003 BignumAddition(data, size, is_target_absolute_bigger, *this, rhs);
47004 if (is_result_negative != is_negative) {
47005 is_negative = is_result_negative;
47006 }
47007 if (OverOrUnderflow()) {
47008 // We must throw an error, usually we should print the numbers, but I have a feeling that it won't be possible
47009 // here.
47010 throw OutOfRangeException(ProduceOverUnderFlowError(is_result_negative, GetStartDataPos(), size));
47011 }
47012}
bool IsMSBSet() const
If the most significant bit of the first byte is set.
Definition duckdb.cpp:46736
static bool OverOrUnderflow(data_ptr_t data, idx_t size, bool is_negative)
Check if an over/underflow has occurred.
Definition duckdb.cpp:46806
void Reallocate(ArenaAllocator &allocator, idx_t min_size)
If necessary, we reallocate our intermediate to the next power of 2.
Definition duckdb.cpp:46767
void Initialize(ArenaAllocator &allocator)
Initializes our bignum to 0 and 1 byte.
Definition duckdb.cpp:46742
AbsoluteNumberComparison IsAbsoluteBigger(const BignumIntermediate &rhs) const
Definition duckdb.cpp:46702
Here is the call graph for this function:

◆ Add()

string_t duckdb::BignumIntermediate::Add ( Vector result,
const BignumIntermediate lhs,
const BignumIntermediate rhs 
)
static

Adds two BignumIntermediates and returns a string_t result, equivalent of a +.

46933 {
46934 const bool same_sign = lhs.is_negative == rhs.is_negative;
46935 const uint32_t actual_size = lhs.size - lhs.GetStartDataPos();
46936 const uint32_t actual_rhs_size = rhs.size - rhs.GetStartDataPos();
46937 uint32_t result_size = actual_size;
46938 if (actual_size < actual_rhs_size || (same_sign && (lhs.IsMSBSet() || (rhs.IsMSBSet() && lhs.size == rhs.size)))) {
46939 result_size = actual_size < actual_rhs_size ? actual_rhs_size + 1 : actual_size + 1;
46940 }
46941 bool is_target_absolute_bigger = true;
46942 if (result_size == 0) {
46943 result_size++;
46944 }
46945 result_size += Bignum::BIGNUM_HEADER_SIZE;
46946 if (lhs.is_negative != rhs.is_negative) {
46947 auto is_absolute_bigger = lhs.IsAbsoluteBigger(rhs);
46948 if (is_absolute_bigger == EQUAL) {
46949 // We set this value to 0
46950 auto target = StringVector::EmptyString(result_vector, result_size);
46951 auto target_data = target.GetDataWriteable();
46952 Bignum::SetHeader(target_data, 1, false);
46953 target_data[Bignum::BIGNUM_HEADER_SIZE] = 0;
46954 target.SetSizeAndFinalize(1 + Bignum::BIGNUM_HEADER_SIZE, result_size);
46955 return target;
46956
46957 } else if (is_absolute_bigger == SMALLER) {
46958 is_target_absolute_bigger = false;
46959 }
46960 }
46961
46962 auto target = StringVector::EmptyString(result_vector, result_size);
46963 auto result_size_data = result_size - Bignum::BIGNUM_HEADER_SIZE;
46964
46965 auto target_data = target.GetDataWriteable();
46966 BignumAddition(reinterpret_cast<data_ptr_t>(target_data + Bignum::BIGNUM_HEADER_SIZE), result_size_data,
46967 is_target_absolute_bigger, lhs, rhs);
46968 bool is_result_negative = is_target_absolute_bigger ? lhs.is_negative : rhs.is_negative;
46969 if (OverOrUnderflow(reinterpret_cast<data_ptr_t>(target_data + Bignum::BIGNUM_HEADER_SIZE), result_size_data,
46970 is_result_negative)) {
46971 auto actual_start = GetStartDataPos(reinterpret_cast<data_ptr_t>(target_data + Bignum::BIGNUM_HEADER_SIZE),
46972 result_size_data, is_result_negative);
46973 throw OutOfRangeException(ProduceOverUnderFlowError(is_result_negative, actual_start, result_size_data));
46974 }
46975 Trim(reinterpret_cast<data_ptr_t>(target_data + Bignum::BIGNUM_HEADER_SIZE), result_size_data, is_result_negative);
46976 Bignum::SetHeader(target_data, result_size_data, is_result_negative);
46977 target.SetSizeAndFinalize(result_size_data + Bignum::BIGNUM_HEADER_SIZE, result_size);
46978 return target;
46979}
static DUCKDB_API void SetHeader(char *blob, uint64_t number_of_bytes, bool is_negative)
static DUCKDB_API string_t EmptyString(Vector &vector, idx_t len)
Here is the call graph for this function:

◆ Negate()

string_t duckdb::BignumIntermediate::Negate ( Vector result_vector) const

Negates a value, e.g., -x.

46886 {
46887 auto target = StringVector::EmptyString(result_vector, size + Bignum::BIGNUM_HEADER_SIZE);
46888 auto ptr = target.GetDataWriteable();
46889
46890 if (!is_negative && size == 1 && data[0] == 0x00) {
46891 // If we have a zero, we just do a copy
46892 Bignum::SetHeader(ptr, size, is_negative);
46893 for (idx_t i = 0; i < size; ++i) {
46894 ptr[i + Bignum::BIGNUM_HEADER_SIZE] = static_cast<char>(data[i]);
46895 }
46896 } else {
46897 // Otherwise, we set the header with a flip on the signal
46898 Bignum::SetHeader(ptr, size, !is_negative);
46899 for (idx_t i = 0; i < size; ++i) {
46900 // And flip all the data bits
46901 ptr[i + Bignum::BIGNUM_HEADER_SIZE] = static_cast<char>(~data[i]);
46902 }
46903 }
46904
46905 return target;
46906}
Here is the call graph for this function:

◆ NegateInPlace()

void duckdb::BignumIntermediate::NegateInPlace ( )
46908 {
46909 if (!is_negative && size == 1 && data[0] == 0x00) {
46910 // this is a zero, there is no negation
46911 return;
46912 }
46914 for (size_t i = 0; i < size; i++) {
46915 data[i] = ~data[i]; // flip each byte of the pointer
46916 }
46917}

◆ ToBignum()

bignum_t duckdb::BignumIntermediate::ToBignum ( ArenaAllocator allocator)

Exports to a bignum, either arena allocated.

46826 {
46827 // This must be trimmed before transforming
46828 Trim();
46829 bignum_t result;
46830 uint32_t bignum_size = Bignum::BIGNUM_HEADER_SIZE + size;
46831 auto ptr = reinterpret_cast<char *>(allocator.Allocate(bignum_size));
46832 // Set Header
46833 Bignum::SetHeader(ptr, size, is_negative);
46834 // Copy data
46835 memcpy(ptr + Bignum::BIGNUM_HEADER_SIZE, data, size);
46836 result.data = string_t(ptr, bignum_size);
46837 return result;
46838}
Here is the call graph for this function:

◆ OverOrUnderflow() [1/2]

bool duckdb::BignumIntermediate::OverOrUnderflow ( data_ptr_t  data,
idx_t  size,
bool  is_negative 
)
static

Check if an over/underflow has occurred.

46806 {
46807 if (size <= Bignum::MAX_DATA_SIZE) {
46808 return false;
46809 }
46810 // variable that stores a fully unset byte can safely be ignored
46811 uint8_t byte_to_compare = is_negative ? 0xFF : 0x00;
46812 // we will basically check if any byte has any set bit up to Bignum::MAX_DATA_SIZE, if so, that's an under/overflow
46813 idx_t data_pos = 0;
46814 for (idx_t i = size; i > Bignum::MAX_DATA_SIZE; i--) {
46815 if (data[data_pos++] != byte_to_compare) {
46816 return true;
46817 }
46818 }
46819 return false;
46820}
static DUCKDB_API constexpr uint32_t MAX_DATA_SIZE
Definition duckdb.cpp:46513
Here is the call graph for this function:
Here is the caller graph for this function:

◆ OverOrUnderflow() [2/2]

bool duckdb::BignumIntermediate::OverOrUnderflow ( ) const
46822 {
46823 return OverOrUnderflow(data, size, is_negative);
46824}

The documentation for this struct was generated from the following file: