use std::mem;
use std::sync::atomic::AtomicI32;
use std::sync::atomic::AtomicI64;
use std::sync::atomic::Ordering;
use std::sync::Arc;
use bytes::Buf;
use bytes::Bytes;
use crate::log_file::mapped_file::default_mapped_file_impl::DefaultMappedFile;
use crate::log_file::mapped_file::MappedFile;
pub const INDEX_HEADER_SIZE: usize = 40;
const BEGIN_TIMESTAMP_INDEX: usize = 0;
const END_TIMESTAMP_INDEX: usize = 8;
const BEGIN_PHY_OFFSET_INDEX: usize = 16;
const END_PHY_OFFSET_INDEX: usize = 24;
const HASH_SLOT_COUNT_INDEX: usize = 32;
const INDEX_COUNT_INDEX: usize = 36;
pub struct IndexHeader {
mapped_file: Arc<DefaultMappedFile>,
begin_timestamp: AtomicI64,
end_timestamp: AtomicI64,
begin_phy_offset: AtomicI64,
end_phy_offset: AtomicI64,
hash_slot_count: AtomicI32,
index_count: AtomicI32,
}
impl IndexHeader {
#[inline]
pub fn new(mapped_file: Arc<DefaultMappedFile>) -> Self {
Self {
mapped_file,
begin_timestamp: AtomicI64::new(0),
end_timestamp: AtomicI64::new(0),
begin_phy_offset: AtomicI64::new(0),
end_phy_offset: AtomicI64::new(0),
hash_slot_count: AtomicI32::new(0),
index_count: AtomicI32::new(1),
}
}
#[inline]
pub fn load(&self) {
let mut buffer = self.mapped_file.get_bytes(0, INDEX_HEADER_SIZE).unwrap();
self.begin_timestamp
.store(buffer.get_i64(), Ordering::SeqCst);
self.end_timestamp.store(buffer.get_i64(), Ordering::SeqCst);
self.begin_phy_offset
.store(buffer.get_i64(), Ordering::SeqCst);
self.end_phy_offset
.store(buffer.get_i64(), Ordering::SeqCst);
self.hash_slot_count
.store(buffer.get_i32(), Ordering::SeqCst);
self.index_count.store(buffer.get_i32(), Ordering::SeqCst);
if self.index_count.load(Ordering::SeqCst) <= 0 {
self.index_count.store(1, Ordering::SeqCst);
}
}
#[inline]
pub fn update_byte_buffer(&self) {
self.mapped_file.put_slice(
&self.begin_timestamp.load(Ordering::SeqCst).to_be_bytes(),
BEGIN_TIMESTAMP_INDEX,
);
self.mapped_file.put_slice(
&self.end_timestamp.load(Ordering::SeqCst).to_be_bytes(),
END_TIMESTAMP_INDEX,
);
self.mapped_file.put_slice(
&self.begin_phy_offset.load(Ordering::SeqCst).to_be_bytes(),
BEGIN_PHY_OFFSET_INDEX,
);
self.mapped_file.put_slice(
&self.end_phy_offset.load(Ordering::SeqCst).to_be_bytes(),
END_PHY_OFFSET_INDEX,
);
self.mapped_file.put_slice(
&self.hash_slot_count.load(Ordering::SeqCst).to_be_bytes(),
HASH_SLOT_COUNT_INDEX,
);
self.mapped_file.put_slice(
&self.index_count.load(Ordering::SeqCst).to_be_bytes(),
INDEX_COUNT_INDEX,
);
}
#[inline]
pub fn get_begin_timestamp(&self) -> i64 {
self.begin_timestamp.load(Ordering::SeqCst)
}
#[inline]
pub fn set_begin_timestamp(&self, begin_timestamp: i64) {
self.begin_timestamp
.store(begin_timestamp, Ordering::SeqCst);
self.mapped_file.append_message_offset_length(
&Bytes::copy_from_slice(&self.begin_timestamp.load(Ordering::SeqCst).to_be_bytes()),
BEGIN_TIMESTAMP_INDEX,
mem::size_of::<i64>(),
);
}
#[inline]
pub fn get_end_timestamp(&self) -> i64 {
self.end_timestamp.load(Ordering::SeqCst)
}
#[inline]
pub fn set_end_timestamp(&self, end_timestamp: i64) {
self.end_timestamp.store(end_timestamp, Ordering::SeqCst);
self.mapped_file.append_message_offset_length(
&Bytes::copy_from_slice(&self.end_timestamp.load(Ordering::SeqCst).to_be_bytes()),
END_TIMESTAMP_INDEX,
mem::size_of::<i64>(),
);
}
#[inline]
pub fn get_begin_phy_offset(&self) -> i64 {
self.begin_phy_offset.load(Ordering::SeqCst)
}
#[inline]
pub fn set_begin_phy_offset(&self, begin_phy_offset: i64) {
self.begin_phy_offset
.store(begin_phy_offset, Ordering::SeqCst);
self.mapped_file.append_message_offset_length(
&Bytes::copy_from_slice(&self.begin_phy_offset.load(Ordering::SeqCst).to_be_bytes()),
BEGIN_PHY_OFFSET_INDEX,
mem::size_of::<i64>(),
);
}
#[inline]
pub fn get_end_phy_offset(&self) -> i64 {
self.end_phy_offset.load(Ordering::SeqCst)
}
#[inline]
pub fn set_end_phy_offset(&self, end_phy_offset: i64) {
self.end_phy_offset.store(end_phy_offset, Ordering::SeqCst);
self.mapped_file.append_message_offset_length(
&Bytes::copy_from_slice(&self.end_phy_offset.load(Ordering::SeqCst).to_be_bytes()),
END_PHY_OFFSET_INDEX,
mem::size_of::<i64>(),
);
}
#[inline]
pub fn get_hash_slot_count(&self) -> i32 {
self.hash_slot_count.load(Ordering::SeqCst)
}
#[inline]
pub fn inc_hash_slot_count(&self) {
self.hash_slot_count.fetch_add(1, Ordering::SeqCst);
self.mapped_file.append_message_offset_length(
&Bytes::copy_from_slice(&self.hash_slot_count.load(Ordering::SeqCst).to_be_bytes()),
HASH_SLOT_COUNT_INDEX,
mem::size_of::<i32>(),
);
}
#[inline]
pub fn get_index_count(&self) -> i32 {
self.index_count.load(Ordering::SeqCst)
}
#[inline]
pub fn inc_index_count(&self) {
self.index_count.fetch_add(1, Ordering::SeqCst);
self.mapped_file.append_message_offset_length(
&Bytes::copy_from_slice(&self.index_count.load(Ordering::SeqCst).to_be_bytes()),
INDEX_COUNT_INDEX,
mem::size_of::<i32>(),
);
}
}