1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106
// Copyright 2021 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
use crate::writer::private::InspectTypeInternal;
use crate::writer::{Error, InnerType, State};
use inspect_format::BlockIndex;
/// Trait implemented by properties.
pub trait Property<'t>: InspectTypeInternal {
/// The type of the property.
type Type;
/// Set the property value to |value|.
fn set(&self, value: Self::Type);
/// Takes a function to execute as under a single lock of the Inspect VMO. This function
/// receives a reference to the `Property` on which it is called.
fn atomic_update<R, F: FnOnce(&Self) -> R>(&self, update_fn: F) -> R {
self.atomic_access(update_fn)
}
}
/// Trait implemented by numeric properties providing common operations.
pub trait NumericProperty<'t>: Property<'t> {
/// Add the given |value| to the property current value.
fn add(&self, value: <Self as Property<'t>>::Type) -> Option<<Self as Property<'t>>::Type>;
/// Subtract the given |value| from the property current value.
fn subtract(&self, value: <Self as Property<'t>>::Type)
-> Option<<Self as Property<'t>>::Type>;
}
/// Get the usable length of a type.
pub trait Length {
fn len(&self) -> Option<usize>;
fn is_empty(&self) -> Option<bool> {
self.len().map(|s| s == 0)
}
}
impl<T: ArrayProperty + InspectTypeInternal> Length for T {
fn len(&self) -> Option<usize> {
if let Ok(state) = self.state()?.try_lock() {
if let Ok(size) = state.get_array_size(self.block_index()?) {
return Some(size);
}
}
None
}
}
/// Trait implemented by all array properties providing common operations on arrays.
pub trait ArrayProperty: Length + InspectTypeInternal {
/// The type of the array entries.
type Type;
/// Sets the array value to `value` at the given `index`.
fn set(&self, index: usize, value: impl Into<Self::Type>);
/// Sets all slots of the array to 0 and releases any references.
fn clear(&self);
/// Takes a function to execute as under a single lock of the Inspect VMO. This function
/// receives a reference to the `ArrayProperty` on which it is called.
fn atomic_update<R, F: FnOnce(&Self) -> R>(&self, update_fn: F) -> R {
self.atomic_access(update_fn)
}
}
pub trait ArithmeticArrayProperty: ArrayProperty {
/// Adds the given `value` to the property current value at the given `index`.
fn add(&self, index: usize, value: Self::Type);
/// Subtracts the given `value` to the property current value at the given `index`.
fn subtract(&self, index: usize, value: Self::Type);
}
/// Trait implemented by all histogram properties providing common operations.
pub trait HistogramProperty {
/// The type of each value added to the histogram.
type Type;
/// Inserts the given `value` in the histogram.
fn insert(&self, value: Self::Type);
/// Inserts the given `value` in the histogram `count` times.
fn insert_multiple(&self, value: Self::Type, count: usize);
/// Clears all buckets of the histogram.
fn clear(&self);
}
#[derive(Default, Debug)]
pub(crate) struct InnerPropertyType;
impl InnerType for InnerPropertyType {
type Data = ();
fn free(state: &State, _: &Self::Data, block_index: BlockIndex) -> Result<(), Error> {
let mut state_lock = state.try_lock()?;
state_lock
.free_property(block_index)
.map_err(|err| Error::free("property", block_index, err))
}
}