Improve shifting by partial shifting on multiple operations

Signed-off-by: trivernis <trivernis@protonmail.com>
main
trivernis 4 years ago
parent 4842b9f346
commit 3f6063b24a
Signed by: Trivernis
GPG Key ID: DFFFCC2C7A02DB45

2
Cargo.lock generated

@ -307,7 +307,7 @@ dependencies = [
[[package]] [[package]]
name = "minecraft-regions-tool" name = "minecraft-regions-tool"
version = "0.5.1" version = "0.5.2"
dependencies = [ dependencies = [
"byteorder", "byteorder",
"colored", "colored",

@ -1,6 +1,6 @@
[package] [package]
name = "minecraft-regions-tool" name = "minecraft-regions-tool"
version = "0.5.1" version = "0.5.2"
authors = ["trivernis <trivernis@protonmail.com>"] authors = ["trivernis <trivernis@protonmail.com>"]
edition = "2018" edition = "2018"
license = "GPL-3.0" license = "GPL-3.0"

@ -96,11 +96,18 @@ impl RegionFile {
if options.fix || options.fix_delete { if options.fix || options.fix_delete {
let mut shifted = 0isize; let mut shifted = 0isize;
for (offset, amount) in shift_operations {
let offset = (offset as isize + shifted) as usize; let mut operations = shift_operations.iter().peekable();
self.shift_right(offset, amount)?; while let Some((offset, amount)) = operations.next() {
self.locations.shift_entries(offset as u32, amount as i32); shifted += *amount;
shifted += amount; let end_offset = if let Some((o, a)) = operations.peek() {
(*o as isize + *a) as usize
} else {
self.locations.max_offset() as usize
};
self.shift_right(*offset, end_offset, shifted)?;
self.locations
.shift_entries(*offset as u32, end_offset as u32, shifted as i32);
} }
statistic.shrunk_size = self.locations.estimated_size(); statistic.shrunk_size = self.locations.estimated_size();
self.writer.seek(SeekFrom::Start(0))?; self.writer.seek(SeekFrom::Start(0))?;
@ -181,16 +188,29 @@ impl RegionFile {
} }
/// Shifts the file from the `offset` position `amount` blocks to the right /// Shifts the file from the `offset` position `amount` blocks to the right
pub fn shift_right(&mut self, offset: usize, amount: isize) -> Result<()> { pub fn shift_right(
&mut self,
start_offset: usize,
end_offset: usize,
amount: isize,
) -> Result<()> {
log::debug!(
"Shifting chunk blocks starting from {} by {} until {}",
start_offset,
amount,
end_offset,
);
self.reader self.reader
.seek(SeekFrom::Start((offset * BLOCK_SIZE) as u64))?; .seek(SeekFrom::Start((start_offset * BLOCK_SIZE) as u64))?;
self.writer.seek(SeekFrom::Start( self.writer
((offset as isize + amount) as usize * BLOCK_SIZE) as u64, .seek(SeekFrom::Start((start_offset * BLOCK_SIZE) as u64))?;
))?; self.writer
loop { .seek(SeekFrom::Current(amount as i64 * BLOCK_SIZE as i64))?;
for _ in 0..(end_offset - start_offset) {
let mut buf = [0u8; BLOCK_SIZE]; let mut buf = [0u8; BLOCK_SIZE];
let read = self.reader.read(&mut buf)?; let read = self.reader.read(&mut buf)?;
self.writer.write(&buf)?; self.writer.write(&buf)?;
if read < BLOCK_SIZE { if read < BLOCK_SIZE {
break; break;
} }
@ -260,8 +280,8 @@ impl Locations {
.collect() .collect()
} }
/// Returns the estimated of all chunks combined including the header /// The maximum offset in the file
pub fn estimated_size(&self) -> u64 { pub fn max_offset(&self) -> u32 {
let largest = self let largest = self
.inner .inner
.iter() .iter()
@ -277,7 +297,12 @@ impl Locations {
.cloned() .cloned()
.unwrap_or((2, 0)); .unwrap_or((2, 0));
(largest.0 as u64 + largest.1 as u64) * BLOCK_SIZE as u64 largest.0 + largest.1 as u32
}
/// Returns the estimated of all chunks combined including the header
pub fn estimated_size(&self) -> u64 {
self.max_offset() as u64 * BLOCK_SIZE as u64
} }
/// Replaces an entry with a new one. Panics if the index doesn't exist /// Replaces an entry with a new one. Panics if the index doesn't exist
@ -296,11 +321,12 @@ impl Locations {
} }
/// Shifts all entries starting from `start_index` by `amount` /// Shifts all entries starting from `start_index` by `amount`
pub fn shift_entries(&mut self, start_offset: u32, amount: i32) { pub fn shift_entries(&mut self, start_offset: u32, end_offset: u32, amount: i32) {
log::debug!( log::debug!(
"Shifting location entries starting from {} by {}", "Shifting location entries starting from {} by {} until {}",
start_offset, start_offset,
amount amount,
end_offset
); );
self.inner = self self.inner = self
.inner .inner
@ -308,7 +334,7 @@ impl Locations {
.map(|e| { .map(|e| {
let mut entry = *e; let mut entry = *e;
if e.0 >= start_offset { if e.0 >= start_offset && e.0 <= end_offset {
entry.0 = (entry.0 as i32 + amount) as u32; entry.0 = (entry.0 as i32 + amount) as u32;
} }

Loading…
Cancel
Save