Computes the annotations array in O(n) by "traversing" the suffix array.

        Based on ideas from Abouelhoda et al. (2004) and Dubov & Chernyak (2013).

def _compute_anntab(self, suftab, lcptab):
        """Computes the annotations array in O(n) by "traversing" the suffix array.

        Based on ideas from Abouelhoda et al. (2004) and Dubov & Chernyak (2013).
        """
        n = len(suftab)
        anntab = np.zeros(n, dtype=np.int)  # Zeros / -1 ?

        def process_node(node):
            # NOTE(msdubov): Assumes that child l-[i..j] lcp intervals come in the ascending
            #                order (by i). This allows to handle the leafs properly.
            i = node[1]
            for child_node in node[3]:
                if i < child_node[1]:
                    anntab[self._interval_index(node)] += child_node[1] - i
                anntab[self._interval_index(node)] += anntab[self._interval_index(child_node)]
                i = child_node[2] + 1
            if i <= node[2]:
                anntab[self._interval_index(node)] += node[2] - i + 1

        self.traverse_depth_first_post_order(process_node)
        # NOTE(msdubov): Removing the "degenerate" 1st-level leafs
        #                with the auxiliary symbol in the arc.
        anntab[0] -= len(self.strings_collection)

        return anntab