diff options
author | Dwight <dmerriman@gmail.com> | 2008-09-09 10:19:31 -0400 |
---|---|---|
committer | Dwight <dmerriman@gmail.com> | 2008-09-09 10:19:31 -0400 |
commit | 98d4a02dcbb943961c0c30e3b556bd4150f62c4c (patch) | |
tree | 5ec54d56da27cacffcc89d985e9eac3c1b5d2d37 /db | |
parent | 8dd8937576635dbe8da2ea4cce90854ab79aeb19 (diff) | |
download | mongo-98d4a02dcbb943961c0c30e3b556bd4150f62c4c.tar.gz |
dbgrid start
Diffstat (limited to 'db')
-rw-r--r-- | db/db.sln | 6 | ||||
-rw-r--r-- | db/db.vcproj | 16 | ||||
-rw-r--r-- | db/jsobj.cpp | 458 | ||||
-rw-r--r-- | db/makefile | 8 | ||||
-rw-r--r-- | db/query.cpp | 10 |
5 files changed, 26 insertions, 472 deletions
diff --git a/db/db.sln b/db/db.sln index 9ebc444204b..43585735798 100644 --- a/db/db.sln +++ b/db/db.sln @@ -3,6 +3,8 @@ Microsoft Visual Studio Solution File, Format Version 10.00 # Visual Studio 2008
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "db", "db.vcproj", "{215B2D68-0A70-4D10-8E75-B31010C62A91}"
EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "dbgrid", "..\dbgrid\dbgrid.vcproj", "{E03717ED-69B4-4D21-BC55-DF6690B585C6}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
@@ -13,6 +15,10 @@ Global {215B2D68-0A70-4D10-8E75-B31010C62A91}.Debug|Win32.Build.0 = Debug|Win32
{215B2D68-0A70-4D10-8E75-B31010C62A91}.Release|Win32.ActiveCfg = Release|Win32
{215B2D68-0A70-4D10-8E75-B31010C62A91}.Release|Win32.Build.0 = Release|Win32
+ {E03717ED-69B4-4D21-BC55-DF6690B585C6}.Debug|Win32.ActiveCfg = Debug|Win32
+ {E03717ED-69B4-4D21-BC55-DF6690B585C6}.Debug|Win32.Build.0 = Debug|Win32
+ {E03717ED-69B4-4D21-BC55-DF6690B585C6}.Release|Win32.ActiveCfg = Release|Win32
+ {E03717ED-69B4-4D21-BC55-DF6690B585C6}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/db/db.vcproj b/db/db.vcproj index 6ab824bf3c7..ece0d5c6bf4 100644 --- a/db/db.vcproj +++ b/db/db.vcproj @@ -215,6 +215,10 @@ >
</File>
<File
+ RelativePath=".\matcher.cpp"
+ >
+ </File>
+ <File
RelativePath="..\grid\message.cpp"
>
</File>
@@ -403,10 +407,6 @@ Name="misc"
>
<File
- RelativePath=".\how_to_build.txt"
- >
- </File>
- <File
RelativePath=".\makefile"
>
</File>
@@ -426,14 +426,6 @@ RelativePath="..\pcre-7.4\pcrecpp.h"
>
</File>
- <File
- RelativePath=".\testdb.js"
- >
- </File>
- <File
- RelativePath=".\todo.txt"
- >
- </File>
</Filter>
<Filter
Name="libs_etc"
diff --git a/db/jsobj.cpp b/db/jsobj.cpp index 51c8df5f1a3..8687321f3e4 100644 --- a/db/jsobj.cpp +++ b/db/jsobj.cpp @@ -19,101 +19,6 @@ #include "stdafx.h" #include "jsobj.h" #include "../util/goodies.h" -#include "javajs.h" - -#if defined(_WIN32) - -#include <hash_map> -using namespace stdext; - -typedef const char * MyStr; -struct less_str { - bool operator()(const MyStr & x, const MyStr & y) const { - if ( strcmp(x, y) > 0) - return true; - - return false; - } -}; - -typedef hash_map<const char*, int, hash_compare<const char *, less_str> > strhashmap; - -#else - -#include <ext/hash_map> -using namespace __gnu_cxx; - -typedef const char * MyStr; -struct eq_str { - bool operator()(const MyStr & x, const MyStr & y) const { - if ( strcmp(x, y) == 0) - return true; - - return false; - } -}; - -typedef hash_map<const char*, int, hash<const char *>, eq_str > strhashmap; - -#endif - -#include "minilex.h" - -MiniLex minilex; - -class Where { -public: - Where() { codeCopy = 0; } - ~Where() { - JavaJS->scopeFree(scope); - delete codeCopy; - scope = 0; func = 0; codeCopy = 0; - } - jlong scope, func; - strhashmap fields; -// map<string,int> fields; - bool fullObject; - int nFields; - char *codeCopy; - - void setFunc(const char *code) { - codeCopy = new char[strlen(code)+1]; - strcpy(codeCopy,code); - func = JavaJS->functionCreate( code ); - minilex.grabVariables(codeCopy, fields); - // if user references db, eg db.foo.save(obj), - // we make sure we have the whole thing. - fullObject = fields.count("fullObject") + - fields.count("db") > 0; - nFields = fields.size(); - } - - void buildSubset(JSObj& src, JSObjBuilder& dst) { - JSElemIter it(src); - int n = 0; - if( !it.more() ) return; - while( 1 ) { - Element e = it.next(); - if( e.eoo() ) - break; - if( //n == 0 && - fields.find(e.fieldName()) != fields.end() - //fields.count(e.fieldName()) - ) { - dst.append(e); - if( ++n >= nFields ) - break; - } - } - } -}; - -JSMatcher::~JSMatcher() { - for( int i = 0; i < nBuilders; i++ ) - delete builders[i]; - delete in; - delete where; -} Element nullElement; @@ -334,304 +239,6 @@ int getGtLtOp(Element& e) { return op; } -#include "pdfile.h" - -JSMatcher::JSMatcher(JSObj &_jsobj) : - in(0), where(0), jsobj(_jsobj), nRegex(0) -{ - nBuilders = 0; - - JSElemIter i(jsobj); - n = 0; - while( i.more() ) { - Element e = i.next(); - if( e.eoo() ) - break; - - if( e.type() == Code && strcmp(e.fieldName(), "$where")==0 ) { - // $where: function()... - assert( where == 0 ); - where = new Where(); - const char *code = e.valuestr(); - massert( "$where query, but jni is disabled", JavaJS ); - where->scope = JavaJS->scopeCreate(); - JavaJS->scopeSetString(where->scope, "$client", client->name.c_str()); - where->setFunc(code); - continue; - } - - if( e.type() == RegEx ) { - if( nRegex >= 4 ) { - cout << "ERROR: too many regexes in query" << endl; - } - else { - pcrecpp::RE_Options options; - options.set_utf8(true); - const char *flags = e.regexFlags(); - while( flags && *flags ) { - if( *flags == 'i' ) - options.set_caseless(true); - else if( *flags == 'm' ) - options.set_multiline(true); - else if( *flags == 'x' ) - options.set_extended(true); - flags++; - } - regexs[nRegex].re = new pcrecpp::RE(e.regex(), options); - regexs[nRegex].fieldName = e.fieldName(); - nRegex++; - } - continue; - } - - // greater than / less than... - // e.g., e == { a : { $gt : 3 } } - // or - // { a : { $in : [1,2,3] } } - if( e.type() == Object ) { - // e.g., fe == { $gt : 3 } - JSElemIter j(e.embeddedObject()); - bool ok = false; - while( j.more() ) { - Element fe = j.next(); - if( fe.eoo() ) - break; - // Element fe = e.embeddedObject().firstElement(); - const char *fn = fe.fieldName(); - if( fn[0] == '$' && fn[1] ) { - if( fn[2] == 't' ) { - int op = Equality; - if( fn[1] == 'g' ) { - if( fn[3] == 0 ) op = GT; - else if( fn[3] == 'e' && fn[4] == 0 ) op = GTE; - } - else if( fn[1] == 'l' ) { - if( fn[3] == 0 ) op = LT; - else if( fn[3] == 'e' && fn[4] == 0 ) op = LTE; - } - if( op && nBuilders < 8) { - JSObjBuilder *b = new JSObjBuilder(); - builders[nBuilders++] = b; - b->appendAs(fe, e.fieldName()); - toMatch.push_back( b->done().firstElement() ); - compareOp.push_back(op); - n++; - ok = true; - } - } - else if( fn[1] == 'i' && fn[2] == 'n' && fn[3] == 0 && fe.type() == Array ) { - // $in - assert( in == 0 ); // only one per query supported so far. finish... - in = new set<Element,element_lt>(); - JSElemIter i(fe.embeddedObject()); - if( i.more() ) { - while( 1 ) { - Element ie = i.next(); - if( ie.eoo() ) - break; - in->insert(ie); - } - } - toMatch.push_back(e); // not actually used at the moment - compareOp.push_back(opIN); - n++; - ok = true; - } - } - else { - ok = false; - break; - } - } - if( ok ) - continue; - } - - { - // normal, simple case e.g. { a : "foo" } - toMatch.push_back(e); - compareOp.push_back(Equality); - n++; - } - } -} - -inline int JSMatcher::valuesMatch(Element& l, Element& r, int op) { - if( op == 0 ) - return l.valuesEqual(r); - - if( op == opIN ) { - // { $in : [1,2,3] } - int c = in->count(l); - return c; - } - - /* check LT, GTE, ... */ - if( l.type() != r.type() ) - return false; - int c = compareElementValues(l, r); - int z = 1 << (c+1); - return (op & z); -} - -/* Check if a particular field matches. - - fieldName - field to match "a.b" if we are reaching into an embedded object. - toMatch - element we want to match. - obj - database object to check against - compareOp - Equality, LT, GT, etc. - deep - out param. set to true/false if we scanned an array - isArr - - - Special forms: - - { "a.b" : 3 } means obj.a.b == 3 - { a : { $lt : 3 } } means obj.a < 3 - { a : { $in : [1,2] } } means [1,2].contains(obj.a) - - return value - -1 mismatch - 0 missing element - 1 match -*/ -int JSMatcher::matchesDotted(const char *fieldName, Element& toMatch, JSObj& obj, int compareOp, bool *deep, bool isArr) { - { - const char *p = strchr(fieldName, '.'); - if( p ) { - string left(fieldName, p-fieldName); - - Element e = obj.getField(left.c_str()); - if( e.eoo() ) - return 0; - if( e.type() != Object && e.type() != Array ) - return -1; - - JSObj eo = e.embeddedObject(); - return matchesDotted(p+1, toMatch, eo, compareOp, deep, e.type() == Array); - } - } - - Element e = obj.getField(fieldName); - - if( valuesMatch(e, toMatch, compareOp) ) { - return 1; - } - else if( e.type() == Array ) { - JSElemIter ai(e.embeddedObject()); - while( ai.more() ) { - Element z = ai.next(); - if( valuesMatch( z, toMatch, compareOp) ) { - if( deep ) - *deep = true; - return 1; - } - } - } - else if( isArr ) { - JSElemIter ai(obj); - while( ai.more() ) { - Element z = ai.next(); - if( z.type() == Object ) { - JSObj eo = z.embeddedObject(); - int cmp = matchesDotted(fieldName, toMatch, eo, compareOp, deep); - if( cmp > 0 ) { - if( deep ) *deep = true; - return 1; - } - } - } - } - else if( e.eoo() ) { - return 0; - } - return -1; -} - -extern int dump; - -inline bool _regexMatches(RegexMatcher& rm, Element& e) { - char buf[64]; - const char *p = buf; - if( e.type() == String || e.type() == Symbol ) - p = e.valuestr(); - else if( e.type() == Number ) { - sprintf(buf, "%f", e.number()); - } - else if( e.type() == Date ) { - unsigned long long d = e.date(); - time_t t = (d/1000); - time_t_to_String(t, buf); - } - else - return false; - return rm.re->PartialMatch(p); -} -/* todo: internal dotted notation scans -- not done yet here. */ -inline bool regexMatches(RegexMatcher& rm, Element& e, bool *deep) { - if( e.type() != Array ) - return _regexMatches(rm, e); - - JSElemIter ai(e.embeddedObject()); - while( ai.more() ) { - Element z = ai.next(); - if( _regexMatches(rm, z) ) { - if( deep ) - *deep = true; - return true; - } - } - return false; -} - -/* See if an object matches the query. - deep - return true when meanswe looked into arrays for a match -*/ -bool JSMatcher::matches(JSObj& jsobj, bool *deep) { - if( deep ) - *deep = false; - - /* assuming there is usually only one thing to match. if more this - could be slow sometimes. */ - - // check normal non-regex cases: - for( int i = 0; i < n; i++ ) { - Element& m = toMatch[i]; - int cmp = matchesDotted(toMatch[i].fieldName(), toMatch[i], jsobj, compareOp[i], deep); - - /* missing is ok iff we were looking for null */ - if( cmp < 0 ) - return false; - if( cmp == 0 && (m.type() != jstNULL && m.type() != Undefined ) ) - return false; - } - - for( int r = 0; r < nRegex; r++ ) { - RegexMatcher& rm = regexs[r]; - Element e = jsobj.getFieldDotted(rm.fieldName); - if( e.eoo() ) - return false; - if( !regexMatches(rm, e, deep) ) - return false; - } - - if( where ) { - if( where->func == 0 ) - return false; // didn't compile - if( jsobj.objsize() < 200 || where->fullObject ) { - JavaJS->scopeSetObject(where->scope, "obj", &jsobj); - } else { - JSObjBuilder b; - where->buildSubset(jsobj, b); - JSObj temp = b.done(); - JavaJS->scopeSetObject(where->scope, "obj", &temp); - } - if( JavaJS->invoke(where->scope, where->func) ) - return false; - return JavaJS->scopeGetBoolean(where->scope, "return") != 0; - } - - return true; -} /* JSObj ------------------------------------------------------------*/ @@ -829,7 +436,6 @@ int JSObj::addFields(JSObj& from, set<string>& fields) { /*-- test things ----------------------------------------------------*/ #pragma pack(push,1) - struct MaxKeyData { MaxKeyData() { totsize=7; maxkey=MaxKey; name=0; eoo=EOO; } int totsize; @@ -844,6 +450,7 @@ struct JSObj0 { int totsize; char eoo; } js0; +#pragma pack(pop) Element::Element() { data = &js0.eoo; @@ -851,60 +458,13 @@ Element::Element() { totalSize = -1; } -struct JSObj1 js1; - -struct JSObj2 { - JSObj2() { - totsize=sizeof(JSObj2); - s = String; strcpy_s(sname, 7, "abcdef"); slen = 10; - strcpy_s(sval, 10, "123456789"); eoo = EOO; - } - unsigned totsize; - char s; - char sname[7]; - unsigned slen; - char sval[10]; - char eoo; -} js2; - -struct JSUnitTest { - JSUnitTest() { - JSObj j1((const char *) &js1); - JSObj j2((const char *) &js2); - JSMatcher m(j2); - assert( m.matches(j1) ); - js2.sval[0] = 'z'; - assert( !m.matches(j1) ); - JSMatcher n(j1); - assert( n.matches(j1) ); - assert( !n.matches(j2) ); - - JSObj j0((const char *) &js0); - JSMatcher p(j0); - assert( p.matches(j1) ); - assert( p.matches(j2) ); - } -} jsunittest; - +#pragma pack(push,1) +struct EmptyObject { + EmptyObject() { len = 5; jstype = EOO; } + int len; + char jstype; +} emptyObject; #pragma pack(pop) -struct RXTest { - RXTest() { - /* - static const boost::regex e("(\\d{4}[- ]){3}\\d{4}"); - static const boost::regex b("....."); - cout << "regex result: " << regex_match("hello", e) << endl; - cout << "regex result: " << regex_match("abcoo", b) << endl; - */ - pcrecpp::RE re1(")({a}h.*o"); - pcrecpp::RE re("h.llo"); - assert( re.FullMatch("hello") ); - assert( !re1.FullMatch("hello") ); - - - pcrecpp::RE_Options options; - options.set_utf8(true); - pcrecpp::RE part("dwi", options); - assert( part.PartialMatch("dwight") ); - } -} rxtest; +JSObj emptyObj((char *) &emptyObject); + diff --git a/db/makefile b/db/makefile index a199765173d..abbf77161be 100644 --- a/db/makefile +++ b/db/makefile @@ -5,12 +5,15 @@ FLAGS= ${CFLAGS} -fPIC -ggdb -pthread -O3 -I .. -Isrc/p -I/src/p/db -L/usr/loca LIB_DEPS = -lpcrecpp -lpcre LIB_BOOST = -lboost_thread -lboost_filesystem -LIBS= $(LIB_DEPS) $(LIB_BOOST) -lstdc++ +LIBS= $(LIB_DEPS) $(LIB_BOOST) -lstdc++ +DBGRID_LIBS = $(LIB_BOOST) -lstdc++ JVM_LIBS = -L/opt/java/lib/ OBJS=../stdafx.o ../util/sock.o ../grid/message.o ../util/mmap.o pdfile.o query.o jsobj.o introspect.o btree.o clientcursor.o ../util/util.o javajs.o tests.o json.o repl.o dbclient.o btreecursor.o cloner.o namespace.o +DBGRID_OBJS=../stdafx.o ../util/sock.o ../grid/message.o ../util/util.o dbclient.o ../dbgrid/dbgrid.o + # ../grid/protorecv.o ../grid/protosend.o GPP = g++ @@ -41,6 +44,9 @@ _REQ_GPP_VER = 4.2 db: $(OBJS) db.o $(GPP) $(FLAGS) -o $@ $(OBJS) db.o $(LIBS) $(JVM_LIBS) # -./db quicktest + +dbgrid: $(DBGRID_OBJS) ../dbgrid/dbgrid.o + $(GPP) $(FLAGS) -o $@ $(DBGRID_OBJS) $(DBGRID_LIBS) javatest: javatest.o $(OBJS) $(GPP) $(FLAGS) -o $@ javatest.o $(OBJS) $(LIBS) $(JVM_LIBS) diff --git a/db/query.cpp b/db/query.cpp index 47522d8818c..3e29977f461 100644 --- a/db/query.cpp +++ b/db/query.cpp @@ -41,16 +41,6 @@ LRUishMap<JSObj,DiskLoc,5> lrutest(123); int nextCursorId = 1; extern bool useCursors; -#pragma pack(push,1) -struct EmptyObject { - EmptyObject() { len = 5; jstype = EOO; } - int len; - char jstype; -} emptyObject; -#pragma pack(pop) - -JSObj emptyObj((char *) &emptyObject); - int getGtLtOp(Element& e); void appendElementHandlingGtLt(JSObjBuilder& b, Element& e); int runCount(const char *ns, JSObj& cmd, string& err); |