namespace querying
This commit is contained in:
parent
c7a92a191c
commit
e9a5075a9b
15
db/db.cpp
15
db/db.cpp
@ -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;
|
||||
}
|
||||
|
||||
57
db/jsobj.h
57
db/jsobj.h
@ -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);
|
||||
|
||||
@ -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)
|
||||
|
||||
37
db/pdfile.h
37
db/pdfile.h
@ -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;
|
||||
};
|
||||
|
||||
37
db/query.cpp
37
db/query.cpp
@ -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();
|
||||
|
||||
13
stdafx.h
13
stdafx.h
@ -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;
|
||||
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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 ) {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user