/**
 * Copyright © 2019, Oracle and/or its affiliates. All rights reserved.
 *
 * Licensed under the Universal Permissive License v 1.0 as shown at
 * http://oss.oracle.com/licenses/upl
 *
 */
#ifndef FWG_H
#define FWG_H
/* File work graph. */

/* A file work graph is a directed acyclic graph (DAG) of nodes, each
 * containing an fwobject.

 * This structure is multithreaded, with some threads adding nodes,
 * and some removing nodes that have no predecessors.
 *
 * The graph has a budget, measured in bytes.  The graph avoids
 * allocating more memory than the budget permits, so if you try to
 * add too many nodes, you will stall until some other thread removes
 * objects.

 * A fwobject is opaque from this module's perspective.
 *
 * fwobjects are identified by a pathname (a string).  We assume that
 * symlinks aren't being used to confuse us by using different
 * pathnames for the same directory.
 *
 * To create an object (a file, hardlink, symlink, or directory, for
 * example), the directory of the object must have been created, and
 * the previous object in the same directory must have been created.
 * For hardlinks, the linked-to object must also have been created.
 *
 * To make this work we keep a hash table that maps from pathnames to nodes.
 *
 *   Pathnames for regular files point at the node that creates the
 *   file.  When the file is created, we remove the hashtable entry.
 *
 *   Pathnames for directories point at a node for the directory
 *   creation.  When the directory is created, we remove the hashtable
 *   entry.
 *
 *   Pathnames for directories also can point at the latest node that
 *   has been added for a file that will be created in that directory.

 */
#include <stddef.h>

struct fwg;
struct fwgnode;
struct fwobject;

struct fwg *mk_fwg(size_t budget);
// Effect: Make and return a fwg with a given budget.

struct fwg *fwg_destroy(struct fwg *fwg);
// Effect: Waits until everything has been removed and frees the
//   resources used by fwg.  You may not add anything else after this
//   has been invoked.

void fwg_add1(struct fwg *fwg,
              const char *name, struct fwobject *fwobject, size_t budget,
              const char *prev);
// Usage: To create a file, name is the name of the file and prev is
// the name of the directory containing the file.
void fwg_add2(struct fwg *fwg,
              const char *name, struct fwobject *fwobject, size_t budget,
              const char *prev1, const char *prev2);
void fwg_add3(struct fwg *fwg,
              const char *name, struct fwobject *fwobject, size_t budget,
              const char *prev1, const char *prev2, const char *prev3);
void fwg_end_of_nodes(struct fwg *fwg);
int fwg_get_ready_node(struct fwg       *fwg,
                       struct fwobject **fwobject,
                       struct fwgnode  **handle);
void fwg_finish_node(struct fwg *fwg,  struct fwgnode *handle);

#endif
