/*
 *  rtdump.c -- dump an rtree file.
 *
 * $Header: /private/postgres/src/test/RCS/rtdump.c,v 1.3 1991/02/28 18:01:44 mao Exp $
 */
#include <stdio.h>

#include "tmp/c.h"
#include "tmp/postgres.h"

#include "storage/bufmgr.h"
#include "storage/bufpage.h"
#include "storage/page.h"

#include "utils/log.h"
#include "utils/rel.h"

#include "access/genam.h"
#include "access/rtree.h"
#include "access/itup.h"

extern char	*DBName;

main(argc, argv)
    int argc;
    char **argv;
{
    Relation index;
    BlockNumber nblocks;
    BlockNumber i;
    OffsetNumber j, noff;
    IndexTuple t;
    ItemPointer itm;
    BlockNumber h_block;
    PageNumber h_pg;
    OffsetNumber h_off;
    Page p;
    Buffer b;
    extern char *optarg;
    extern int optind, opterr;
    char *indname;
    RTreePageOpaque opaque;
    int c;

    extern char *getenv();

    DBName = getenv("USER");

    while ((c = getopt("d:")) != EOF) {
	if (c != 'd') {
	    fprintf(stderr, "illegal option %c\n", c);
	    fprintf(stderr, "usage: %s [-d dbname] index\n");
	    exit (1);
	}
	DBName = optarg;
    }

    if ((indname = argv[optind]) == (char *) NULL) {
	fprintf(stderr, "usage: %s [-d dbname] index\n");
	exit (1);
    }

    InitPostgres(DBName);

    if ((index = index_openr(indname)) == (Relation) NULL)
	exit (1);

    nblocks = RelationGetNumberOfBlocks(index);

    for (i = 0; i < nblocks; i++) {
	b = ReadBuffer(index, i);
	p = BufferGetPage(b, 0);
	noff = PageGetMaxOffsetIndex(p);
	opaque = (RTreePageOpaque) PageGetSpecialPointer(p);
	printf("Page %d maxoff %d flags 0x%x (%s)\n", i, noff, opaque->flags,
			(opaque->flags & F_LEAF ? "leaf" : "internal"));
	for (j = 0; j <= noff; j++) {
	    t = (IndexTuple) PageGetItem(p, PageGetItemId(p, j));
	    itm = &(t->t_tid);
	    h_block = ItemPointerGetBlockNumber(itm);
	    h_pg = ItemPointerGetPageNumber(itm, 0);
	    h_off = ItemPointerGetOffsetNumber(itm, 0);
	    printf("\t[%d,0,%d] <%d,%d,%d>\n", i, j, h_block, h_pg, h_off);
	}
	ReleaseBuffer(b);
    }

    index_close(index);

    exitpg(0);
}
