summaryrefslogtreecommitdiff
path: root/src/dirpool.h
blob: 29ed109fd194ac6f89f71541ff9d39dfb8843b7e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
/*
 * Copyright (c) 2007, Novell Inc.
 *
 * This program is licensed under the BSD license, read LICENSE.BSD
 * for further information
 */
#ifndef LIBSOLV_DIRPOOL_H
#define LIBSOLV_DIRPOOL_H


#include "pooltypes.h"
#include "util.h"

typedef struct _Dirpool {
  Id *dirs;
  int ndirs;
  Id *dirtraverse;
} Dirpool;

void dirpool_init(Dirpool *dp);
void dirpool_free(Dirpool *dp);

void dirpool_make_dirtraverse(Dirpool *dp);
Id dirpool_add_dir(Dirpool *dp, Id parent, Id comp, int create);

/* return the parent directory of child did */
static inline Id dirpool_parent(Dirpool *dp, Id did)
{
  if (!did)
    return 0;
  while (dp->dirs[--did] > 0)
    ;
  return -dp->dirs[did];
}

/* return the next child entry of child did */
static inline Id
dirpool_sibling(Dirpool *dp, Id did)
{
  /* if this block contains another entry, simply return it */
  if (did + 1 < dp->ndirs && dp->dirs[did + 1] > 0)
    return did + 1;
  /* end of block reached, rewind to get to the block's
   * dirtraverse entry */
  while (dp->dirs[--did] > 0)
    ;
  /* need to special case did == 0 to prevent looping */
  if (!did)
    return 0;
  if (!dp->dirtraverse)
    dirpool_make_dirtraverse(dp);
  return dp->dirtraverse[did];
}

/* return the first child entry of directory did */
static inline Id
dirpool_child(Dirpool *dp, Id did)
{
  if (!dp->dirtraverse)
    dirpool_make_dirtraverse(dp);
  return dp->dirtraverse[did];
}

static inline void
dirpool_free_dirtraverse(Dirpool *dp)
{
  solv_free(dp->dirtraverse);
  dp->dirtraverse = 0;
}

static inline Id
dirpool_compid(Dirpool *dp, Id did)
{
  return dp->dirs[did];
}

#endif /* LIBSOLV_DIRPOOL_H */