• No results found

For testing the read performance of the MongoDB store with real world data, the database content of a Tricia installation with approximately 440.000 rows was used. The test itself consisted of 20 simulated users who vised the start page, some wikis and group pages simultaneously. Each test run made 1600 requests to the Tricia instance and was performed on a virtual machine with Windows Vista 64 Bit on an Intel Xeon processor with 2,5GHz and 1,5GB of RAM.

Table 7.2 shows some of the results of this test. MongoDB performed most queries faster than any of the two other databases. The query with the slowest average time to MongoDB took a little bit longer than the slowest query in MySQL, how- ever MongoDB performed the next slowest queries a lot faster than MySQL. In total MongoDB was more than three times quicker as MySQL and more than two times faster than HSQL, despite that the join operations were not performed in- side the database. The results of the MonitorStore showed that the join operations performed by the MongoQuery class did not have a noticeable impact on the per- formance.

The total times in table 7.2 show how much time was spent for the ve database operations, which consumed the most time during the test.

MySQL HSQL MongoDB

Total time spent

for db operations 3375s 2315s 948s

Average times of the ve slowest operations in ms

1140, 890, 775,

763, 578 1461, 777, 648,547, 491 1306, 208, 142,139, 109 The ve greatest

total times in s 1137, 494, 404,297, 136 970, 270, 209, 186,121 433, 150, 105, 90,56 Table 7.2: Performance results with real world data.

8 Conclusion

This work has shown that there are a lot of dierences between current NoSQL implementations. This is not a surprising result, because none of the examined databases aim to be the perfect solution for every problem. Instead each database has its own properties and features, so that developers have to choose the right database depended on the requirements of their project. Therefore this work com- pared the trade-os of the examined database implementations and explained why these are necessary.

Furthermore was an Object-relational Persistence Layer based on a NoSQL database for a Web Collaboration and Knowledge Management Software successfully imple- mented. This showed that NoSQL databases can fulll the requirements of such an application. It has also shown that the usage of a NoSQL database can increase the performance signicantly, even on a single machine. Aside from this was the development process for the replacement of a persistence layer of an already existing application outlined.

Using MongoDB for the persistence layer also has some disadvantages compared to established relational databases like MySQL. The biggest problem with MongoDB is the durability. By using memory mapped les, MongoDB becomes very vulner- able to power failures and other kinds of system failures [6].

The other problem is the administration, because MongoDB has no built in graph- ical conguration tools or graphical query browsers yet. There are some projects which attempt to provide graphical user interfaces for the administration of Mon- goDB databases [1], but they are currently not in a state comparable to the ones of the already established databases.

The prototype implementation instruments join operations that are performed by the client to realize the relations between the entities. Even though this imple- mentation was faster then the counterparts for MySQL, the performance could be even more increased through the usage of nested documents in MongoDB. But this would have required more fundamental changes in the architecture of the persistence layer.

8. Conclusion

Another interesting topic for future works could be the implementation of support layers for other NoSQL databases for Tricia, which would give the opportunity to compare the performance of them with real world data.

A Listing of MongoQuery.java

package de . i n f o a s s e t . platform . s t o r e . mongodb ;

import java . u t i l . HashMap ;

import java . u t i l . I t e r a t o r ;

5 import java . u t i l . L i s t ;

import com . google . common . c o l l e c t . Maps ;

import com . mongodb . BasicDBList ;

import com . mongodb . BasicDBObject ;

10 import com . mongodb . DBCursor ;

import de . i n f o a s s e t . platform . s e r v i c e s . Loggers ;

import de . i n f o a s s e t . platform . s t o r e . AbstractAttribute ;

import de . i n f o a s s e t . platform . s t o r e . AbstractQuery ;

15 import de . i n f o a s s e t . platform . s t o r e . AbstractQueryVisitor ;

import de . i n f o a s s e t . platform . s t o r e . Container ;

import de . i n f o a s s e t . platform . s t o r e . Content ;

import de . i n f o a s s e t . platform . s t o r e . Join ;

import de . i n f o a s s e t . platform . s t o r e . Query ;

20 import de . i n f o a s s e t . platform . s t o r e . QueryCondition ;

import de . i n f o a s s e t . platform . s t o r e . QueryEquals ;

import de . i n f o a s s e t . platform . s t o r e . QueryGreater ;

import de . i n f o a s s e t . platform . s t o r e . QueryGreaterOrEqual ;

import de . i n f o a s s e t . platform . s t o r e . QueryLess ;

25 import de . i n f o a s s e t . platform . s t o r e . QueryLessOrEqual ;

import de . i n f o a s s e t . platform . s t o r e . QueryNot ;

import de . i n f o a s s e t . platform . s t o r e . S o r t i n g C r i t e r i o n ;

p u b l i c c l a s s MongoQuery {

30

/∗∗ The Container a g a i n s t t h i s query i s made . ∗/ MongoContainer c o n t a i n e r ;

/∗∗ The query as mongodb o b j e c t . ∗/

35 BasicDBObject mongoQuery = new BasicDBObject ( ) ;

/∗∗ The second part o f the query , i f the query c o n t a i n s a j o i n operation . ∗/

A. Listing of MongoQuery.java

boolean j o i n = f a l s e ;

/∗ The c o n t a i n e r that i s used f o r the joinedQuery . ∗/ MongoContainer jo i n C o n ta in e r ;

45

/∗

∗ The name o f the a t t r i b u t e which i s used to j o i n the q u e r i e s on the l e f t

∗ s i d e o f the query . ∗/

50 S t r i n g l e f t J o i n A t t r i b u t e ;

/∗

∗ The name o f the a t t r i b u t e which i s used to j o i n the q u e r i e s on the s i d e

∗ o f the j o i n e d query .

55 ∗/

S t r i n g r i g h t J o i n A t t r i b u t e ;

/∗ The o r d e r i n g o f the query . ∗/

BasicDBObject orderBy = new BasicDBObject ( ) ;

60

/∗ The o r d e r i n g o f the j o i n part o f the query . ∗/

BasicDBObject joinOrderBy = new BasicDBObject ( ) ;

p u b l i c MongoQuery ( MongoContainer mongoContainer , AbstractQuery q ,

65 List <String > types ) {

t h i s. c o n t a i n e r = mongoContainer ; buildQuery (q , types ) ;

}

70 /∗ Analyzes q u e r i e s and prepares them f o r mongodb . ∗/

p r i v a t e void buildQuery ( AbstractQuery q , List <String > types ) {

i f ( ! ( q i n s t a n c e o f Query ) ) {

i f ( Loggers . mongoLog . isDebugEnabled ( ) ) {

Loggers . mongoLog . debug ( " unsupported query type "

75 + q . g e t C la s s ( ) ) ;

} }

Query query = ( Query ) q ;

i f ( Loggers . mongoLog . isDebugEnabled ( ) ) {

80 Loggers . mongoLog . debug ( " buildQuery f o r : " + query

+ " in " + c o n t a i n e r . getTableName ( ) ) ; }

// Create type c o n d i t i o n s

85 i f ( types != n u l l) {

i f ( types . s i z e ( ) == 1) {

mongoQuery . put ( " type " , types . get ( 0 ) ) ; } e l s e i f ( types . s i z e ( ) > 1) {

// use the $in operator f o r m u l t i p l e types

A. Listing of MongoQuery.java

90 BasicDBList t y p e L i s t = new BasicDBList ( ) ;

i n t i = 0 ;

f o r ( S t r i n g type : types ) { t y p e L i s t . put ( i ++,type ) ; }

95 mongoQuery . put ( " type " ,new BasicDBObject ( " $in " ,

t y p e L i s t ) ) ; }

}

100 // v i s i t a l l parts o f the query

query . v i s i t (new AbstractQueryVisitor ( ) {

// t h i s map s t o r e s a l l already v i s i t e d equals c o n d i t i o n s HashMap<QueryEquals , QueryEquals> used = Maps

. newHashMap ( ) ;

105

@Override

protected void visitOp ( Query q ) {

i f ( used . containsKey ( q ) )

// do not look again on an already v i s i t e d query

110 return;

// handle j o i n o p e r a t i o n s

f o r ( Join j : q . g e t J o i n s ( ) ) {

Container cont1 = castToMongoContainer ( j . g e t F i r s t A t t r i b u t e S i g n a t u r e s ( )

115 . getContainer ( ) ) ;

Container cont2 = castToMongoContainer ( j . getSecondAttributeSignatures ( ) . getContainer ( ) ) ;

i f ( j oin C o n t a i ne r != n u l l) {

120 i f ( Loggers . mongoLog . isDebugEnabled ( ) ) {

Loggers . mongoLog

. debug ( " Queries with more than one j o i n operation are not

supported ! " ) ; } Thread . dumpStack ( ) ; 125 i f ( MongoContainer . stopOnError ( ) ) System . e x i t (−1) ; } i f ( cont1 != c o n t a i n e r ) { 130 jo in C o nt a in e r = castToMongoContainer ( cont1 ) ; l e f t J o i n A t t r i b u t e = AbstractAttribute . getColumnName ( j . getSecondAttributeSignatures ( ) ) ; 135 r i g h t J o i n A t t r i b u t e = AbstractAttribute . getColumnName ( j . g e t F i r s t A t t r i b u t e S i g n a t u r e s ( ) ) ;

A. Listing of MongoQuery.java jo in C o nt a in e r = castToMongoContainer ( cont2 ) ; 140 r i g h t J o i n A t t r i b u t e = AbstractAttribute . getColumnName ( j . getSecondAttributeSignatures ( ) ) ; l e f t J o i n A t t r i b u t e = AbstractAttribute . getColumnName ( j 145 . g e t F i r s t A t t r i b u t e S i g n a t u r e s ( ) ) ; }

// convert the id names to MongoDB id names

i f ( r i g h t J o i n A t t r i b u t e . equals ( " id " ) ) r i g h t J o i n A t t r i b u t e = "_id" ;

150 i f ( l e f t J o i n A t t r i b u t e . equals ( " id " ) )

l e f t J o i n A t t r i b u t e = "_id" ;

// t h i s query obviously has a j o i n operation j o i n = true;

}

155 // currentQuerry p o i n t s e i t h e r to mongoQuerry or to

the

// joinedQuerry

// depending on the c o n t a i n e r o f the c o n d i t i o n BasicDBObject currentQuery = mongoQuery ;

i f ( q i n s t a n c e o f QueryCondition ) {

160 QueryCondition c = ( QueryCondition ) q ;

Container cont = c . g e t A t t r i b u t e S i g n a t u r e ( ) . getContainer ( ) ;

165 i f ( ! cont . getTableName ( ) . equals (

c o n t a i n e r . getTableName ( ) ) ) { j o i n = true;

// t h i s c o n d i t i o n belongs to the joinedQuerry currentQuery = joinedQuery ; 170 } // t r a n s l a t e the d i f f e r e n t types o f c o n d i t i o n s i n t o MongoDB // c o n d i t i o n s i f ( q i n s t a n c e o f QueryEquals ) { 175 QueryEquals qe = ( QueryEquals ) q ;

currentQuery . put ( AbstractAttribute . getColumnName ( qe

. g e t A t t r i b u t e S i g n a t u r e ( ) ) , qe . getValue ( ) ) ;

180 } e l s e i f ( q i n s t a n c e o f QueryGreater ) {

QueryGreater qr = ( QueryGreater ) q ; BasicDBObject b = new BasicDBObject ( ) ; b . put ( AbstractAttribute . getColumnName ( qr

. g e t A t t r i b u t e S i g n a t u r e ( ) ) , qr

185 . getValue ( ) ) ;

currentQuery . put ( "&gt " ,b) ;

} e l s e i f ( q i n s t a n c e o f QueryGreaterOrEqual ) {

A. Listing of MongoQuery.java

QueryGreaterOrEqual qr = ( QueryGreaterOrEqual ) q ;

BasicDBObject b = new BasicDBObject ( ) ;

190 b . put ( AbstractAttribute . getColumnName ( qr

. g e t A t t r i b u t e S i g n a t u r e ( ) ) , qr . getValue ( ) ) ;

currentQuery . put ( "&gte " ,b) ; } e l s e i f ( q i n s t a n c e o f QueryLess ) {

195 QueryLess qr = ( QueryLess ) q ;

BasicDBObject b = new BasicDBObject ( ) ; b . put ( AbstractAttribute . getColumnName ( qr

. g e t A t t r i b u t e S i g n a t u r e ( ) ) , qr . getValue ( ) ) ;

200 currentQuery . put ( "&l t " , b) ;

} e l s e i f ( q i n s t a n c e o f QueryLessOrEqual ) { QueryLessOrEqual qr = ( QueryLessOrEqual ) q ; BasicDBObject b = new BasicDBObject ( ) ; b . put ( AbstractAttribute . getColumnName ( qr

205 . g e t A t t r i b u t e S i g n a t u r e ( ) ) , qr

. getValue ( ) ) ;

currentQuery . put ( "&l t e " ,b) ; } e l s e {

i f ( Loggers . mongoLog . isDebugEnabled ( ) ) {

210 Loggers . mongoLog . e r r o r ( " c o n d i t i o n type "

+ q . g e t C la s s ( )

+ " i s not supported " ) ; }

}

215 } e l s e i f ( q i n s t a n c e o f QueryNot ) {

// handle not operations , which are only supported // i f they are used to determine i f an a t t r i b u t e

i s s e t

// and can t h e r e f o r e be transformed i n t o an $ e x i s t s

// c o n d i t i o n

220 QueryNot qn = ( QueryNot ) q ;

i f ( qn . getTerm ( ) i n s t a n c e o f QueryEquals ) {

QueryEquals qe = ( QueryEquals ) qn . getTerm ( ) ; currentQuery . put ( AbstractAttribute

. getColumnName ( qe

225 . g e t A t t r i b u t e S i g n a t u r e ( ) ) ,

new BasicDBObject ( " $ e x i s t s " ,true) ) ; used . put ( qe , qe ) ;

} e l s e {

Loggers . mongoLog

230 . e r r o r ( " cannot p r o c e s s not operator " ) ;

} } }

A. Listing of MongoQuery.java

// Handle the s o r t order :

f o r ( S o r t i n g C r i t e r i o n sc : query . g e t A l l S o r t i n g C r i t e r i o n s ( ) ) { S t r i n g name = AbstractAttribute . getColumnName ( sc

240 . g e t A t t r i b u t e S i g n a t u r e ( ) ) ;

// convert id a t t r i b u t e name to MongoDB

i f (name . equals ( " id " ) ) name = "_id" ;

245 i f ( ! sc . g e t A t t r i b u t e S i g n a t u r e ( ) . getContainer ( )

. getTableName ( ) . equals ( c o n t a i n e r . getTableName ( ) ) ) {

// t h i s o r d e r i n g i n s t r u c t i o n i s f o r the joinedQuery

i f ( sc . isAscending ( ) ) { joinOrderBy . put (name , 1 ) ;

250 } e l s e {

joinOrderBy . put (name, −1) ; }

} e l s e {

// t h i s one f o r the mongoQuery

255 i f ( sc . isAscending ( ) ) {

orderBy . put (name , 1 ) ; } e l s e {

orderBy . put (name, −1) ; }

260 i f ( j o i n ) {

Loggers . mongoLog

. e r r o r ( " Sorting in the second part o f a j o i n e d query i s not supported " ) ; }

}

265 }

// some debug code :

i f ( Loggers . mongoLog . isDebugEnabled ( ) ) {

Loggers . mongoLog . debug ( " created mongoQuery : "

270 + mongoQuery ) ;

i f ( j o i n ) {

Loggers . mongoLog . debug ( " created joinedQuery : " + joinedQuery ) ;

Loggers . mongoLog . debug ( " j o i n l e f t : "

275 + l e f t J o i n A t t r i b u t e + " r i g h t : "

+ r i g h t J o i n A t t r i b u t e ) ;

Loggers . mongoLog . debug ( " orderBy : " + orderBy ) ; }

}

280 }

/∗

∗ @return An i t e r a t o r over the content o b j e c t s in the r e s u l t s e t o f t h i s

A. Listing of MongoQuery.java

∗ query

285 ∗/

p u b l i c I t e r a t o r <Content> g e t C o n t e n t I t e r a t o r (i n t l i m i t ) {

i f ( j o i n ) {

return new Con t e nt It er a t or (new J o i n I t e r a t o r ( l i m i t ) ) ; } e l s e { 290 DBCursor c u r s o r = c o n t a i n e r . g e t C o l l e c t i o n ( ) . f i n d ( mongoQuery ) ; i f ( l i m i t > 0) c u r s o r . l i m i t ( l i m i t + 1) ; c u r s o r . s o r t ( orderBy ) ;

295 return new Con t e nt It er a t or (new S i m p l e I t e r a t o r ( c u r s o r ) ) ;

} }

/∗ @return An i t e r a t o r o f the i d e n t e n t i f i e r s o f the query r e s u l t s . ∗/

300 p u b l i c I t e r a t o r <String > g e t I d I t e r a t o r (i n t l i m i t ) {

i f ( j o i n ) {

return new I d I t e r a t o r (new J o i n I t e r a t o r ( l i m i t ) ) ; } e l s e { DBCursor c u r s o r = c o n t a i n e r . g e t C o l l e c t i o n ( ) . f i n d ( 305 mongoQuery ) ; i f ( l i m i t > 0) c u r s o r . l i m i t ( l i m i t + 1) ; c u r s o r . s o r t ( orderBy ) ;

return new I d I t e r a t o r (new S i m p l e I t e r a t o r ( c u r s o r ) ) ;

310 }

}

/∗ Del e t es a l l o b j e c t s in the database that are in the query r e s u l t s e t . ∗/

p u b l i c void d e l e t e ( ) {

315 i f ( j o i n ) {

DBCursor c u r s o r = j oin C on t ain e r . g e t C o l l e c t i o n ( ) . f i n d ( joinedQuery ) ;

while ( c u r s o r . hasNext ( ) ) {

BasicDBObject obj = ( BasicDBObject ) c u r s o r . next ( ) ;

320 mongoQuery . put ( l e f t J o i n A t t r i b u t e , obj

. get ( r i g h t J o i n A t t r i b u t e ) ) ; try { c o n t a i n e r . g e t C o l l e c t i o n ( ) . remove ( mongoQuery ) ; } catch ( Exception ex ) { 325 ex . printStackTrace ( ) ; } } } e l s e { 330 c o n t a i n e r . g e t C o l l e c t i o n ( ) . remove ( mongoQuery ) ; }

A. Listing of MongoQuery.java

p u b l i c MongoContainer castToMongoContainer ( Container cont ) {

335 i f ( cont i n s t a n c e o f MongoContainer ) {

return ( MongoContainer ) cont ; } e l s e {

return ( MongoContainer ) c o n t a i n e r . g e t S t o r e ( ) . getContainer ( cont . getTableName ( ) ) ;

340 }

}

/∗ @return The s i z e o f the r e s u l t s e t o f t h i s query . ∗/

345 p u b l i c i n t count ( ) {

i f ( j o i n ) {

DBCursor c u r s o r = j oin C on t ain e r . g e t C o l l e c t i o n ( ) . f i n d ( joinedQuery ) ;

i n t sum = 0 ;

350 HashMap<String , String > used = Maps . newHashMap ( ) ;

while ( c u r s o r . hasNext ( ) ) {

BasicDBObject obj = ( BasicDBObject ) c u r s o r . next ( ) ; S t r i n g id = obj . g e t S t r i n g ( "_id" ) . t o S t r i n g ( ) ;

i f ( ! used . containsKey ( id ) ) {

355 mongoQuery . put ( l e f t J o i n A t t r i b u t e , obj

. get ( r i g h t J o i n A t t r i b u t e ) ) ; sum += c o n t a i n e r . g e t C o l l e c t i o n ( ) . f i n d ( mongoQuery ) . count ( ) ; } 360 } return sum ; } e l s e {

return c o n t a i n e r . g e t C o l l e c t i o n ( ) . f i n d ( mongoQuery ) . count ( ) ; } 365 } /∗ An I t e r a t o r f o r q u e r i e s without j o i n s . ∗/ p r i v a t e c l a s s S i m p l e I t e r a t o r implements I t e r a t o r <BasicDBObject> { DBCursor c u r s o r ; 370 p u b l i c S i m p l e I t e r a t o r ( DBCursor c u r s o r ) { t h i s. c u r s o r = c u r s o r ; } 375 @Override p u b l i c boolean hasNext ( ) { return c u r s o r . hasNext ( ) ; } 380 @Override p u b l i c BasicDBObject next ( ) {

BasicDBObject r e s u l t = ( BasicDBObject ) c u r s o r . next ( ) ;

return r e s u l t ;

A. Listing of MongoQuery.java } 385 @Override p u b l i c void remove ( ) { c u r s o r . remove ( ) ; } 390 }

/∗ This I t e r a t o r i s used f o r q u e r i e s with a j o i n operation . ∗/

p r i v a t e c l a s s J o i n I t e r a t o r implements I t e r a t o r <BasicDBObject> {

395 /∗ Cursor over the r e s u l t s o f the joinedQuery . ∗/

DBCursor joinedCursor ;

/∗ Cursor over the f i n a l r e s u l t s e t s . ∗/ DBCursor c u r s o r ;

400

/∗ The o b j e c t that was l a s t returned by next ( ) . ∗/ BasicDBObject current ;

/∗ The next o b j e c t that w i l l be returned by next ( ) . ∗/

405 BasicDBObject next ;

i n t l i m i t ;

i n t n = 0 ;

410

/∗ Already used o b j e c t s from the joinedCursor . ∗/ HashMap<String , String > used = Maps . newHashMap ( ) ;

p u b l i c J o i n I t e r a t o r (i n t l i m i t ) {

415 i f ( j oin C o n t ain er == n u l l) {

Loggers . mongoLog . e r r o r ( " j o in C o n t a i ne r n u l l " ) ; }

// i n i t the c u r s o r o f the joinedQuery

joinedCursor = j o inC o n t a in e r . g e t C o l l e c t i o n ( ) . f i n d (

420 joinedQuery ) ;

// some debug code

i f ( Loggers . mongoLog . isDebugEnabled ( ) ) {

Loggers . mongoLog . debug ( " J o i n I t e r a t o r : c u r s o r " + joinedQuery + " cursorcount : "

425 + joinedCursor . count ( ) ) ;

Loggers . mongoLog . debug ( " J o i n I t e r a t o r : c u r s o r on " + j o in C o n t a i ne r . g e t C o l l e c t i o n ( ) . getName ( ) ) ; Loggers . mongoLog . debug ( " J o i n I t e r a t o r : c u r s o r c o l l e c t i o n s i z e " 430 + j o in C o n t a i n e r . g e t C o l l e c t i o n ( ) . getCount ( ) ) ; }

A. Listing of MongoQuery.java

435 /∗ Find the f i r s t element . ∗/

searchNext ( ) ; t h i s. l i m i t = l i m i t ; } 440 @Override p u b l i c boolean hasNext ( ) { return next != n u l l; } 445 @Override p u b l i c BasicDBObject next ( ) { current = next ;

searchNext ( ) ; // the i t e r a t o r i s always a step ahead to determine i f

// th ere i s a next element

450 n++;

return current ; }

/∗

455 ∗ Find the next element . In order to do t hi s , t h i s method has

to

∗ perform the j o i n operation . ∗/

p r i v a t e void searchNext ( ) { next = n u l l;

460 i f ( c u r s o r == n u l l | | ! c u r s o r . hasNext ( ) ) {

// i f the c u r s o r cannot return anymore elements , then increment

// the joinedCursor

// u n t i l the joinedCursor has reached i t s end or a new c u r s o r i s

// found with

465 // more r e s u l t elements

while ( joinedCursor . hasNext ( )

&& ( c u r s o r == n u l l | | ! c u r s o r . hasNext ( ) ) ) { S t r i n g value = joinedCursor . next ( ) . get (

r i g h t J o i n A t t r i b u t e ) . t o S t r i n g ( ) ;

470 i f ( ! used . containsKey ( value ) ) {

used . put ( value , value ) ;

mongoQuery . put ( l e f t J o i n A t t r i b u t e , value ) ;

i f ( Loggers . mongoLog . isDebugEnabled ( ) ) { Loggers . mongoLog 475 . debug ( " J o i n I t e r a t o r : c u r s o r " + mongoQuery ) ; } c u r s o r = c o n t a i n e r . g e t C o l l e c t i o n ( ) . f i n d ( mongoQuery ) ; 480 c u r s o r . l i m i t ( l i m i t ) ; } 87

A. Listing of MongoQuery.java

} }

// i f the c u r s o r has another element , then get i t

485 i f ( c u r s o r != n u l l && c u r s o r . hasNext ( ) ) {

next = ( BasicDBObject ) c u r s o r . next ( ) ;

i f ( Loggers . mongoLog . isDebugEnabled ( ) ) {

Loggers . mongoLog . debug ( " J o i n I t e r a t o r : next " + next ) ; 490 } } } 495 @Override p u b l i c void remove ( ) {

c o n t a i n e r . deleteContent ( current . get ( "_id" ) . t o S t r i n g ( ) ) ; } } 500 /∗ An I t e r a t o r that r e t u r n s Content o b j e c t s . ∗/ p r i v a t e c l a s s Co n t en tI te ra to r implements I t e r a t o r <Content> { I t e r a t o r <BasicDBObject> i t e r ; 505 p u b l i c C o nt e nt I t er at o r ( I t e r a t o r <BasicDBObject> i t e r ) { t h i s. i t e r = i t e r ; } 510 @Override p u b l i c boolean hasNext ( ) { return i t e r . hasNext ( ) ; } 515 @Override p u b l i c Content next ( ) {

MongoContent content = c o n t a i n e r . contentFactory ( ) ; BasicDBObject dbObject = i t e r . next ( ) ;

content . i n i t i a l i z e ( container , dbObject . get ( "_id" )

520 . t o S t r i n g ( ) ,n u l l) ;

content . read ( dbObject ) ;

return content ; } 525 @Override p u b l i c void remove ( ) { i t e r . remove ( ) ; } } 530

A. Listing of MongoQuery.java p r i v a t e c l a s s I d I t e r a t o r implements I t e r a t o r <String > { I t e r a t o r <BasicDBObject> i t e r ; 535 p u b l i c I d I t e r a t o r ( I t e r a t o r <BasicDBObject> i t e r ) { t h i s. i t e r = i t e r ; } 540 @Override p u b l i c boolean hasNext ( ) { return i t e r . hasNext ( ) ; } 545 @Override p u b l i c S t r i n g next ( ) {

return i t e r . next ( ) . get ( "_id" ) . t o S t r i n g ( ) ; } 550 @Override p u b l i c void remove ( ) { i t e r . remove ( ) ; } } 555 } 89

Bibliography

[1] Tim's Daft Junk. http://blog.timgourley.com/post/453680012/ tuesday-night-tech-mongodb-ui-edition, 2010. [Online; accessed 6-April-2010].

[2] 10gen.com: BSON - MongoDB. http://www.mongodb.org/display/DOCS/ BSON, 2009. [Online; accessed 17-November-2009].

[3] 10gen.com: Home - MongoDB. http://mongodb.org/, 2009. [Online; ac- cessed 17-November-2009].

[4] 10gen.com: Querying - MongoDB. http://www.mongodb.org/display/ DOCS/Querying, 2009. [Online; accessed 17-November-2009].

[5] 10gen.com: Querying - MongoDB. http://www.mongodb.org/display/ DOCS/MapReduce, 2009. [Online; accessed 20-November-2009].

[6] 10gen.com: Durability and Repair - MongoDB. http://www.mongodb.org/ display/DOCS/Durability+and+Repair, 2010. [Online; accessed 6-April- 2010].

[7] A.Brewer, Dr.Eric: PODC keynote. http://www.cs.berkeley.edu/ ~brewer/cs262b-2004/PODC-keynote.pdf, 2000. [Online; accessed 10- Oktober-2009].

[8] acmqueue: A Conversation with Werner Vogels. http://queue.acm.org/ detail.cfm?id=1142065, 2006. [Online; accessed 10-Oktober-2009].

[9] Amazon: Amazon Simple Storage Service. http://docs. amazonwebservices.com/AmazonS3/latest/index.html?Introduction. html, 2009. [Online; accessed 14-Oktober-2009].

[10] Amazon: Amazon Simple Storage Service. http://docs. amazonwebservices.com/AmazonSimpleDB/latest/DeveloperGuide/, 2009. [Online; accessed 5-November-2009].

[11] Amazon: Amazon Simple Storage Service. http://docs. amazonwebservices.com/AmazonSimpleDB/latest/DeveloperGuide/

index.html?SDBLimits.html, 2009. [Online; accessed 5-November-2009]. [12] Apache Software Foundation: The Apache Cassandra Project. http:

Bibliography

[13] Apache Software Foundation: Welcomde to Hadoop! http://hadoop. apache.org/, 2009. [Online; accessed 25-November-2009].

[14] Apache Software Foundation: Welcome to HBase! http://hadoop. apache.org/hbase/, 2009. [Online; accessed 25-November-2009].

[15] Barrett, Ryan: Under the Covers of the Google App Engine Datastore. http://sites.google.com/site/io/ under-the-covers-of-the-google-app-engine-datastore, 2010. [Online; accessed 20-Januar-2010].

[16] Blue Coast Web: Hypertable An Open Source, High Performance, Scal- able Database. http://www.hypertable.org, 2009. [Online; accessed 25- November-2009].

[17] Burrows, M. et al.: The Chubby lock service for loosely-coupled distributed systems. In Proc. of the 7th OSDI, volume 11, 2006.

[18] Büchner, T.: Introspektive modellgetriebene Softwareentwicklung. VDM Ver- lag Dr. Müller, 2007.

[19] Büchner, T. and F. Matthes: Introspective Model-Driven Development. Lecture Notes in Computer Science, 4344:33, 2006.

[20] Chang, F., J. Dean, S. Ghemawat, W.C. Hsieh, D.A. Wallach, M. Burrows, T. Chandra, A. Fikes and R.E. Gruber: Bigtable: A dis- tributed storage system for structured data. In Proceedings of the 7th USENIX Symposium on Operating Systems Design and Implementation (OSDIâ06), 2006.

[21] cloudant.com: Cloudant: CouchDB hosting. http://cloudant.com, 2010. [Online; accessed 15-Januar-2010].

[22] Compete.com: Site Prole of amazon.com. http://siteanalytics. compete.com/amazon.com/, 2009. [Online; accessed 10-Oktober-2009].

[23] Corporation, Oracle: MySQL :: The world's most popular open source database. http://www.mysql.com, 2010. [Online; accessed 19-March-2010]. [24] Crockford, Douglas: RFC 4627 - The application/json Media Type for

JavaScript Object Notation (JSON). http://tools.ietf.org/html/rfc4627, 2006. [Online; accessed 19-Dezember-2009].

[25] Dean, J. and S. Ghemawat: MapReduce: Simplied data processing on large clusters.

[26] DeCandia, G., D. Hastorun, M. Jampani, G. Kakulapati, A. Laksh- man, A. Pilchin, S. Sivasubramanian, P. Vosshall and W. Vogels: Dynamo: amazon's highly available key-value store. ACM SIGOPS Operating Systems Review, 41(6):220, 2007.

Bibliography

[27] Development Group, The hsql: HSQLDB. http://www.mysql.com, 2010. [Online; accessed 19-March-2010].

[28] Ghemawat, S., H. Gobioff and S.T. Leung: The Google le system. ACM SIGOPS Operating Systems Review, 37(5):43, 2003.

[29] Gilbert, Seth and Nancy Lynch: Brewer's conjecture and the feasibility of consistent, available, partition-tolerant web services. SIGACT News, 33(2):51 59, 2002.

[30] Google: Google App Engine - Google Code. http://code.google.com/ intl/de/appengine/docs/whatisgoogleappengine.html, 2010. [Online; ac- cessed 20-Januar-2010].

[31] Google: How Index Building Works - Google App Engine - Google Code. http://code.google.com/intl/de/appengine/articles/index_ building.html, 2010. [Online; accessed 20-Januar-2010].

[32] Google: protobuf - Project Hosting on Google Code. http://code.google. com/p/protobuf/, 2010. [Online; accessed 22-Januar-2010].

[33] Google: Queries and Indexes - Google App Engine - Google Code. http://code.google.com/intl/de/appengine/docs/java/datastore/ queriesandindexes.html, 2010. [Online; accessed 20-Januar-2010].

[34] Ho, Ricky: Pragmatic Programming Techniques: CouchDB Implementa- tion. http://horicky.blogspot.com/2008/10/couchdb-implementation. html, 2010. [Online; accessed 16-Januar-2010].

[35] Infoasset: infoAsset : infoAsset - Tricia. http://www.infoasset.de, 2010. [Online; accessed 23-February-2010].

[36] J. Chris Anderson, Jan Lehnardt, Noah Slater: CouchDB: The Denitive Guide. http://books.couchdb.org/relax/, 2009. [Online; ac- cessed 17-Dezember-2009].

[37] Kang, B., R. Wilensky and J. Kubiatowicz: The hash history approach for reconciling mutual inconsistency. In INTERNATIONAL CONFERENCE ON DISTRIBUTED COMPUTING SYSTEMS, volume 23, pages 670677. Citeseer, 2003.

[38] Kevin Ferguson, Vijay Raghunathan, Randall Leeds: Lounge. http://tilgovi.github.com/couchdb-lounge/, 2010. [Online; accessed 15- Januar-2010].

[39] Lamport, L.: Paxos made simple. ACM SIGACT News, 32(4):1825, 2001. [40] Lamport, Leslie: Time, clocks, and the ordering of events in a distributed

system. Commun. ACM, 21(7):558565, 1978.

Bibliography

[42] Nussbaum, Daniel and Anant Agarwal: Scalability of parallel machines. Commun. ACM, 34(3):5761, 1991.

[43] Project, The Linux Information: Scalable denition by The Linux In- formation Project. http://www.linfo.org/scalable.html, 2006. [Online; accessed 15-March-2010].

[44] Reed, D. P.: NAMING AND SYNCHRONIZATION IN A DECENTRAL- IZED COMPUTER SYSTEM. Technical Report, Cambridge, MA, USA, 1978. [45] Skeen, Dale: Nonblocking commit protocols. In SIGMOD '81: Proceedings of the 1981 ACM SIGMOD international conference on Management of data, pages 133142, New York, NY, USA, 1981. ACM.

[46] Strozzi, Carlo: NoSQL - A Relational Database Management Sys- tem. http://www.strozzi.it/cgi-bin/CSA/tw7/I/en_US/nosql/Home% 20Page, 2010. [Online; accessed 6-April-2010].

[47] Stuntz, Craig: Craig Stuntz's Weblog - Multiversion Concurrency Con- trol Before InterBase. http://blogs.teamb.com/craigstuntz/dtpostname/ multiversionconcurrencycontrolbeforeinterbase/#2718, 2005. [Online; accessed 9-November-2009].

[48] Vogels, Werner: Eventual Consistenz - Revisited - All Things Dis- tributed. http://www.allthingsdistributed.com/2008/12/eventually_ consistent.html, 2008. [Online; accessed 6-November-2009].

[49] Wikipedia: ACID  Wikipedia, The Free Encyclopedia. http://en. wikipedia.org/w/index.php?title=ACID&oldid=343104240, 2010. [Online; accessed 10-February-2010].

Related documents