📄 cmdline.cc
字号:
// cmdline.cc// Copyright (c) 1998, Regents of the University of California// $Id: cmdline.cc,v 1.15 2000/03/15 00:23:48 mashah Exp $#include <stdio.h>#include <stdlib.h>#include <string.h>// VCPORT_B#if (defined WIN32) || (__GNUG__==3)#pragma warning(disable:4786)#include <fstream>#include <iostream>#include <strstream>using namespace std;#else#include <fstream.h>#include <iostream.h>#include <strstream.h>#endif// VCPORT_E#include "gist.h"#include "gist_extensions.h"#include "gist_defs.h"#include "gist_compat.h"#include "gist_cursor.h"#include "gist_cursorext.h"#include "gist_btree.h"#include "gist_rtree.h"#include "gist_rstartree.h"#include "gist_nptree.h"#include "gist_rrtree.h"#include "gist_sptree.h"#include "gist_sstree.h"#include "gist_srtree.h"#include "gist_rtreecext.h"#include "cmdline.h"#include "cmdline_help.h" // generated at compile-time#include "cmdline_ts.h" // generated at compile-time#ifdef AMDB#include "amdb_defs.h"#include "amdb_analysis.h"#include "amdb_wkldprofile.h"#include "amdb_treemap.h"#include "amdb_breakpoints.h"#include "amdb_idxstruct.h"#endifextern int yyparse();#define NOT_FOUND (-1)static const int MAXLINE = 8192;static const int MAXIDX = sizeof(_gist_exts)/sizeof(gist_ext_t*);static gist_cursorext_t* gist_cexts[] = { &stack_cext, &rt_point_nn_cext, &rt_rect_nn_cext, &rr_point_nn_cext, &sp_point_nn_cext, &ss_point_nn_cext, &sr_point_nn_cext,};struct Table { char* name; gist* index;#ifdef AMDB amdb_idxstruct* strct;#endif};static Table tables[MAXIDX];static int numTables = 0;static bool echoOutput = true; // true: echos inserted/retrieved keysstatic bool noPrompt = false; // true: don't print prompt (simplifies tests)#ifdef AMDBstruct Analysis { char* name; amdb_analysis* analysis;};static Analysis analyses[MAXIDX];static int numAnalyses = 0;#endif// forward declarationsstatic rc_t runQuery(gist& index, const gist_query_t* query, int k, int io, int& numRetrieved);static void printDatum(void* key, int klen, void* data, int dlen, gist_ext_t* ext);static rc_t closeTable(int idx);static void closeAnalysis(int idx);static int getTable(const char* name);static int getAnalysis(const char* name);static gist_ext_t* getExtension(const char* extname);static rc_t scanString(istream& s, char* str);static rc_t scanTup(void* key, int& klen, void* data, int& dlen, shpid_t& child, void* param);static rc_trunQuery( gist& index, const gist_query_t* query, // in: query to run int k, // in: max. number of tuples to retrieve int io, // in: max. number of page accesses int& numRetrieved) // out: number of retrieved tuples{ gist_cursor_t cursor; if (index.fetch_init(cursor, query, k, io) != RCOK) { cout << "can't initialize cursor" << endl; return(eERROR); } gist_ext_t* ext = index.extension(); bool eof = false; char key[gist_p::max_tup_sz]; smsize_t klen; char data[gist_p::max_tup_sz]; smsize_t dlen; int cnt = 0; for (;;) { klen = gist_p::max_tup_sz; dlen = gist_p::max_tup_sz; if (index.fetch(cursor, (void *) key, klen, (void *) data, dlen, eof) != RCOK) { cerr << "can't fetch from cursor" << endl; return(eERROR); } if (eof) break; // print key and data if (echoOutput) { printDatum(key, klen, data, dlen, ext); cout << endl; } cnt++; } numRetrieved = cnt; return(RCOK);}static voidprintDatum( void* key, int klen, void* data, int dlen, gist_ext_t* ext){ vec_t keyv(key, klen); vec_t datav(data, dlen); ext->printPred(cout, keyv, 1); cout << ": "; ext->printData(cout, datav);}static rc_tcloseTable( int idx){#ifdef AMDB delete tables[idx].strct; tables[idx].strct = NULL;#endif free(tables[idx].name); rc_t status = tables[idx].index->close(); delete tables[idx].index; tables[idx].index = NULL; for ( ; idx < numTables-1; idx++) { tables[idx] = tables[idx+1]; } numTables--; return(status);}static voidcloseAnalysis( int idx){#ifdef AMDB free(analyses[idx].name); delete analyses[idx].analysis; analyses[idx].analysis = NULL; for ( ; idx < numAnalyses-1; idx++) { analyses[idx] = analyses[idx+1]; } numAnalyses--;#endif}static intgetTable( const char* name){ int i; for (i = 0; i < numTables; i++) { if (strcmp(tables[i].name, name) == 0) break; } return (i == numTables ? NOT_FOUND : i);}static intgetAnalysis( const char* name){#ifdef AMDB int i; for (i = 0; i < numAnalyses; i++) { if (strcmp(analyses[i].name, name) == 0) break; } return (i == numAnalyses ? NOT_FOUND : i);#endif}static gist_ext_t*getExtension( const char* extname){ int i; for (i = 0; i < gist_ext_t::gist_numext; i++) { if (strcmp(extname, gist_ext_t::gist_ext_list[i]->myName) == 0) break; } return (i == gist_ext_t::gist_numext ? (gist_ext_t *) NULL : gist_ext_t::gist_ext_list[i]);}struct TupStreamParam { int idx; // into gist table istream& s; // read tuples from there TupStreamParam(int idx, istream&s) : idx(idx), s(s) {}};static rc_tscanString( istream& s, // in: input stream char* str) // out: string stripped off '"'s{ char ch; s >> ws; // discard whitespace s >> ch; if (ch != '"') return(ePARSEERROR); int i = 0; do { s.get(ch); str[i] = ch; i++; } while (!s.eof() && ch != '"'); if (s.eof()) return(ePARSEERROR); // key isn't terminated assert(ch == '"'); str[i-1] = '\0'; // replace terminating double quote if (i == 1) return(ePARSEERROR); // no key specified return(RCOK);}/////////////////////////////////////////////////////////////////////////// scanTup - scan single line in load file//// Description:// - line format: "<key>" "<data"\n//// Preconditions:// - ext->printPred/-Data must not be NULL//// Return Values:// RCOK// eEOF// eFILEERROR// ePAGEBREAK/////////////////////////////////////////////////////////////////////////static rc_tscanTup( void* key, int& klen, void* data, int& dlen, shpid_t& child, void* param){ static int itemCnt = 0; TupStreamParam* p = (TupStreamParam *) param; char line[MAXLINE]; p->s.getline(line, MAXLINE); if (p->s.eof()) { // we're done with this load file cout << "read " << itemCnt << " items" << endl; itemCnt = 0; // reset for next bulk load return eEOF; } if (p->s.fail()) return eFILEERROR; if (strlen(line) == 0) { // we read a page break marker (empty line) klen = dlen = 0; if (echoOutput) { cout << "BREAK" << endl; } return ePAGEBREAK; } istrstream s(line); // scan input line for "<key>" "<data>" char ch; char keystr[MAXLINE]; W_DO(scanString(s, keystr)); char datastr[MAXLINE]; W_DO(scanString(s, datastr)); // now, convert key and data strings gist *index = tables[p->idx].index; gist_ext_t* ext = tables[p->idx].index->extension(); if (ext->parsePred(keystr, key, klen) != RCOK) { cout << "can't parse key " << keystr << endl; return ePARSEERROR; } if (ext->parseData(datastr, data, dlen) != RCOK) { cout << "can't parse data " << datastr << endl; return ePARSEERROR; } if (echoOutput) { printDatum(key, klen, data, dlen, ext); cout << endl; } child = 0; itemCnt++; return RCOK;}///////////////////////////////////////////////////////////////////////////////// cmdCreate - call gist::create()//// Description:// - records new index in tables[]///////////////////////////////////////////////////////////////////////////////voidcmdCreate( const char* table, const char* extname){ if (numTables == MAXIDX) { cout << "Capacity exceeded (" << MAXIDX << ")" << endl; return; } gist_ext_t* ext = getExtension(extname); if (ext == NULL) { cout << "Extension not recognized\n"; return; } gist *index = new gist(); rc_t status = index->create(table, ext); index->flush(); if (status != RCOK) { cout << "Error creating table." << endl; delete index; return; } tables[numTables].name = strdup(table); tables[numTables].index = index; numTables++;}///////////////////////////////////////////////////////////////////////////////// cmdLoad - call gist::create() to bulk-load index//// Description:///////////////////////////////////////////////////////////////////////////////voidcmdLoad( const char* table, const char* extname, const char* filename, float fillFactor){ if (numTables == MAXIDX) { cout << "Capacity exceeded (" << MAXIDX << ")" << endl; return; } gist_ext_t* ext = getExtension(extname); if (ext == NULL) { cout << "Extension not recognized\n"; return; } // check if we have the required parsing functions if (ext->parsePred == NULL) { cout << "Extension can't parse predicates." << endl; return; } if (ext->parseData == NULL) { cout << "Extension can't parse data." << endl; return; } ifstream s(filename); if (s.fail()) { cout << "Error opening data file." << endl; return; } gist *index = new gist(); tables[numTables].name = strdup(table); tables[numTables].index = index; numTables++; TupStreamParam param(numTables-1, s); rc_t status = index->create(table, ext, scanTup, (void *) ¶m, fillFactor); s.close(); index->flush(); if (status != RCOK) { cout << "Error loading table." << endl; delete index; return; }}///////////////////////////////////////////////////////////////////////////////// cmdWriteLoadFile - call gist::writeLoadFile//// Description:///////////////////////////////////////////////////////////////////////////////voidcmdWriteLoadfile( const char* table, const char* filename){#ifdef AMDB int i; if ((i = getTable(table)) == NOT_FOUND) { cerr << "Table not open" << endl; return; } ofstream s(filename); if (s.fail()) { cout << "Error opening file." << endl; return; } if (tables[i].index->writeLoadfile(s) != RCOK) { cout << "Error writing load file." << endl; } s.close();#endif}///////////////////////////////////////////////////////////////////////////////// cmdOpen - call gist::open()//// Description:// - record index in tables[]///////////////////////////////////////////////////////////////////////////////voidcmdOpen( const char* table){ if (numTables == MAXIDX) { cout << "Capacity exceeded (" << MAXIDX << ")" << endl; return; } if (getTable(table) != NOT_FOUND) { cout << "Index already open" << endl; return; } gist *index = new gist(); rc_t status = index->open(table); if (status != RCOK) { delete index; cout << "Error opening index." << endl; return; } tables[numTables].index = index; tables[numTables].name = strdup(table); numTables++;}///////////////////////////////////////////////////////////////////////////////// cmdClose - call gist::close//// Description:// - remove index from tables[]///////////////////////////////////////////////////////////////////////////////voidcmdClose( const char* table){ int i; if ((i = getTable(table)) == NOT_FOUND) { cout << "Index not opened" << endl; return; } if (closeTable(i) != RCOK) { cout << "can't close" << endl; }}///////////////////////////////////////////////////////////////////////////////// cmdCheck - call gist::check()//// Description:///////////////////////////////////////////////////////////////////////////////voidcmdCheck( const char* table){ int i; if ((i = getTable(table)) == NOT_FOUND) { cout << "Index not opened" << endl; return; } gist *index = tables[i].index; if (index->check() != RCOK) { cout << "can't check" << endl; }}///////////////////////////////////////////////////////////////////////////////// cmdSelect - call gist::fetch()//// Description:// - select max of k tuples with given query/////////////////////////////////////////////////////////////////////////////////voidcmdSelect( const char* table, const char* qstr, int k, int io){ int i; if ((i = getTable(table)) == NOT_FOUND) { cout << "Index not opened" << endl; return; } gist* index = tables[i].index; gist_ext_t* ext = tables[i].index->extension(); // make sure extension can parse queries if (ext->parseQuery == NULL) { cout << "Extension can't parse queries." << endl; return; } gist_query_t* query; rc_t status = ext->parseQuery(qstr, query); if (status != RCOK) { cout << "Error parsing qualification" << endl; return; } int numRetrieved; if (runQuery(*index, query, k, io, numRetrieved) != RCOK) { return; } cout << "retrieved " << numRetrieved << " items" << endl; delete query;}///////////////////////////////////////////////////////////////////////////////// cmdInsert - call gist::insert//// Description://///////////////////////////////////////////////////////////////////////////////voidcmdInsert( const char* table, const char* kstr, const char* dstr){ int i; if ((i = getTable(table)) == NOT_FOUND) { cout << "Index not opened" << endl; return; } gist *index = tables[i].index; gist_ext_t* ext = tables[i].index->extension(); // make sure extension can parse predicates and data if (ext->parsePred == NULL) { cout << "Extension can't parse predicates." << endl; return; } if (ext->parseData == NULL) { cout << "Extension can't parse data." << endl; return; } char key[gist_p::max_tup_sz]; int klen; char data[gist_p::max_tup_sz]; int dlen; if (ext->parsePred(kstr, key, klen) != RCOK) { cout << "can't parse key" << endl; return; } if (ext->parseData(dstr, data, dlen) != RCOK) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -