Qu'est-ce que cela signifie pour une structure de données d'être «intrusive»?

120

J'ai vu le terme intrusif utilisé pour décrire des structures de données telles que des listes et des piles, mais qu'est-ce que cela signifie?

Pouvez-vous donner un exemple de code d'une structure de données intrusive, et en quoi elle diffère d'une structure non intrusive?

Aussi, pourquoi le rendre intrusif (ou non intrusif)? Quels sont les bénéfices? Quels sont les inconvénients?

Rudiger
la source

Réponses:

107

Une structure de données intrusive est une structure qui nécessite l'aide des éléments qu'elle a l'intention de stocker pour les stocker.

Permettez-moi de reformuler cela. Lorsque vous mettez quelque chose dans cette structure de données, ce «quelque chose» prend conscience du fait qu'il se trouve dans cette structure de données, d'une certaine manière. L'ajout de l'élément à la structure de données modifie l'élément.

Par exemple, vous pouvez créer un arbre binaire non intrusif, où chaque nœud a une référence aux sous-arbres gauche et droit, et une référence à la valeur d'élément de ce nœud.

Vous pouvez également en créer une intrusive dans laquelle les références à ces sous-arbres sont intégrées dans la valeur elle-même.

Un exemple de structure de données intrusive serait une liste ordonnée d'éléments modifiables. Si l'élément change, la liste doit être réorganisée, donc l'objet de la liste doit empiéter sur la confidentialité des éléments afin d'obtenir leur coopération. c'est à dire. l'élément doit connaître la liste dans laquelle il se trouve et l'informer des changements.

Les systèmes ORM tournent généralement autour de structures de données intrusives, pour minimiser l'itération sur de grandes listes d'objets. Par exemple, si vous récupérez une liste de tous les employés dans la base de données, puis changez le nom de l'un d'entre eux et souhaitez l'enregistrer à nouveau dans la base de données, la liste intrusive d'employés sera informée lorsque l'objet employé a changé car cela l'objet sait dans quelle liste il se trouve.

Une liste non intrusive ne serait pas révélée et devrait déterminer ce qui a changé et comment cela a changé par elle-même.

Lasse V. Karlsen
la source
8
J'aimerais toujours voir un exemple et les avantages et inconvénients, mais c'est une bonne introduction.
Rudiger
Plutôt que du code postal, je dirai que la STL est non intrusive, tandis que Boost.Intrusive est intrusive (évidemment).
stonemetal
1
Intrusive Pros: Pas besoin de copier vos données dans une structure interne, elles peuvent être utilisées telles quelles. Inconvénients: vous devez interrompre l'encapsulation de vos données pour prendre en charge les conteneurs dans lesquels vos données vont être stockées. Cela peut devenir délicat si vos données doivent se trouver dans plusieurs conteneurs. Conteneurs non intrusifs Avantages: Meilleure encapsulation, pas besoin de modifier les données de vos conteneurs. Inconvénients: nécessite une copie de vos données dans la structure de nœud interne.
stonemetal
3
boost.org/doc/libs/1_45_0/doc/html/intrusive.html contient des exemples et une bonne description des avantages et des inconvénients.
Tony Delroy
5
Excellente explication avec des exemples: boost.org/doc/libs/1_55_0/doc/html/intrusive/…
Paweł Szczur
22

Dans un conteneur intrusif, les données elles-mêmes sont responsables du stockage des informations nécessaires pour le conteneur. Cela signifie que d'un côté le type de données doit être spécialisé en fonction de la façon dont il sera stocké, de l'autre, cela signifie que les données "savent" comment elles sont stockées et peuvent donc être légèrement mieux optimisées.

Non intrusif:

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;

Intrusif:

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;

Personnellement, je préfère le design intrusif pour sa transparence.

API-Bête
la source
Cette dernière ligne est curieuse en raison de l'utilisation du mot «transparent» car être dans un conteneur intrusif n'est pas transparent pour l'objet.
Traîneau
@ArtB Il est plus clair de montrer comment les données sont utilisées exactement dans l'application finale, dans le cas de données non intrusives, vous devez généralement fouiller dans les conteneurs tandis que pour les données intrusives, vous les voyez uniquement à partir de la structure des données.
API-Beast
1
Eh bien, je suppose que toute utilisation "transparente" de transparent doit être qualifiée selon quelle perspective. D'après mon expérience, «transparent» est souvent utilisé pour indiquer que la manière dont les données sont traitées est invisible pour le domaine (c'est-à-dire que la modélisation du domaine est pure). Si le terme est utilisé dans les deux sens, je me demande s'il y a une valeur.
Traîneau
2
@ArtB Oh! Il y a une signification spéciale en informatique pour transparent! Transparent signifie pour moi que vous pouvez voir les éléments internes, par exemple "ne pas obstruer la vue", comme le terme est utilisé dans n'importe quel contexte non-cs.
API-Beast