Benchmark Rust against pinned C# reference (#105)
Some checks failed
API and SemVer surface / api-surface (push) Failing after 1m8s
Native code generation / deterministic (push) Failing after 2m6s
Concurrency and resource soak audit / soak (push) Failing after 12m13s
Documentation / documentation (push) Failing after 1m36s
Imaging and meshing gate / native (push) Failing after 3m2s
JPEG 2000 feature / linux (push) Successful in 2m48s
performance evidence / audit (push) Failing after 13m49s
Release platform and feature matrix / audit (push) Successful in 44s
Native Rust workspace compile / compile (push) Failing after 55s
Skia feature / linux (push) Successful in 31m13s
Dependency and supply-chain audit / audit (push) Failing after 9m13s
Release platform and feature matrix / matrix (false, linux-stable-minimal, x86_64-unknown-linux-gnu, stable) (push) Failing after 9m49s
Release platform and feature matrix / matrix (false, windows-stable-portable, x86_64-pc-windows-gnu, stable) (push) Has been cancelled
Release platform and feature matrix / matrix (true, linux-msrv-portable, x86_64-unknown-linux-gnu, 1.96.0) (push) Has been cancelled
Release platform and feature matrix / matrix (true, linux-stable-default, x86_64-unknown-linux-gnu, stable) (push) Has been cancelled
Release platform and feature matrix / matrix (true, linux-stable-features, x86_64-unknown-linux-gnu, stable) (push) Has been cancelled
Release platform and feature matrix / matrix (true, linux-stable-release-surface, x86_64-unknown-linux-gnu, stable) (push) Has been cancelled
Release platform and feature matrix / matrix (false, macos-stable-portable, x86_64-apple-darwin, stable) (push) Has been cancelled

This commit is contained in:
2026-08-12 03:26:56 +00:00
parent b71386dc31
commit 738fe3933e
27 changed files with 4746 additions and 21 deletions

View File

@@ -1706,6 +1706,44 @@ impl Inventory {
let parent_uuid = value.base().parent_uuid;
let event = {
let mut state = write(&self.inner.state);
// Root-level records have no hierarchy edges or ancestor counts to
// rebuild. They are common during the initial flat inventory feed
// and for incremental item refreshes, so update their node and link
// index directly instead of walking and relocking the entire store.
// The general path below remains responsible for moves, folders,
// cycles, placeholder parents, and descendant counts.
let old_root_value = state
.items
.get(&uuid)
.and_then(InventoryNode::value)
.filter(|old| old.base().parent_uuid == UUID::zero());
if parent_uuid == UUID::zero()
&& (old_root_value.is_some() || !state.items.contains_key(&uuid))
{
if let Some(old) = old_root_value.as_ref() {
update_link_index(&mut state.links, uuid, old, false);
}
update_link_index(&mut state.links, uuid, &value, true);
let event = if let Some(node) = state.items.get(&uuid) {
let old = node.value();
node.set_value(value.clone());
old.map(|old| InventoryObjectUpdatedEventArgs::from_values(old, value.clone()))
} else {
state
.items
.insert(uuid, InventoryNode::from_value(value.clone()));
None
};
drop(state);
if let Some(event) = event {
self.inner.updated.emit(event);
} else {
self.inner
.added
.emit(InventoryObjectAddedEventArgs::from_value(value));
}
return Ok(());
}
if parent_uuid != UUID::zero() && !state.items.contains_key(&parent_uuid) {
let mut fake = InventoryFolder::new(parent_uuid)?;
fake.version = InventoryFolder::VERSION_UNKNOWN;
@@ -1865,6 +1903,28 @@ impl Inventory {
}
}
fn update_link_index(
links: &mut HashMap<UUID, HashSet<UUID>>,
uuid: UUID,
value: &InventoryValue,
insert: bool,
) {
let Some(item) = value.item() else {
return;
};
if !item.is_link().unwrap_or(false) || item.asset_uuid == UUID::zero() {
return;
}
if insert {
links.entry(item.asset_uuid).or_default().insert(uuid);
} else if let Some(records) = links.get_mut(&item.asset_uuid) {
records.remove(&uuid);
if records.is_empty() {
links.remove(&item.asset_uuid);
}
}
}
fn rebuild_indexes_and_counts(state: &mut InventoryState) {
state.links.clear();
let nodes: Vec<_> = state.items.values().cloned().collect();
@@ -2944,6 +3004,29 @@ mod tests {
assert_eq!(calls.load(Ordering::SeqCst), 1);
}
#[test]
fn root_item_fast_path_keeps_link_index_and_events_consistent() {
let (_client, inventory) = fixture();
let item_id = UUID::random().unwrap();
let first_target = UUID::random().unwrap();
let second_target = UUID::random().unwrap();
let mut item = InventoryItem::new_with_uuid(item_id).unwrap();
item.set_asset_type(AssetType::Link);
item.set_asset_uuid(first_target);
inventory.update_node_for(&item).unwrap();
assert_eq!(inventory.find_all_links(first_target).unwrap().len(), 1);
item.set_asset_uuid(second_target);
inventory.update_node_for(&item).unwrap();
assert!(inventory.find_all_links(first_target).unwrap().is_empty());
assert_eq!(inventory.find_all_links(second_target).unwrap().len(), 1);
item.set_asset_type(AssetType::Texture);
inventory.update_node_for(&item).unwrap();
assert!(inventory.find_all_links(second_target).unwrap().is_empty());
assert_eq!(inventory.count(), 1);
}
#[test]
fn system_folders_sort_first_and_are_discoverable() {
let (_client, mut inventory) = fixture();

View File

@@ -11,6 +11,16 @@ type TgaPalette = (usize, Vec<[u8; 4]>);
pub struct Targa;
impl Targa {
/// Decodes an in-memory TGA or DDS payload without copying it through the
/// compatibility stream boundary.
///
/// # Errors
///
/// Returns a typed error for oversized, malformed, or unsupported input.
pub fn decode_to_managed_image_with_bytes(data: &[u8]) -> Result<ManagedImage, Error> {
decode(data)
}
/// Decodes a TGA or DDS file into planar managed-image storage.
///
/// # Errors
@@ -185,6 +195,15 @@ fn decode_tga(bytes: &[u8]) -> Result<ManagedImage, Error> {
return Err(parse(18, "truncated TGA image ID"));
}
let palette = read_tga_palette(bytes, header, has_color_map, color_mapped, &mut position)?;
if !rle
&& !grayscale
&& palette.is_none()
&& matches!(depth, 24 | 32)
&& header[17] & 0x30 == 0x20
{
decode_plain_truecolor(bytes, position, pixels, pixel_bytes, depth, &mut image)?;
return Ok(image);
}
let mut decoded = 0;
while decoded < pixels {
let (count, repeated) = if rle {
@@ -238,6 +257,30 @@ fn decode_tga(bytes: &[u8]) -> Result<ManagedImage, Error> {
Ok(image)
}
fn decode_plain_truecolor(
bytes: &[u8],
position: usize,
pixels: usize,
pixel_bytes: usize,
depth: u8,
image: &mut ManagedImage,
) -> Result<(), Error> {
let byte_length = pixels.checked_mul(pixel_bytes).ok_or(Error::Argument)?;
let end = position.checked_add(byte_length).ok_or(Error::Argument)?;
let data = bytes
.get(position..end)
.ok_or_else(|| parse(position, "truncated TGA pixel data"))?;
for (target, pixel) in data.chunks_exact(pixel_bytes).enumerate() {
image.blue[target] = pixel[0];
image.green[target] = pixel[1];
image.red[target] = pixel[2];
if depth == 32 {
image.alpha[target] = pixel[3];
}
}
Ok(())
}
fn tga_channels(
grayscale: bool,
color_mapped: bool,

View File

@@ -0,0 +1,44 @@
use std::sync::Arc;
use libremetaverse::imaging::Targa;
use libremetaverse::{GridClient, Inventory, InventoryItem};
use libremetaverse_types::{AssetType, UUID};
#[test]
fn root_inventory_updates_preserve_link_index() {
let client = Arc::new(GridClient::new().expect("offline client"));
let inventory = Inventory::new_with_grid_client_uuid(client, UUID::zero()).expect("store");
let item_id = UUID::new_with_u_int64(1).expect("item UUID");
let first_target = UUID::new_with_u_int64(2).expect("first target");
let second_target = UUID::new_with_u_int64(3).expect("second target");
let mut item = InventoryItem::new_with_uuid(item_id).expect("item");
item.set_asset_type(AssetType::Link);
item.set_asset_uuid(first_target);
inventory.update_node_for(&item).expect("insert root link");
assert_eq!(inventory.find_all_links(first_target).unwrap().len(), 1);
item.set_asset_uuid(second_target);
inventory
.update_node_for(&item)
.expect("retarget root link");
assert!(inventory.find_all_links(first_target).unwrap().is_empty());
assert_eq!(inventory.find_all_links(second_target).unwrap().len(), 1);
item.set_asset_type(AssetType::Texture);
inventory.update_node_for(&item).expect("replace link");
assert!(inventory.find_all_links(second_target).unwrap().is_empty());
assert_eq!(inventory.count(), 1);
}
#[test]
fn borrowed_tga_fast_path_preserves_fixture_pixels() {
let bytes = include_bytes!("../../../benchmarks/fixtures/image.tga");
let image = Targa::decode_to_managed_image_with_bytes(bytes).expect("decode TGA fixture");
assert_eq!((image.width, image.height), (128, 128));
assert_eq!(image.red.len(), 128 * 128);
assert_eq!(
(&image.red[..4], &image.green[..4], &image.blue[..4]),
(&[0, 1, 2, 3][..], &[0, 3, 6, 9][..], &[0, 7, 14, 21][..])
);
assert!(image.alpha.iter().all(|value| *value == u8::MAX));
}