mirror of
git://sourceware.org/git/lvm2.git
synced 2025-01-03 05:18:29 +03:00
export: use radix_tree for write formatter
Replace use of dm_hash with radix_tree when making PV index names. Store just the index number itself and use pv%d for outf() string. For lookup up a PV - use just the PV pointer itself, it's faster then converint for it's ID to UUID format.
This commit is contained in:
parent
7c5cca600c
commit
4dc0ee8e56
@ -25,6 +25,7 @@
|
|||||||
#include "lib/commands/toolcontext.h"
|
#include "lib/commands/toolcontext.h"
|
||||||
#include "lib/device/device_id.h"
|
#include "lib/device/device_id.h"
|
||||||
#include "libdaemon/client/config-util.h"
|
#include "libdaemon/client/config-util.h"
|
||||||
|
#include "base/data-struct/radix-tree.h"
|
||||||
|
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
@ -53,8 +54,7 @@ typedef int (*nl_fn) (struct formatter * f);
|
|||||||
* exporting the vg, ie. writing it to a file.
|
* exporting the vg, ie. writing it to a file.
|
||||||
*/
|
*/
|
||||||
struct formatter {
|
struct formatter {
|
||||||
struct dm_pool *mem; /* pv names allocated from here */
|
struct radix_tree *pv_idx; /* dev_name id -> pv_name (eg, pv1) */
|
||||||
struct dm_hash_table *pv_names; /* dev_name -> pv_name (eg, pv1) */
|
|
||||||
|
|
||||||
union {
|
union {
|
||||||
FILE *fp; /* where we're writing to */
|
FILE *fp; /* where we're writing to */
|
||||||
@ -500,29 +500,18 @@ static int _print_vg(struct formatter *f, struct volume_group *vg)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/* Get the pv index %d name from the formatters radix tree. */
|
||||||
* Get the pv%d name from the formatters hash
|
static int _get_pv_idx(const struct formatter *f, const struct physical_volume *pv)
|
||||||
* table.
|
|
||||||
*/
|
|
||||||
static const char *_get_pv_name_from_uuid(struct formatter *f, char *uuid)
|
|
||||||
{
|
{
|
||||||
const char *pv_name = dm_hash_lookup(f->pv_names, uuid);
|
union radix_value idx;
|
||||||
|
|
||||||
if (!pv_name)
|
if (!pv || !radix_tree_lookup(f->pv_idx, &pv, sizeof(pv), &idx)) {
|
||||||
log_error(INTERNAL_ERROR "PV name for uuid %s missing from text metadata export hash table.",
|
log_error(INTERNAL_ERROR "PV name for %s missing in metadata export radix tree.",
|
||||||
uuid);
|
pv_dev_name(pv));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
return pv_name;
|
return (int) idx.n;
|
||||||
}
|
|
||||||
|
|
||||||
static const char *_get_pv_name(struct formatter *f, struct physical_volume *pv)
|
|
||||||
{
|
|
||||||
char uuid[64] __attribute__((aligned(8)));
|
|
||||||
|
|
||||||
if (!pv || !id_write_format(&pv->id, uuid, sizeof(uuid)))
|
|
||||||
return_NULL;
|
|
||||||
|
|
||||||
return _get_pv_name_from_uuid(f, uuid);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _print_pvs(struct formatter *f, struct volume_group *vg)
|
static int _print_pvs(struct formatter *f, struct volume_group *vg)
|
||||||
@ -530,7 +519,7 @@ static int _print_pvs(struct formatter *f, struct volume_group *vg)
|
|||||||
struct pv_list *pvl;
|
struct pv_list *pvl;
|
||||||
struct physical_volume *pv;
|
struct physical_volume *pv;
|
||||||
char buffer[PATH_MAX * 2];
|
char buffer[PATH_MAX * 2];
|
||||||
const char *name;
|
int idx;
|
||||||
const char *idtype, *idname;
|
const char *idtype, *idname;
|
||||||
|
|
||||||
outf(f, "physical_volumes {");
|
outf(f, "physical_volumes {");
|
||||||
@ -542,11 +531,11 @@ static int _print_pvs(struct formatter *f, struct volume_group *vg)
|
|||||||
if (!id_write_format(&pv->id, buffer, sizeof(buffer)))
|
if (!id_write_format(&pv->id, buffer, sizeof(buffer)))
|
||||||
return_0;
|
return_0;
|
||||||
|
|
||||||
if (!(name = _get_pv_name_from_uuid(f, buffer)))
|
if ((idx = _get_pv_idx(f, pv)) < 0)
|
||||||
return_0;
|
return_0;
|
||||||
|
|
||||||
outnl(f);
|
outnl(f);
|
||||||
outf(f, "%s {", name);
|
outf(f, "pv%d {", idx);
|
||||||
_inc_indent(f);
|
_inc_indent(f);
|
||||||
|
|
||||||
outf(f, "id = \"%s\"", buffer);
|
outf(f, "id = \"%s\"", buffer);
|
||||||
@ -630,8 +619,8 @@ static int _print_segment(struct formatter *f, struct volume_group *vg,
|
|||||||
int out_areas(struct formatter *f, const struct lv_segment *seg,
|
int out_areas(struct formatter *f, const struct lv_segment *seg,
|
||||||
const char *type)
|
const char *type)
|
||||||
{
|
{
|
||||||
const char *name;
|
|
||||||
unsigned int s;
|
unsigned int s;
|
||||||
|
int idx;
|
||||||
struct physical_volume *pv;
|
struct physical_volume *pv;
|
||||||
|
|
||||||
outnl(f);
|
outnl(f);
|
||||||
@ -648,10 +637,10 @@ int out_areas(struct formatter *f, const struct lv_segment *seg,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(name = _get_pv_name(f, pv)))
|
if ((idx = _get_pv_idx(f, pv)) < 0)
|
||||||
return_0;
|
return_0;
|
||||||
|
|
||||||
outf(f, "\"%s\", %u%s", name,
|
outf(f, "\"pv%d\", %u%s", idx,
|
||||||
seg_pe(seg, s),
|
seg_pe(seg, s),
|
||||||
(s == seg->area_count - 1) ? "" : ",");
|
(s == seg->area_count - 1) ? "" : ",");
|
||||||
break;
|
break;
|
||||||
@ -962,35 +951,22 @@ static int _print_historical_lvs(struct formatter *f, struct volume_group *vg)
|
|||||||
* 'pv2' etc. This function builds a hash table
|
* 'pv2' etc. This function builds a hash table
|
||||||
* to enable a quick lookup from device -> name.
|
* to enable a quick lookup from device -> name.
|
||||||
*/
|
*/
|
||||||
static int _build_pv_names(struct formatter *f, struct volume_group *vg)
|
static int _build_pv_idx(struct formatter *f, struct volume_group *vg)
|
||||||
{
|
{
|
||||||
int count = 0;
|
union radix_value count = { 0 };
|
||||||
struct pv_list *pvl;
|
struct pv_list *pvl;
|
||||||
struct physical_volume *pv;
|
struct physical_volume *pv;
|
||||||
char buffer[32], *name;
|
|
||||||
char uuid[64];
|
|
||||||
|
|
||||||
if (!(f->mem = dm_pool_create("text pv_names", 512)))
|
if (!(f->pv_idx = radix_tree_create(NULL, NULL)))
|
||||||
return_0;
|
|
||||||
|
|
||||||
if (!(f->pv_names = dm_hash_create(115)))
|
|
||||||
return_0;
|
return_0;
|
||||||
|
|
||||||
dm_list_iterate_items(pvl, &vg->pvs) {
|
dm_list_iterate_items(pvl, &vg->pvs) {
|
||||||
pv = pvl->pv;
|
pv = pvl->pv;
|
||||||
|
|
||||||
/* FIXME But skip if there's already an LV called pv%d ! */
|
/* FIXME But skip if there's already an LV called pv%d ! */
|
||||||
if (dm_snprintf(buffer, sizeof(buffer), "pv%d", count++) < 0)
|
if (!radix_tree_insert(f->pv_idx, &pv, sizeof(pv), count))
|
||||||
return_0;
|
|
||||||
|
|
||||||
if (!(name = dm_pool_strdup(f->mem, buffer)))
|
|
||||||
return_0;
|
|
||||||
|
|
||||||
if (!id_write_format(&pv->id, uuid, sizeof(uuid)))
|
|
||||||
return_0;
|
|
||||||
|
|
||||||
if (!dm_hash_insert(f->pv_names, uuid, name))
|
|
||||||
return_0;
|
return_0;
|
||||||
|
count.n++;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
@ -1001,7 +977,7 @@ static int _text_vg_export(struct formatter *f,
|
|||||||
{
|
{
|
||||||
int r = 0;
|
int r = 0;
|
||||||
|
|
||||||
if (!_build_pv_names(f, vg))
|
if (!_build_pv_idx(f, vg))
|
||||||
goto_out;
|
goto_out;
|
||||||
|
|
||||||
if (f->header && !_print_header(vg->cmd, f, desc))
|
if (f->header && !_print_header(vg->cmd, f, desc))
|
||||||
@ -1037,14 +1013,9 @@ static int _text_vg_export(struct formatter *f,
|
|||||||
r = 1;
|
r = 1;
|
||||||
|
|
||||||
out:
|
out:
|
||||||
if (f->mem) {
|
if (f->pv_idx) {
|
||||||
dm_pool_destroy(f->mem);
|
radix_tree_destroy(f->pv_idx);
|
||||||
f->mem = NULL;
|
f->pv_idx = NULL;
|
||||||
}
|
|
||||||
|
|
||||||
if (f->pv_names) {
|
|
||||||
dm_hash_destroy(f->pv_names);
|
|
||||||
f->pv_names = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
|
Loading…
Reference in New Issue
Block a user