O que significa uma estrutura de dados ser “intrusiva”?

120

Já vi o termo intrusivo ser usado para descrever estruturas de dados como listas e pilhas, mas o que isso significa?

Você pode dar um exemplo de código de uma estrutura de dados intrusiva e como ela difere de uma não intrusiva?

Além disso, por que torná-lo intrusivo (ou não intrusivo)? Quais são os benefícios? Quais são as desvantagens?

Rudiger
fonte

Respostas:

107

Uma estrutura de dados intrusiva é aquela que requer ajuda dos elementos que pretende armazenar para armazená-los.

Deixe-me reformular isso. Quando você coloca algo nessa estrutura de dados, esse "algo" se torna ciente do fato de que está nessa estrutura de dados, de alguma forma. Adicionar o elemento à estrutura de dados altera o elemento.

Por exemplo, você pode construir uma árvore binária não intrusiva, em que cada nó tem uma referência às subárvores esquerda e direita e uma referência ao valor do elemento desse nó.

Ou você pode construir um intrusivo em que as referências a essas subárvores sejam incorporadas ao próprio valor.

Um exemplo de uma estrutura de dados intrusiva seria uma lista ordenada de elementos mutáveis. Se o elemento for alterado, a lista precisará ser reordenada, de modo que o objeto de lista terá que se intrometer na privacidade dos elementos para obter sua cooperação. ie. o elemento deve saber sobre a lista em que está e informá-lo sobre as mudanças.

Os sistemas ORM geralmente giram em torno de estruturas de dados intrusivas, para minimizar a iteração em grandes listas de objetos. Por exemplo, se você recuperar uma lista de todos os funcionários no banco de dados, alterar o nome de um deles e salvá-la de volta no banco de dados, a lista intrusiva de funcionários será informada quando o objeto funcionário for alterado porque objeto sabe em qual lista está.

Uma lista não intrusiva não seria contada e teria que descobrir o que mudou e como mudou por si só.

Lasse V. Karlsen
fonte
8
Ainda gostaria de ver um exemplo e os prós e contras, mas esta é uma boa introdução.
Rudiger de
Em vez de código postal, direi que o STL não é intrusivo, enquanto Boost.Intrusive é intrusivo (obviamente).
stonemetal
1
Prós intrusivos: Não há necessidade de copiar seus dados em uma estrutura interna, eles podem ser usados ​​como estão. Contras: você deve quebrar o encapsulamento de seus dados para dar suporte aos contêineres nos quais seus dados serão armazenados. Pode ser complicado se seus dados precisarem estar em vários contêineres. Recipientes não intrusivos Prós: Melhor encapsulamento sem necessidade de modificar os dados dos seus recipientes. Contras: requer uma cópia de seus dados para a estrutura interna do nó.
stonemetal
3
boost.org/doc/libs/1_45_0/doc/html/intrusive.html tem exemplos e uma boa descrição dos prós e contras.
Tony Delroy
5
Ótima explicação com exemplos: boost.org/doc/libs/1_55_0/doc/html/intrusive/…
Paweł Szczur
22

Em um contêiner intrusivo, os próprios dados são responsáveis ​​por armazenar as informações necessárias para o contêiner. Isso significa que, por um lado, o tipo de dados precisa ser especializado dependendo de como será armazenado, por outro lado, significa que os dados "sabem" como estão armazenados e, portanto, podem ser otimizados um pouco melhor.

Não intrusivo:

template<typename T>
class LinkedList
{
  struct ListItem
  {
    T Value;
    ListItem* Prev;
    ListItem* Next;
  };

  ListItem* FirstItem;
  ListItem* LastItem;

  [...]
  ListItem* append(T&& val)
  {
    LastItem = LastItem.Next = new ListItem{val, LastItem, nullptr};
  };
};

LinkedList<int> IntList;

Intrusivo:

template<typename T>
class LinkedList
{
  T* FirstItem;
  T* LastItem;

  [...]
  T* append(T&& val)
  {
    T* newValue = new T(val);
    newValue.Next = nullptr;
    newValue.Prev = LastItem;
    LastItem.Next = newValue;
    LastItem = newValue;
  };
};

struct IntListItem
{
  int Value;
  IntListItem* Prev;
  IntListItem* Next;
};

LinkedList<IntListItem> IntList;

Pessoalmente, prefiro um design intrusivo pela sua transparência.

API-Beast
fonte
Essa última linha é curiosa devido ao uso da palavra "transparente", uma vez que estar em um contêiner intrusivo não é transparente para o objeto.
Trenó de
@ArtB É mais claro transmitir como os dados são usados ​​exatamente na aplicação final; no caso de dados não intrusivos, você geralmente precisa cavar os contêineres, enquanto os dados intrusivos os vê apenas a partir da estrutura dos dados.
API-Beast de
1
Bem, suponho que qualquer uso de "transparente" de transparente deve ser qualificado de acordo com qual perspectiva. Na minha experiência, "transparente" costuma ser usado para indicar que a forma como os dados estão sendo tratados é invisível para o domínio (ou seja, que a modelagem do domínio é pura). Se o termo está sendo usado nos dois sentidos, me pergunto se ele tem algum valor.
Trenó de
2
@ArtB Oh! Há algum significado especial em Ciência da Computação para transparente! Transparente significa para mim que você pode ver as partes internas, por exemplo, "não obstruindo a visão", como o termo é usado em qualquer contexto não-cs.
API-Beast