namespace querying

This commit is contained in:
Dwight 2007-11-01 22:34:44 -04:00
parent c7a92a191c
commit e9a5075a9b
8 changed files with 174 additions and 47 deletions

View File

@ -92,19 +92,18 @@ private:
const char *theEnd;
};
Record* findByOID(const char *ns, OID *oid) {
/*Record* findByOID(const char *ns, OID *oid) {
// temp implementation
Cursor c = theDataFileMgr.findAll(ns);
while( c.ok() ) {
Record *r = c.current();
JSObj js(r);
JSObj js = c.current();
OID *i = js.getOID();
if( i && *oid == *i )
return r;
c.advance();
}
return 0;
}
}*/
#pragma pack(push)
#pragma pack(1)
@ -179,12 +178,12 @@ void testTheDb() {
updateObjects("sys.unittest.delete", j1, j1, false);
cout << "findAll:\n";
Cursor c = theDataFileMgr.findAll("sys.unittest.pdfile");
while( c.ok() ) {
Record* r = c.current();
auto_ptr<Cursor> c = theDataFileMgr.findAll("sys.unittest.pdfile");
while( c->ok() ) {
Record* r = c->_current();
cout << " gotrec " << r->netLength() << ' ' <<
r->data << '\n';
c.advance();
c->advance();
}
cout << endl;
}

View File

@ -3,7 +3,8 @@
#pragma once
#include "../stdafx.h"
#include "pdfile.h"
#include "../util/builder.h"
//#include "pdfile.h"
#pragma pack(push)
#pragma pack(1)
@ -107,6 +108,7 @@ private:
int totalSize;
};
class Record;
class JSObj {
friend class JSElemIter;
@ -114,11 +116,12 @@ public:
JSObj(const char *msgdata) {
_objdata = msgdata;
_objsize = *((int*) _objdata);
iDelete = false;
}
JSObj(Record *r) {
_objdata = r->data;
_objsize = *((int*) _objdata);
assert( _objsize <= r->netLength() );
JSObj(Record *r);
~JSObj() {
// if( iDelete ) { free((void*)_objdata); _objdata = 0; }
}
const char *objdata() { return _objdata; }
@ -130,11 +133,54 @@ public:
return 0;
return (OID *) ++p;
}
JSObj& operator=(JSObj& r) {
iDelete = r.iDelete;
r.iDelete = false;
_objsize = r._objsize;
_objdata = r._objdata;
return *this;
}
JSObj(JSObj& r) {
*this = r;
}
bool iDelete;
private:
int _objsize;
const char *_objdata;
};
class JSObjBuilder {
public:
JSObjBuilder() { b.skip(4); /*leave room for size field*/ }
void append(const char *fieldName, double n) {
b.append((char) Number);
b.append(fieldName);
b.append(n);
}
void append(const char *fieldName, const char *str) {
b.append((char) String);
b.append(fieldName);
b.append((int) strlen(str)+1);
b.append(str);
}
JSObj done() {
b.append((char) EOO);
char *data = b.buf();
*((int*)data) = b.len();
b.decouple();
JSObj j(data);
j.iDelete = true;
return j;
}
private:
BufBuilder b;
};
class JSElemIter {
public:
JSElemIter(JSObj& jso) {
@ -152,6 +198,7 @@ private:
const char *theend;
};
/* For when a js object is a pattern... */
class JSMatcher {
public:
JSMatcher(JSObj& pattern);

View File

@ -20,6 +20,13 @@ DataFileMgr theDataFileMgr;
/* just temporary */
const int ExtentSize = 1 * 1024 * 1024;
JSObj::JSObj(Record *r) {
_objdata = r->data;
_objsize = *((int*) _objdata);
assert( _objsize <= r->netLength() );
iDelete = false;
}
/*---------------------------------------------------------------------*/
int bucketSizes[] = {
@ -140,6 +147,7 @@ DiskLoc NamespaceDetails::_alloc(int len) {
}
class NamespaceIndex {
friend class NamespaceCursor;
public:
NamespaceIndex() { }
@ -175,6 +183,43 @@ private:
HashTable<Namespace,NamespaceDetails> *ht;
} namespaceIndex;
class NamespaceCursor : public Cursor {
public:
virtual bool ok() { return i >= 0; }
virtual Record* _current() { assert(false); return 0; }
virtual DiskLoc currLoc() { assert(false); return DiskLoc(); }
virtual JSObj current() {
NamespaceDetails &d = namespaceIndex.ht->nodes[i].value;
JSObjBuilder b;
b.append("name", namespaceIndex.ht->nodes[i].k.buf);
return b.done();
}
virtual bool advance() {
while( 1 ) {
i++;
if( i >= namespaceIndex.ht->n )
break;
if( namespaceIndex.ht->nodes[i].inUse() )
return true;
}
i = -1000000;
return false;
}
NamespaceCursor() {
i = -1;
advance();
}
private:
int i;
};
auto_ptr<Cursor> makeNamespaceCursor() {
return auto_ptr<Cursor>(new NamespaceCursor());
}
/*---------------------------------------------------------------------*/
void PhysicalDataFile::open(const char *filename, int length) {
@ -286,15 +331,15 @@ Record* Extent::newRecord(int len) {
/*---------------------------------------------------------------------*/
Cursor DataFileMgr::findAll(const char *ns) {
auto_ptr<Cursor> DataFileMgr::findAll(const char *ns) {
DiskLoc loc;
bool found = namespaceIndex.find(ns, loc);
if( !found ) {
cout << "info: findAll() namespace does not exist: " << ns << endl;
return Cursor(DiskLoc());
return auto_ptr<Cursor>(new BasicCursor(DiskLoc()));
}
Extent *e = temp.getExtent(loc);
return Cursor( e->firstRecord );
return auto_ptr<Cursor>(new BasicCursor( e->firstRecord ));
}
void DataFileMgr::deleteRecord(const char *ns, Record *todelete, const DiskLoc& dl)

View File

@ -5,10 +5,12 @@
#include "../stdafx.h"
#include "../util/mmap.h"
#include "storage.h"
#include "jsobj.h"
class PDFHeader;
class Extent;
class Record;
class Cursor;
/*---------------------------------------------------------------------*/
@ -36,14 +38,14 @@ public:
char buf[128];
};
/*---------------------------------------------------------------------*/
auto_ptr<Cursor> makeNamespaceCursor();
class Cursor;
/*---------------------------------------------------------------------*/
class PDFHeader;
class PhysicalDataFile {
friend class DataFileMgr;
friend class Cursor;
friend class BasicCursor;
public:
void open(const char *filename, int length = 64 * 1024 * 1024);
@ -59,7 +61,7 @@ private:
};
class DataFileMgr {
friend class Cursor;
friend class BasicCursor;
public:
void init();
@ -69,7 +71,7 @@ public:
const char *buf, int len);
void insert(const char *ns, const void *buf, int len);
void deleteRecord(const char *ns, Record *todelete, const DiskLoc& dl);
Cursor findAll(const char *ns);
auto_ptr<Cursor> findAll(const char *ns);
static Extent* getExtent(const DiskLoc& dl);
static Record* getRecord(const DiskLoc& dl);
@ -210,22 +212,37 @@ inline Extent* PhysicalDataFile::getExtent(DiskLoc loc) {
class Cursor {
public:
bool ok() { return !curr.isNull(); }
virtual bool ok() = 0;
bool eof() { return !ok(); }
Record* current() {
virtual Record* _current() = 0;
virtual JSObj current() = 0;
virtual DiskLoc currLoc() = 0;
virtual bool advance() = 0;
};
class BasicCursor : public Cursor {
public:
bool ok() { return !curr.isNull(); }
Record* _current() {
assert( ok() );
return theDataFileMgr.temp.recordAt(curr);
}
JSObj current() {
return JSObj( _current() );
}
virtual DiskLoc currLoc() { return curr; }
bool advance() {
if( eof() )
return false;
Record *r = current();
Record *r = _current();
curr = r->getNext(curr);
return ok();
}
Cursor(DiskLoc dl) : curr(dl) { }
Cursor() { }
BasicCursor(DiskLoc dl) : curr(dl) { }
BasicCursor() { }
DiskLoc curr;
};

View File

@ -14,11 +14,11 @@ void deleteObjects(const char *ns, JSObj pattern, bool justOne) {
JSMatcher matcher(pattern);
Cursor c = theDataFileMgr.findAll(ns);
while( c.ok() ) {
Record *r = c.current();
DiskLoc rloc = c.curr;
c.advance(); // must advance before deleting as the next ptr will die
auto_ptr<Cursor> c = theDataFileMgr.findAll(ns);
while( c->ok() ) {
Record *r = c->_current();
DiskLoc rloc = c->currLoc();
c->advance(); // must advance before deleting as the next ptr will die
JSObj js(r);
if( matcher.matches(js) ) {
cout << " found match to delete" << endl;
@ -35,16 +35,16 @@ void updateObjects(const char *ns, JSObj updateobj, JSObj pattern, bool upsert)
JSMatcher matcher(pattern);
Cursor c = theDataFileMgr.findAll(ns);
while( c.ok() ) {
Record *r = c.current();
auto_ptr<Cursor> c = theDataFileMgr.findAll(ns);
while( c->ok() ) {
Record *r = c->_current();
JSObj js(r);
if( matcher.matches(js) ) {
cout << " found match to update" << endl;
theDataFileMgr.update(ns, r, c.curr, updateobj.objdata(), updateobj.objsize());
theDataFileMgr.update(ns, r, c->currLoc(), updateobj.objdata(), updateobj.objsize());
return;
}
c.advance();
c->advance();
}
cout << " no match found. ";
@ -67,20 +67,21 @@ QueryResult* runQuery(const char *ns, int ntoreturn, JSObj jsobj) {
b.skip(sizeof(QueryResult));
int n = 0;
Cursor c = theDataFileMgr.findAll(ns);
while( c.ok() ) {
Record *r = c.current();
JSObj js(r);
auto_ptr<Cursor> c =
strcmp(ns, "system.namespaces") == 0 ?
makeNamespaceCursor() :
theDataFileMgr.findAll(ns);
while( c->ok() ) {
JSObj js = c->current();
if( matcher.matches(js) ) {
assert( js.objsize() <= r->netLength() );
b.append(r->data, js.objsize());
b.append((void*) js.objdata(), js.objsize());
n++;
if( n >= ntoreturn && ntoreturn != 0 )
break;
}
c.advance();
c->advance();
}
qr = (QueryResult *) b.buf();

View File

@ -46,3 +46,16 @@ typedef void *HANDLE;
#define null (0)
#include <vector>
// for debugging
typedef struct _Ints { int i[100]; } *Ints;
typedef struct _Chars { char c[200]; } *Chars;
typedef char CHARS[400];
typedef struct _OWS {
int size;
char type;
char string[400];
} *OWS;

View File

@ -2,6 +2,8 @@
*/
#pragma once
#include "../stdafx.h"
class BufBuilder {
@ -10,7 +12,9 @@ public:
data = (char *) malloc(size);
l = 0;
}
~BufBuilder() {
~BufBuilder() { kill(); }
void kill() {
if( data ) {
free(data);
data = 0;

View File

@ -21,12 +21,13 @@ template <
class Type
>
class HashTable {
private:
public:
const char *name;
struct Node {
int hash;
Key k;
Type value;
bool inUse() { return hash != 0; }
} *nodes;
int n;
@ -37,7 +38,7 @@ private:
int start = i;
int chain = 0;
while( 1 ) {
if( nodes[i].hash == 0 ) {
if( !nodes[i].inUse() ) {
return i;
}
if( nodes[i].hash == h && nodes[i].k == k ) {