示例#1
0
static void
tree_node_destroy (DirectTree *tree,
                   DirectNode *node)
{
     if (node) {
          tree_node_destroy (tree, node->left);
          tree_node_destroy (tree, node->right);

          if (node->value)
               D_FREE(node->value);

          D_FREE(node);
     }
}
示例#2
0
/**
 * Destroys and frees the node and all children
 *
 * @param parent Parent node to be destroyed
 */
static void
tree_node_destroy (struct MeshTunnelTreeNode *parent)
{
  struct MeshTunnelTreeNode *n;
  struct MeshTunnelTreeNode *next;

#if MESH_TREE_DEBUG
  struct GNUNET_PeerIdentity id;

  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "tree: Destroying node %u\n",
              parent->peer);
  GNUNET_PEER_resolve (parent->peer, &id);
  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "tree:   (%s)\n", GNUNET_i2s (&id));
#endif
  n = parent->children_head;
  while (NULL != n)
  {
    next = n->next;
    tree_node_destroy (n);
    n = next;
  }
  GNUNET_PEER_change_rc (parent->peer, -1);
  if (NULL != parent->parent)
    GNUNET_CONTAINER_DLL_remove (parent->parent->children_head,
                                 parent->parent->children_tail, parent);
  GNUNET_free (parent);
}
示例#3
0
/**
 * Delete the current path to the peer, including all now unused relays.
 * The destination peer is NOT destroyed, it is returned in order to either set
 * a new path to it or destroy it explicitly, taking care of it's child nodes.
 *
 * @param t Tunnel tree where to delete the path from.
 * @param peer_id Short ID of the destination peer whose path we want to remove.
 * @param cb Callback to use to notify about disconnected peers.
 * @param cbcls Closure for cb.
 *
 * @return pointer to the pathless node.
 *         NULL when not found
 */
struct MeshTunnelTreeNode *
tree_del_path (struct MeshTunnelTree *t, GNUNET_PEER_Id peer_id,
               MeshTreeCallback cb, void *cbcls)
{
  struct MeshTunnelTreeNode *parent;
  struct MeshTunnelTreeNode *node;
  struct MeshTunnelTreeNode *n;

#if MESH_TREE_DEBUG
  struct GNUNET_PeerIdentity id;

  GNUNET_PEER_resolve (peer_id, &id);
  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "tree:   Deleting path to %s.\n",
              GNUNET_i2s (&id));
#endif
  if (peer_id == t->root->peer)
    return NULL;

  for (n = t->disconnected_head; NULL != n; n = n->next)
  {
    if (n->peer == peer_id)
    {
      /* Was already pathless, waiting for reconnection */
      GNUNET_CONTAINER_DLL_remove (t->disconnected_head, t->disconnected_tail,
                                   n);
      return n;
    }
  }
  n = tree_find_peer (t, peer_id);
  if (NULL == n)
    return NULL;
  node = n;

  parent = n->parent;
  GNUNET_CONTAINER_DLL_remove (parent->children_head, parent->children_tail, n);
  n->parent = NULL;

  while (MESH_PEER_RELAY == parent->status && NULL == parent->children_head)
  {
#if MESH_TREE_DEBUG
    GNUNET_PEER_resolve (parent->peer, &id);
    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "tree:   Deleting node %s.\n",
                GNUNET_i2s (&id));
#endif
    n = parent->parent;
    tree_node_destroy (parent);
    parent = n;
  }
#if MESH_TREE_DEBUG
  GNUNET_PEER_resolve (parent->peer, &id);
  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "tree:   Not deleted peer %s.\n",
              GNUNET_i2s (&id));
#endif

  tree_mark_peers_disconnected (t, node, cb, cbcls);

  return node;
}
示例#4
0
static void
destroy_node_without_reporting (FMTreeModel *model, TreeNode *node)
{
	abandon_node_ref_count (model, node);
	stop_monitoring_directory (model, node);
	node->inserted = FALSE;
	destroy_children_without_reporting (model, node);
	g_hash_table_remove (node->root->file_to_node_map, node->file);
	tree_node_destroy (model, node);
}
示例#5
0
/**
 * Destroy the whole tree and free all used memory and Peer_Ids
 *
 * @param t Tree to be destroyed
 */
void
tree_destroy (struct MeshTunnelTree *t)
{
#if MESH_TREE_DEBUG
  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "tree: Destroying tree\n");
#endif
  tree_node_destroy (t->root);
  GNUNET_CONTAINER_multihashmap_iterate (t->first_hops, &iterate_free, NULL);
  GNUNET_CONTAINER_multihashmap_destroy (t->first_hops);
  GNUNET_free (t);
}
示例#6
0
/**
 * Deletes a peer from a tunnel, liberating all unused resources on the path to
 * it. It shouldn't have children, if it has they will be destroyed as well.
 * If the tree is not local and no longer has any paths, the root node will be
 * destroyed and marked as NULL.
 *
 * @param t Tunnel tree to use.
 * @param peer Short ID of the peer to remove from the tunnel tree.
 * @param cb Callback to notify client of disconnected peers.
 * @param cbcls Closure for cb.
 *
 * @return GNUNET_OK or GNUNET_SYSERR
 */
int
tree_del_peer (struct MeshTunnelTree *t, GNUNET_PEER_Id peer,
               MeshTreeCallback cb, void *cbcls)
{
  struct MeshTunnelTreeNode *n;

  n = tree_del_path (t, peer, cb, cbcls);
  if (NULL == n)
  {
    GNUNET_break (0);
    return GNUNET_YES;
  }
  GNUNET_break_op (NULL == n->children_head);
  tree_node_destroy (n);
  if (NULL == t->root->children_head && t->me != t->root)
  {
    tree_node_destroy (t->root);
    t->root = NULL;
    return GNUNET_NO;
  }
  return GNUNET_YES;
}
示例#7
0
void
direct_tree_destroy( DirectTree *tree )
{
     unsigned int i;

     for (i = 0; i < 96; i++) {
          if (tree->fast_keys[i])
               D_FREE( tree->fast_keys[i] );
     }

     tree_node_destroy( tree, tree->root );

     D_FREE( tree );
}