Compute and cache a recarray of asset lifetimes.

def _compute_asset_lifetimes(self, country_codes):
        """
        Compute and cache a recarray of asset lifetimes.
        """
        equities_cols = self.equities.c
        if country_codes:
            buf = np.array(
                tuple(
                    sa.select((
                        equities_cols.sid,
                        equities_cols.start_date,
                        equities_cols.end_date,
                    )).where(
                        (self.exchanges.c.exchange == equities_cols.exchange) &
                        (self.exchanges.c.country_code.in_(country_codes))
                    ).execute(),
                ),
                dtype='f8',  # use doubles so we get NaNs
            )
        else:
            buf = np.array([], dtype='f8')

        lifetimes = np.recarray(
            buf=buf,
            shape=(len(buf),),
            dtype=[
                ('sid', 'f8'),
                ('start', 'f8'),
                ('end', 'f8')
            ],
        )
        start = lifetimes.start
        end = lifetimes.end
        start[np.isnan(start)] = 0  # convert missing starts to 0
        end[np.isnan(end)] = np.iinfo(int).max  # convert missing end to INTMAX
        # Cast the results back down to int.
        return lifetimes.astype([
            ('sid', 'i8'),
            ('start', 'i8'),
            ('end', 'i8'),
        ])