pub struct ItemFinder<'t, I> { /* private fields */ }
Expand description

In-memory index for efficient random-access to Items by index.

ItemFinder can be obtained via ItemInformation::finder. It starts out empty and must be populated by calling ItemFinder::update while iterating. There are two typedefs for easier use:

ItemFinder allocates all the memory it needs when it is first created. The footprint is directly proportional to the total number of types; see ItemInformation::len.

Time/space trade-off

The naïve approach is to store the position of each Item as they are covered in the stream. The cost is memory: namely one u32 per Item.

Compare this approach to an ItemFinder that stores the position of every Nth item. Memory requirements would be reduced by a factor of N in exchange for requiring an average of (N-1)/2 iterations per lookup. However, iteration is cheap sequential memory access, and spending less memory on ItemFinder means more of the data can fit in the cache, so this is likely a good trade-off for small-ish values of N.

ItemFinder is parameterized by shift which controls this trade-off as powers of two:

  • If shift is 0, ItemFinder stores 4 bytes per Item and always performs direct lookups.
  • If shift is 1, ItemFinder stores 2 bytes per Item and averages 0.5 iterations per lookup.
  • If shift is 2, ItemFinder stores 1 byte per Item and averages 1.5 iterations per lookup.
  • If shift is 3, ItemFinder stores 4 bits per Item and averages 3.5 iterations per lookup.
  • If shift is 4, ItemFinder stores 2 bits per Item and averages 7.5 iterations per lookup.
  • If shift is 5, ItemFinder stores 1 bit per Item and averages 15.5 iterations per lookup.

This list can continue but with rapidly diminishing returns. Iteration cost is proportional to item size, which varies, but typical numbers from a large program are:

  • 24% of items are 12 bytes
  • 34% of items are <= 16 bytes
  • 84% of items are <= 32 bytes

A shift of 2 or 3 is likely appropriate for most workloads. 500K items would require 1 MB or 500 KB of memory respectively, and lookups – though indirect – would still usually need only one or two 64-byte cache lines.

Implementations

Returns the highest index which is currently served by this ItemFinder.

When iterating through the stream, you shouldn’t need to consider this. Items only ever reference lower indexes. However, when loading items referenced by the symbols stream, this can be useful to check whether iteration is required.

Update this ItemFinder based on the current position of a ItemIter.

Do this each time you call .next(). See documentation of ItemInformation for an example.

Find an Item by its index.

Errors
  • Error::TypeNotFound(index) if you ask for an item that doesn’t exist.
  • Error::TypeNotIndexed(index, max_index) if you ask for an item that is known to exist but is not currently known by this ItemFinder.

Trait Implementations

Formats the value using the given formatter. Read more

Auto Trait Implementations

Blanket Implementations

Gets the TypeId of self. Read more

Immutably borrows from an owned value. Read more

Mutably borrows from an owned value. Read more

Converts self into T using Into<T>. Read more

Given the context attached to a nom error, and given the original input to the nom parser, extract more the useful context information. Read more

Causes self to use its Binary implementation when Debug-formatted. Read more

Causes self to use its Display implementation when Debug-formatted. Read more

Causes self to use its LowerExp implementation when Debug-formatted. Read more

Causes self to use its LowerHex implementation when Debug-formatted. Read more

Causes self to use its Octal implementation when Debug-formatted. Read more

Causes self to use its Pointer implementation when Debug-formatted. Read more

Causes self to use its UpperExp implementation when Debug-formatted. Read more

Causes self to use its UpperHex implementation when Debug-formatted. Read more

Formats each item in a sequence. Read more

Returns the argument unchanged.

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Pipes by value. This is generally the method you want to use. Read more

Borrows self and passes that borrow into the pipe function. Read more

Mutably borrows self and passes that borrow into the pipe function. Read more

Borrows self, then passes self.borrow() into the pipe function. Read more

Mutably borrows self, then passes self.borrow_mut() into the pipe function. Read more

Borrows self, then passes self.as_ref() into the pipe function.

Mutably borrows self, then passes self.as_mut() into the pipe function. Read more

Borrows self, then passes self.deref() into the pipe function.

Mutably borrows self, then passes self.deref_mut() into the pipe function. Read more

Given the original input, as well as the context reported by nom, recreate a context in the original string where the error occurred. Read more

Immutable access to a value. Read more

Mutable access to a value. Read more

Immutable access to the Borrow<B> of a value. Read more

Mutable access to the BorrowMut<B> of a value. Read more

Immutable access to the AsRef<R> view of a value. Read more

Mutable access to the AsMut<R> view of a value. Read more

Immutable access to the Deref::Target of a value. Read more

Mutable access to the Deref::Target of a value. Read more

Calls .tap() only in debug builds, and is erased in release builds.

Calls .tap_mut() only in debug builds, and is erased in release builds. Read more

Calls .tap_borrow() only in debug builds, and is erased in release builds. Read more

Calls .tap_borrow_mut() only in debug builds, and is erased in release builds. Read more

Calls .tap_ref() only in debug builds, and is erased in release builds. Read more

Calls .tap_ref_mut() only in debug builds, and is erased in release builds. Read more

Calls .tap_deref() only in debug builds, and is erased in release builds. Read more

Calls .tap_deref_mut() only in debug builds, and is erased in release builds. Read more

Attempts to convert self into T using TryInto<T>. Read more

The type returned in the event of a conversion error.

Performs the conversion.

The type returned in the event of a conversion error.

Performs the conversion.