1
0
Fork 0

added tests and documentation for volatile collections

This commit is contained in:
Jan Steemann 2013-01-07 10:55:25 +01:00
parent 36a3ebe2ae
commit d76920443d
17 changed files with 324 additions and 60 deletions

View File

@ -9,6 +9,7 @@ location: /_api/collection/179665369
"name": "UnitTestsCollectionBasics", "name": "UnitTestsCollectionBasics",
"code": 200, "code": 200,
"waitForSync": false, "waitForSync": false,
"isVolatile": false,
"id": 179665369, "id": 179665369,
"status": 3, "status": 3,
"type" : 2, "type" : 2,
@ -26,6 +27,7 @@ location: /_api/collection/184354432
"name": "UnitTestsCollectionEdges", "name": "UnitTestsCollectionEdges",
"code": 200, "code": 200,
"waitForSync": false, "waitForSync": false,
"isVolatile": false,
"id": 184354432, "id": 184354432,
"status": 3, "status": 3,
"type": 3, "type": 3,

View File

@ -7,6 +7,7 @@ content-type: application/json
"name": "UnitTestsCollectionBasics", "name": "UnitTestsCollectionBasics",
"code": 200, "code": 200,
"waitForSync": true, "waitForSync": true,
"isVolatile": false,
"id": 73482, "id": 73482,
"journalSize": 33554432, "journalSize": 33554432,
"count": 0, "count": 0,

View File

@ -26,6 +26,7 @@ location: /_api/collection/73482/figures
} }
}, },
"waitForSync": true, "waitForSync": true,
"isVolatile": false,
"id": 73482, "id": 73482,
"journalSize": 134217728, "journalSize": 134217728,
"count": 0, "count": 0,

View File

@ -8,6 +8,7 @@ content-type: application/json
"name": "UnitTestsCollectionBasics", "name": "UnitTestsCollectionBasics",
"code": 200, "code": 200,
"waitForSync": true, "waitForSync": true,
"isVolatile": false,
"id": 70109828, "id": 70109828,
"journalSize": 134217728, "journalSize": 134217728,
"status": 3, "status": 3,

View File

@ -1,2 +1,2 @@
arango> db.examples.properties() arango> db.examples.properties()
{ "waitForSync" : false, "journalSize" : 33554432 } { "waitForSync" : false, "journalSize" : 33554432, "isVolatile" : false }

View File

@ -1,2 +1,2 @@
arango> db.examples.properties({ waitForSync : false }) arango> db.examples.properties({ waitForSync : false })
{ "waitForSync" : false, "journalSize" : 33554432 } { "waitForSync" : false, "journalSize" : 33554432, "isVolatile" : false }

View File

@ -1,4 +1,4 @@
arango> c = db._create("cars"); arango> c = db._create("cars");
[ArangoCollection 111137, "cars" (status loaded)] [ArangoCollection 111137, "cars" (status loaded)]
arango> c.properties() arango> c.properties()
{ "waitForSync" : false, "journalSize" : 33554432 } { "waitForSync" : false, "journalSize" : 33554432, "isVolatile" : false }

View File

@ -1,4 +1,4 @@
arango> c = db._create("cars", { waitForSync : true, journalSize : 1024 * 1204 }); arango> c = db._create("cars", { waitForSync : true, journalSize : 1024 * 1204 });
[ArangoCollection 96384, "cars" (status loaded)] [ArangoCollection 96384, "cars" (status loaded)]
arango> c.properties() arango> c.properties()
{ "waitForSync" : true, "journalSize" : 1232896 } { "waitForSync" : true, "journalSize" : 1232896, "isVolatile" : false }

View File

@ -242,6 +242,7 @@ describe ArangoDB do
doc.parsed_response['name'].should eq(@cn) doc.parsed_response['name'].should eq(@cn)
doc.parsed_response['status'].should eq(3) doc.parsed_response['status'].should eq(3)
doc.parsed_response['waitForSync'].should eq(true) doc.parsed_response['waitForSync'].should eq(true)
doc.parsed_response['isVolatile'].should eq(false)
doc.parsed_response['journalSize'].should be_kind_of(Integer) doc.parsed_response['journalSize'].should be_kind_of(Integer)
end end
@ -330,12 +331,12 @@ describe ArangoDB do
doc.parsed_response['code'].should eq(200) doc.parsed_response['code'].should eq(200)
doc.parsed_response['id'].should be_kind_of(Integer) doc.parsed_response['id'].should be_kind_of(Integer)
doc.parsed_response['name'].should eq(@cn) doc.parsed_response['name'].should eq(@cn)
doc.parsed_response['waitForSync'].should == false doc.parsed_response['waitForSync'].should eq(false)
cmd = api + "/" + @cn + "/figures" cmd = api + "/" + @cn + "/figures"
doc = ArangoDB.get(cmd) doc = ArangoDB.get(cmd)
doc.parsed_response['waitForSync'].should == false doc.parsed_response['waitForSync'].should eq(false)
ArangoDB.drop_collection(@cn) ArangoDB.drop_collection(@cn)
end end
@ -351,12 +352,34 @@ describe ArangoDB do
doc.parsed_response['code'].should eq(200) doc.parsed_response['code'].should eq(200)
doc.parsed_response['id'].should be_kind_of(Integer) doc.parsed_response['id'].should be_kind_of(Integer)
doc.parsed_response['name'].should eq(@cn) doc.parsed_response['name'].should eq(@cn)
doc.parsed_response['waitForSync'].should == true doc.parsed_response['waitForSync'].should eq(true)
cmd = api + "/" + @cn + "/figures" cmd = api + "/" + @cn + "/figures"
doc = ArangoDB.get(cmd) doc = ArangoDB.get(cmd)
doc.parsed_response['waitForSync'].should == true doc.parsed_response['waitForSync'].should eq(true)
ArangoDB.drop_collection(@cn)
end
it "create a collection, volatile" do
cmd = api
body = "{ \"name\" : \"#{@cn}\", \"isVolatile\" : true }"
doc = ArangoDB.log_post("#{prefix}-create-collection-volatile", cmd, :body => body)
doc.code.should eq(200)
doc.headers['content-type'].should eq("application/json; charset=utf-8")
doc.parsed_response['error'].should eq(false)
doc.parsed_response['code'].should eq(200)
doc.parsed_response['id'].should be_kind_of(Integer)
doc.parsed_response['name'].should eq(@cn)
doc.parsed_response['waitForSync'].should eq(false)
doc.parsed_response['isVolatile'].should eq(true)
cmd = api + "/" + @cn + "/figures"
doc = ArangoDB.get(cmd)
doc.parsed_response['waitForSync'].should eq(false)
ArangoDB.drop_collection(@cn) ArangoDB.drop_collection(@cn)
end end
@ -734,6 +757,7 @@ describe ArangoDB do
doc.parsed_response['name'].should eq(cn) doc.parsed_response['name'].should eq(cn)
doc.parsed_response['status'].should eq(3) doc.parsed_response['status'].should eq(3)
doc.parsed_response['waitForSync'].should eq(true) doc.parsed_response['waitForSync'].should eq(true)
doc.parsed_response['isVolatile'].should eq(false)
cmd = api + "/" + cn + "/properties" cmd = api + "/" + cn + "/properties"
body = "{ \"waitForSync\" : false }" body = "{ \"waitForSync\" : false }"
@ -747,6 +771,7 @@ describe ArangoDB do
doc.parsed_response['name'].should eq(cn) doc.parsed_response['name'].should eq(cn)
doc.parsed_response['status'].should eq(3) doc.parsed_response['status'].should eq(3)
doc.parsed_response['waitForSync'].should eq(false) doc.parsed_response['waitForSync'].should eq(false)
doc.parsed_response['isVolatile'].should eq(false)
ArangoDB.drop_collection(cn) ArangoDB.drop_collection(cn)
end end
@ -773,14 +798,40 @@ describe ArangoDB do
doc.parsed_response['name'].should eq(cn) doc.parsed_response['name'].should eq(cn)
doc.parsed_response['status'].should eq(3) doc.parsed_response['status'].should eq(3)
doc.parsed_response['waitForSync'].should eq(true) doc.parsed_response['waitForSync'].should eq(true)
doc.parsed_response['isVolatile'].should eq(false)
doc.parsed_response['createOptions']['opt1'].should eq(10) doc.parsed_response['createOptions']['opt1'].should eq(10)
doc.parsed_response['createOptions']['opt2'].should eq("val2") doc.parsed_response['createOptions']['opt2'].should eq("val2")
ArangoDB.drop_collection(cn) ArangoDB.drop_collection(cn)
end end
it "create a collection with isVolatile property" do
cn = "UnitTestsCollectionBasics"
ArangoDB.drop_collection(cn)
cmd = "/_api/collection"
body = "{ \"name\" : \"#{cn}\", \"isVolatile\" : true }"
doc = ArangoDB.log_post("#{prefix}-with-volatile", cmd, :body => body)
doc.code.should eq(200)
cid = doc.parsed_response['id']
cmd = api + "/" + cn + "/properties"
doc = ArangoDB.log_get("#{prefix}-with-volatile", cmd)
doc.code.should eq(200)
doc.headers['content-type'].should eq("application/json; charset=utf-8")
doc.parsed_response['error'].should eq(false)
doc.parsed_response['code'].should eq(200)
doc.parsed_response['waitForSync'].should eq(false)
doc.parsed_response['isVolatile'].should eq(true)
ArangoDB.drop_collection(cn)
end
it "create collection with empty createOptions property" do it "create collection with empty createOptions property" do
cn = "UnitTestsCollectionBasics" cn = "UnitTestsCollectionBasics"
ArangoDB.drop_collection(cn)
cmd = "/_api/collection" cmd = "/_api/collection"
body = "{ \"name\" : \"#{cn}\", \"waitForSync\" : false, \"type\" : 2 }" body = "{ \"name\" : \"#{cn}\", \"waitForSync\" : false, \"type\" : 2 }"
@ -801,6 +852,7 @@ describe ArangoDB do
doc.parsed_response['name'].should eq(cn) doc.parsed_response['name'].should eq(cn)
doc.parsed_response['status'].should eq(3) doc.parsed_response['status'].should eq(3)
doc.parsed_response['waitForSync'].should eq(true) doc.parsed_response['waitForSync'].should eq(true)
doc.parsed_response['isVolatile'].should eq(false)
doc.parsed_response['createOptions'].should be_nil doc.parsed_response['createOptions'].should be_nil
ArangoDB.drop_collection(cn) ArangoDB.drop_collection(cn)

View File

@ -203,8 +203,8 @@ endif
SHELL_COMMON = @top_srcdir@/js/common/tests/shell-document.js \ SHELL_COMMON = @top_srcdir@/js/common/tests/shell-document.js \
@top_srcdir@/js/common/tests/shell-edge.js \ @top_srcdir@/js/common/tests/shell-edge.js \
@top_srcdir@/js/common/tests/shell-compactor.js \
@top_srcdir@/js/common/tests/shell-collection.js \ @top_srcdir@/js/common/tests/shell-collection.js \
@top_srcdir@/js/common/tests/shell-compactor.js \
@top_srcdir@/js/common/tests/shell-simple-query.js \ @top_srcdir@/js/common/tests/shell-simple-query.js \
@top_srcdir@/js/common/tests/shell-statement.js \ @top_srcdir@/js/common/tests/shell-statement.js \
@top_srcdir@/js/common/tests/shell-users.js \ @top_srcdir@/js/common/tests/shell-users.js \

View File

@ -1313,13 +1313,11 @@ static v8::Handle<v8::Value> CreateVocBase (v8::Arguments const& argv, TRI_col_t
v8::Handle<v8::Object> p = argv[1]->ToObject(); v8::Handle<v8::Object> p = argv[1]->ToObject();
v8::Handle<v8::String> isSystemKey = v8::String::New("isSystem"); v8::Handle<v8::String> isSystemKey = v8::String::New("isSystem");
v8::Handle<v8::String> isVolatileKey = v8::String::New("isVolatile");
v8::Handle<v8::String> journalSizeKey = v8::String::New("journalSize"); TRI_v8_global_t* v8g = (TRI_v8_global_t*) v8::Isolate::GetCurrent()->GetData();
v8::Handle<v8::String> waitForSyncKey = v8::String::New("waitForSync");
v8::Handle<v8::String> createOptionsKey = v8::String::New("createOptions");
if (p->Has(journalSizeKey)) { if (p->Has(v8g->JournalSizeKey)) {
double s = TRI_ObjectToDouble(p->Get(journalSizeKey)); double s = TRI_ObjectToDouble(p->Get(v8g->JournalSizeKey));
if (s < TRI_JOURNAL_MINIMAL_SIZE) { if (s < TRI_JOURNAL_MINIMAL_SIZE) {
return scope.Close(v8::ThrowException( return scope.Close(v8::ThrowException(
@ -1333,23 +1331,23 @@ static v8::Handle<v8::Value> CreateVocBase (v8::Arguments const& argv, TRI_col_t
// get optional options // get optional options
TRI_json_t* options = 0; TRI_json_t* options = 0;
if (p->Has(createOptionsKey)) { if (p->Has(v8g->CreateOptionsKey)) {
options = TRI_JsonObject(p->Get(createOptionsKey)); options = TRI_JsonObject(p->Get(v8g->CreateOptionsKey));
} }
TRI_InitCollectionInfo(vocbase, &parameter, name.c_str(), collectionType, effectiveSize, options); TRI_InitCollectionInfo(vocbase, &parameter, name.c_str(), collectionType, effectiveSize, options);
if (p->Has(waitForSyncKey)) { if (p->Has(v8g->WaitForSyncKey)) {
parameter._waitForSync = TRI_ObjectToBoolean(p->Get(waitForSyncKey)); parameter._waitForSync = TRI_ObjectToBoolean(p->Get(v8g->WaitForSyncKey));
} }
if (p->Has(isSystemKey)) { if (p->Has(isSystemKey)) {
parameter._isSystem = TRI_ObjectToBoolean(p->Get(isSystemKey)); parameter._isSystem = TRI_ObjectToBoolean(p->Get(isSystemKey));
} }
if (p->Has(isVolatileKey)) { if (p->Has(v8g->IsVolatileKey)) {
#ifdef TRI_HAVE_ANONYMOUS_MMAP #ifdef TRI_HAVE_ANONYMOUS_MMAP
parameter._isVolatile = TRI_ObjectToBoolean(p->Get(isVolatileKey)); parameter._isVolatile = TRI_ObjectToBoolean(p->Get(v8g->IsVolatileKey));
#else #else
TRI_FreeCollectionInfoOptions(&parameter); TRI_FreeCollectionInfoOptions(&parameter);
return scope.Close(v8::ThrowException(TRI_CreateErrorObject(TRI_ERROR_ILLEGAL_OPTION, "volatile collections are not supported on this platform", true))); return scope.Close(v8::ThrowException(TRI_CreateErrorObject(TRI_ERROR_ILLEGAL_OPTION, "volatile collections are not supported on this platform", true)));
@ -4415,16 +4413,6 @@ static v8::Handle<v8::Value> JS_GetIndexesVocbaseCol (v8::Arguments const& argv)
return GetIndexesVocbaseCol(argv, true); return GetIndexesVocbaseCol(argv, true);
} }
////////////////////////////////////////////////////////////////////////////////
/// @brief returns information about the indexes
///
/// it is the caller's responsibility to acquire and release all required locks
////////////////////////////////////////////////////////////////////////////////
static v8::Handle<v8::Value> JS_GetIndexesNLVocbaseCol (v8::Arguments const& argv) {
return GetIndexesVocbaseCol(argv, false);
}
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief loads a collection /// @brief loads a collection
/// ///
@ -4479,6 +4467,10 @@ static v8::Handle<v8::Value> JS_NameVocbaseCol (v8::Arguments const& argv) {
/// ///
/// - @LIT{journalSize} : The size of the journal in bytes. /// - @LIT{journalSize} : The size of the journal in bytes.
/// ///
/// - @LIT{isVolatile}: If @LIT{true} then the collection data will be
/// kept in memory only and ArangoDB will not write or sync the data
/// to disk.
///
/// @FUN{@FA{collection}.properties(@FA{properties})} /// @FUN{@FA{collection}.properties(@FA{properties})}
/// ///
/// Changes the collection properties. @FA{properties} must be a object with /// Changes the collection properties. @FA{properties} must be a object with
@ -4494,6 +4486,9 @@ static v8::Handle<v8::Value> JS_NameVocbaseCol (v8::Arguments const& argv) {
/// created journals. Also note that you cannot lower the journal size to less /// created journals. Also note that you cannot lower the journal size to less
/// then size of the largest document already stored in the collection. /// then size of the largest document already stored in the collection.
/// ///
/// Note: some other collection properties, such as @LIT{type} or @LIT{isVolatile}
/// cannot be changed once the collection is created.
///
/// @EXAMPLES /// @EXAMPLES
/// ///
/// Read all properties /// Read all properties
@ -4506,10 +4501,8 @@ static v8::Handle<v8::Value> JS_NameVocbaseCol (v8::Arguments const& argv) {
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
static v8::Handle<v8::Value> JS_PropertiesVocbaseCol (v8::Arguments const& argv) { static v8::Handle<v8::Value> JS_PropertiesVocbaseCol (v8::Arguments const& argv) {
TRI_v8_global_t* v8g;
v8::HandleScope scope; v8::HandleScope scope;
TRI_v8_global_t* v8g = (TRI_v8_global_t*) v8::Isolate::GetCurrent()->GetData();
v8g = (TRI_v8_global_t*) v8::Isolate::GetCurrent()->GetData();
v8::Handle<v8::Object> err; v8::Handle<v8::Object> err;
TRI_vocbase_col_t const* collection = UseCollection(argv.Holder(), &err); TRI_vocbase_col_t const* collection = UseCollection(argv.Holder(), &err);
@ -4563,11 +4556,26 @@ static v8::Handle<v8::Value> JS_PropertiesVocbaseCol (v8::Arguments const& argv)
if (maximalSize < maximumMarkerSize + TRI_JOURNAL_OVERHEAD) { if (maximalSize < maximumMarkerSize + TRI_JOURNAL_OVERHEAD) {
TRI_ReleaseCollection(collection); TRI_ReleaseCollection(collection);
return scope.Close(v8::ThrowException( return scope.Close(v8::ThrowException(
TRI_CreateErrorObject(TRI_ERROR_BAD_PARAMETER, TRI_CreateErrorObject(TRI_ERROR_BAD_PARAMETER,
"<properties>.journalSize too small"))); "<properties>.journalSize too small")));
} }
} }
if (po->Has(v8g->IsVolatileKey)) {
if (TRI_ObjectToBoolean(po->Get(v8g->IsVolatileKey)) != base->_info._isVolatile) {
TRI_ReleaseCollection(collection);
return scope.Close(v8::ThrowException(TRI_CreateErrorObject(TRI_ERROR_BAD_PARAMETER, "isVolatile option cannot be changed at runtime")));
}
}
if (base->_info._isVolatile && waitForSync) {
// the combination of waitForSync and isVolatile makes no sense
TRI_ReleaseCollection(collection);
return scope.Close(v8::ThrowException(
TRI_CreateErrorObject(TRI_ERROR_BAD_PARAMETER,
"volatile collections do not support the waitForSync option")));
}
// update collection // update collection
TRI_col_info_t newParameter; TRI_col_info_t newParameter;
@ -4593,6 +4601,7 @@ static v8::Handle<v8::Value> JS_PropertiesVocbaseCol (v8::Arguments const& argv)
result->Set(v8g->WaitForSyncKey, waitForSync ? v8::True() : v8::False()); result->Set(v8g->WaitForSyncKey, waitForSync ? v8::True() : v8::False());
result->Set(v8g->JournalSizeKey, v8::Number::New(maximalSize)); result->Set(v8g->JournalSizeKey, v8::Number::New(maximalSize));
result->Set(v8g->IsVolatileKey, base->_info._isVolatile ? v8::True() : v8::False());
if (base->_info._options) { if (base->_info._options) {
result->Set(v8g->CreateOptionsKey, TRI_ObjectJson(base->_info._options)->ToObject()); result->Set(v8g->CreateOptionsKey, TRI_ObjectJson(base->_info._options)->ToObject());
@ -5336,12 +5345,21 @@ static v8::Handle<v8::Value> JS_CompletionsVocbase (v8::Arguments const& argv) {
/// a journal or datafile. Note that this also limits the maximal /// a journal or datafile. Note that this also limits the maximal
/// size of a single object. Must be at least 1MB. /// size of a single object. Must be at least 1MB.
/// ///
/// - @LIT{isSystem} (optional, default is @LIT{false}): If true, create a /// - @LIT{isSystem} (optional, default is @LIT{false}): If @LIT{true}, create a
/// system collection. In this case @FA{collection-name} should start with /// system collection. In this case @FA{collection-name} should start with
/// an underscore. End users should normally create non-system collections /// an underscore. End users should normally create non-system collections
/// only. API implementors may be required to create system collections in /// only. API implementors may be required to create system collections in
/// very special occasions, but normally a regular collection will do. /// very special occasions, but normally a regular collection will do.
/// ///
/// - @LIT{isVolatile} (optional, default is @LIT{false}): If @LIT{true} then the
/// collection data is kept in-memory only and not made persistent. Unloading
/// the collection will cause the collection data to be discarded. Stopping
/// or re-starting the server will also cause full loss of data in the
/// collection. Setting this option will make the resulting collection be
/// slightly faster than regular collections because ArangoDB does not
/// enforce any synchronisation to disk and does not calculate any CRC
/// checksums for datafiles (as there are no datafiles).
///
/// @EXAMPLES /// @EXAMPLES
/// ///
/// With defaults: /// With defaults:
@ -6284,9 +6302,10 @@ TRI_v8_global_t* TRI_InitV8VocBridge (v8::Handle<v8::Context> context,
// keys // keys
// ............................................................................. // .............................................................................
v8g->JournalSizeKey = v8::Persistent<v8::String>::New(v8::String::New("journalSize")); v8g->IsVolatileKey = v8::Persistent<v8::String>::New(v8::String::New("isVolatile"));
v8g->WaitForSyncKey = v8::Persistent<v8::String>::New(v8::String::New("waitForSync")); v8g->JournalSizeKey = v8::Persistent<v8::String>::New(v8::String::New("journalSize"));
v8g->CreateOptionsKey = v8::Persistent<v8::String>::New(v8::String::New("createOptions")); v8g->WaitForSyncKey = v8::Persistent<v8::String>::New(v8::String::New("waitForSync"));
v8g->CreateOptionsKey = v8::Persistent<v8::String>::New(v8::String::New("createOptions"));
if (v8g->BidirectionalKey.IsEmpty()) { if (v8g->BidirectionalKey.IsEmpty()) {
v8g->BidirectionalKey = v8::Persistent<v8::String>::New(TRI_V8_SYMBOL("_bidirectional")); v8g->BidirectionalKey = v8::Persistent<v8::String>::New(TRI_V8_SYMBOL("_bidirectional"));
@ -6401,7 +6420,6 @@ TRI_v8_global_t* TRI_InitV8VocBridge (v8::Handle<v8::Context> context,
TRI_AddMethodVocbase(rt, "ensureUniqueSkiplist", JS_EnsureUniqueSkiplistVocbaseCol); TRI_AddMethodVocbase(rt, "ensureUniqueSkiplist", JS_EnsureUniqueSkiplistVocbaseCol);
TRI_AddMethodVocbase(rt, "figures", JS_FiguresVocbaseCol); TRI_AddMethodVocbase(rt, "figures", JS_FiguresVocbaseCol);
TRI_AddMethodVocbase(rt, "getIndexes", JS_GetIndexesVocbaseCol); TRI_AddMethodVocbase(rt, "getIndexes", JS_GetIndexesVocbaseCol);
TRI_AddMethodVocbase(rt, "getIndexesNL", JS_GetIndexesNLVocbaseCol, true);
TRI_AddMethodVocbase(rt, "load", JS_LoadVocbaseCol); TRI_AddMethodVocbase(rt, "load", JS_LoadVocbaseCol);
TRI_AddMethodVocbase(rt, "lookupFulltextIndex", JS_LookupFulltextIndexVocbaseCol); TRI_AddMethodVocbase(rt, "lookupFulltextIndex", JS_LookupFulltextIndexVocbaseCol);
TRI_AddMethodVocbase(rt, "lookupHashIndex", JS_LookupHashIndexVocbaseCol); TRI_AddMethodVocbase(rt, "lookupHashIndex", JS_LookupHashIndexVocbaseCol);

View File

@ -418,7 +418,7 @@ TRI_df_skip_marker_t;
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief creates a new datafile /// @brief creates a new datafile
/// ///
/// This either creates a datafile using @ref TRI_CreateAnonymousDatafile or /// This either creates a datafile using TRI_CreateAnonymousDatafile or
/// ref TRI_CreatePhysicalDatafile, based on the first parameter /// ref TRI_CreatePhysicalDatafile, based on the first parameter
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////

View File

@ -62,9 +62,10 @@ function collectionRepresentation (collection, showProperties, showCount, showFi
if (showProperties) { if (showProperties) {
var properties = collection.properties(); var properties = collection.properties();
result.waitForSync = properties.waitForSync; result.waitForSync = properties.waitForSync;
result.journalSize = properties.journalSize; result.journalSize = properties.journalSize;
result.createOptions = properties.createOptions; result.createOptions = properties.createOptions;
result.isVolatile = properties.isVolatile;
} }
if (showCount) { if (showCount) {
@ -119,12 +120,24 @@ function collectionRepresentation (collection, showProperties, showCount, showFi
/// a journal or datafile. Note that this also limits the maximal /// a journal or datafile. Note that this also limits the maximal
/// size of a single object. Must be at least 1MB. /// size of a single object. Must be at least 1MB.
/// ///
/// - @LIT{isSystem} (optional, default is @LIT{false}): If true, create a /// - @LIT{isSystem} (optional, default is @LIT{false}): If @LIT{true}, create a
/// system collection. In this case @FA{collection-name} should start with /// system collection. In this case @FA{collection-name} should start with
/// an underscore. End users should normally create non-system collections /// an underscore. End users should normally create non-system collections
/// only. API implementors may be required to create system collections in /// only. API implementors may be required to create system collections in
/// very special occasions, but normally a regular collection will do. /// very special occasions, but normally a regular collection will do.
/// ///
/// - @LIT{isVolatile} (optional, default is @LIT{false}): If @LIT{true} then the
/// collection data is kept in-memory only and not made persistent. Unloading
/// the collection will cause the collection data to be discarded. Stopping
/// or re-starting the server will also cause full loss of data in the
/// collection. Setting this option will make the resulting collection be
/// slightly faster than regular collections because ArangoDB does not
/// enforce any synchronisation to disk and does not calculate any CRC
/// checksums for datafiles (as there are no datafiles).
///
/// This option should threrefore be used for cache-type collections only,
/// and not for data that cannot be re-created otherwise.
///
/// - @LIT{options} (optional) Additional collection options /// - @LIT{options} (optional) Additional collection options
/// ///
/// - @LIT{type} (optional, default is @LIT{2}): the type of the collection to /// - @LIT{type} (optional, default is @LIT{2}): the type of the collection to
@ -166,6 +179,10 @@ function post_api_collection (req, res) {
if (body.hasOwnProperty("isSystem")) { if (body.hasOwnProperty("isSystem")) {
parameter.isSystem = body.isSystem; parameter.isSystem = body.isSystem;
} }
if (body.hasOwnProperty("isVolatile")) {
parameter.isVolatile = body.isVolatile;
}
if (body.hasOwnProperty("_id")) { if (body.hasOwnProperty("_id")) {
cid = body._id; cid = body._id;
@ -194,6 +211,7 @@ function post_api_collection (req, res) {
result.id = collection._id; result.id = collection._id;
result.name = collection.name(); result.name = collection.name();
result.waitForSync = parameter.waitForSync; result.waitForSync = parameter.waitForSync;
result.isVolatile = parameter.isVolatile;
result.status = collection.status(); result.status = collection.status();
result.type = collection.type(); result.type = collection.type();
result.createOptions = collection.createOptions; result.createOptions = collection.createOptions;
@ -278,14 +296,18 @@ function get_api_collections (req, res) {
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
/// ///
/// In addition to the above, the result will always contain the /// In addition to the above, the result will always contain the
/// @LIT{waitForSync} and the @LIT{journalSize} properties. This is /// @LIT{waitForSync}, @LIT{journalSize}, and @LIT{isVolatile} properties.
/// achieved by forcing a load of the underlying collection. /// This is achieved by forcing a load of the underlying collection.
/// ///
/// - @LIT{waitForSync}: If @LIT{true} then creating or changing a /// - @LIT{waitForSync}: If @LIT{true} then creating or changing a
/// document will wait until the data has been synchronised to disk. /// document will wait until the data has been synchronised to disk.
/// ///
/// - @LIT{journalSize}: The maximal size of a journal / datafile. /// - @LIT{journalSize}: The maximal size of a journal / datafile.
/// ///
/// - @LIT{isVolatile}: If @LIT{true} then the collection data will be
/// kept in memory only and ArangoDB will not write or sync the data
/// to disk.
///
/// @REST{GET /_api/collection/@FA{collection-name}/count} /// @REST{GET /_api/collection/@FA{collection-name}/count}
//////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////
/// ///
@ -585,6 +607,9 @@ function put_api_collection_truncate (req, res, collection) {
/// - 2: document collection /// - 2: document collection
/// - 3: edges collection /// - 3: edges collection
/// ///
/// Note: some other collection properties, such as @LIT{type} or @LIT{isVolatile}
/// cannot be changed once the collection is created.
///
/// @EXAMPLES /// @EXAMPLES
/// ///
/// @verbinclude api-collection-identifier-properties-sync /// @verbinclude api-collection-identifier-properties-sync

View File

@ -289,6 +289,7 @@ function CollectionSuite () {
var p = c1.properties(); var p = c1.properties();
assertEqual(false, p.waitForSync); assertEqual(false, p.waitForSync);
assertEqual(false, p.isVolatile);
internal.db._drop(cn); internal.db._drop(cn);
}, },
@ -312,6 +313,7 @@ function CollectionSuite () {
var p = c1.properties(); var p = c1.properties();
assertEqual(false, p.waitForSync); assertEqual(false, p.waitForSync);
assertEqual(false, p.isVolatile);
internal.db._drop(cn); internal.db._drop(cn);
}, },
@ -371,6 +373,7 @@ function CollectionSuite () {
var p = c1.properties(); var p = c1.properties();
assertEqual(false, p.waitForSync); assertEqual(false, p.waitForSync);
assertEqual(false, p.isVolatile);
internal.db._drop(cn); internal.db._drop(cn);
}, },
@ -394,6 +397,7 @@ function CollectionSuite () {
var p = c1.properties(); var p = c1.properties();
assertEqual(true, p.waitForSync); assertEqual(true, p.waitForSync);
assertEqual(false, p.isVolatile);
if (p.journalSize < 1024 * 1024) { if (p.journalSize < 1024 * 1024) {
fail(); fail();
@ -406,6 +410,28 @@ function CollectionSuite () {
internal.db._drop(cn); internal.db._drop(cn);
}, },
////////////////////////////////////////////////////////////////////////////////
/// @brief creating with properties
////////////////////////////////////////////////////////////////////////////////
testCreatingProperties2 : function () {
var cn = "example";
internal.db._drop(cn);
var c1 = internal.db._create(cn, { isVolatile : true });
assertTypeOf("number", c1._id);
assertEqual(cn, c1.name());
assertTypeOf("number", c1.status());
assertEqual(ArangoCollection.TYPE_DOCUMENT, c1.type());
assertTypeOf("number", c1.type());
var p = c1.properties();
assertEqual(true, p.isVolatile);
internal.db._drop(cn);
},
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief drop new-born /// @brief drop new-born
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -746,10 +772,148 @@ function CollectionSuite () {
internal.db._drop(cn1); internal.db._drop(cn1);
internal.db._drop(cn2); internal.db._drop(cn2);
} }
}; };
} }
// -----------------------------------------------------------------------------
// --SECTION-- volatile collections
// -----------------------------------------------------------------------------
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief test suite: volatile collections
////////////////////////////////////////////////////////////////////////////////
function CollectionVolatileSuite () {
var ERRORS = require("internal").errors;
var cn = "UnittestsVolatileCollection";
return {
////////////////////////////////////////////////////////////////////////////////
/// @brief set up
////////////////////////////////////////////////////////////////////////////////
setUp : function () {
internal.db._drop(cn);
},
////////////////////////////////////////////////////////////////////////////////
/// @brief tear down
////////////////////////////////////////////////////////////////////////////////
tearDown : function () {
internal.db._drop(cn);
},
////////////////////////////////////////////////////////////////////////////////
/// @brief create a volatile collection
////////////////////////////////////////////////////////////////////////////////
testCreation1 : function () {
var c = internal.db._create(cn, { isVolatile : true, waitForSync : false });
assertEqual(cn, c.name());
assertEqual(true, c.properties().isVolatile);
},
////////////////////////////////////////////////////////////////////////////////
/// @brief create a volatile collection
////////////////////////////////////////////////////////////////////////////////
testCreation2 : function () {
var c = internal.db._create(cn, { isVolatile : true });
assertEqual(cn, c.name());
assertEqual(true, c.properties().isVolatile);
},
////////////////////////////////////////////////////////////////////////////////
/// @brief create w/ error
////////////////////////////////////////////////////////////////////////////////
testCreationError : function () {
try {
// cannot set isVolatile and waitForSync at the same time
var c = internal.db._create(cn, { isVolatile : true, waitForSync : true });
fail();
}
catch (err) {
assertEqual(ERRORS.ERROR_BAD_PARAMETER.code, err.errorNum);
}
},
////////////////////////////////////////////////////////////////////////////////
/// @brief test property change
////////////////////////////////////////////////////////////////////////////////
testPropertyChange : function () {
var c = internal.db._create(cn, { isVolatile : true, waitForSync : false });
try {
// cannot set isVolatile and waitForSync at the same time
c.properties({ waitForSync : true });
fail();
}
catch (err) {
assertEqual(ERRORS.ERROR_BAD_PARAMETER.code, err.errorNum);
}
},
////////////////////////////////////////////////////////////////////////////////
/// @brief load/unload
////////////////////////////////////////////////////////////////////////////////
testLoadUnload : function () {
var c = internal.db._create(cn, { isVolatile : true });
assertEqual(cn, c.name());
assertEqual(true, c.properties().isVolatile);
c.unload();
internal.wait(4);
assertEqual(true, c.properties().isVolatile);
},
////////////////////////////////////////////////////////////////////////////////
/// @brief data storage
////////////////////////////////////////////////////////////////////////////////
testStorage : function () {
var c = internal.db._create(cn, { isVolatile : true });
assertEqual(true, c.properties().isVolatile);
c.save({"test": true});
assertEqual(1, c.count());
c.unload();
internal.wait(4);
assertEqual(true, c.properties().isVolatile);
assertEqual(0, c.count());
},
////////////////////////////////////////////////////////////////////////////////
/// @brief data storage
////////////////////////////////////////////////////////////////////////////////
testStorageMany : function () {
var c = internal.db._create(cn, { isVolatile : true, journalSize: 1024 * 1024 });
assertEqual(true, c.properties().isVolatile);
for (var i = 0; i < 10000; ++i) {
c.save({"test": true, "foo" : "bar"});
}
assertEqual(10000, c.count());
c.unload();
internal.wait(4);
assertEqual(true, c.properties().isVolatile);
assertEqual(0, c.count());
}
};
}
// -----------------------------------------------------------------------------
// --SECTION-- vocbase methods // --SECTION-- vocbase methods
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
@ -970,6 +1134,7 @@ function CollectionDbSuite () {
jsunity.run(CollectionSuiteErrorHandling); jsunity.run(CollectionSuiteErrorHandling);
jsunity.run(CollectionSuite); jsunity.run(CollectionSuite);
jsunity.run(CollectionVolatileSuite);
jsunity.run(CollectionDbSuite); jsunity.run(CollectionDbSuite);
return jsunity.done(); return jsunity.done();

View File

@ -99,12 +99,6 @@
ArangoCollection.TYPE_EDGE = 3; ArangoCollection.TYPE_EDGE = 3;
////////////////////////////////////////////////////////////////////////////////
/// @brief attachment collection
////////////////////////////////////////////////////////////////////////////////
ArangoCollection.TYPE_ATTACHMENT = 4;
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @} /// @}
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -228,10 +222,9 @@
switch (this.type()) { switch (this.type()) {
case ArangoCollection.TYPE_DOCUMENT: type = "document"; break; case ArangoCollection.TYPE_DOCUMENT: type = "document"; break;
case ArangoCollection.TYPE_EDGE: type = "edge"; break; case ArangoCollection.TYPE_EDGE: type = "edge"; break;
case ArangoCollection.TYPE_ATTACHMENT: type = "attachment"; break;
} }
internal.output("[ArangoCollection ", this._id, ", \"", this.name(), internal.output("[ArangoCollection ", this._id, ", \"", this.name(),
"\" (type ", type, ", status ", status, ")]"); "\" (type ", type, ", status ", status, ")]");
}; };

View File

@ -95,8 +95,7 @@
switch (this.type()) { switch (this.type()) {
case ArangoCollection.TYPE_DOCUMENT: type = "document"; break; case ArangoCollection.TYPE_DOCUMENT: type = "document"; break;
case ArangoCollection.TYPE_EDGE: type = "edge"; break; case ArangoCollection.TYPE_EDGE: type = "edge"; break;
case ArangoCollection.TYPE_ATTACHMENT: type = "attachment"; break;
} }
internal.output("[ArangoStructure ", this._id, ", \"", this.name(), internal.output("[ArangoStructure ", this._id, ", \"", this.name(),

View File

@ -97,6 +97,7 @@ typedef struct TRI_v8_global_s {
VerticesKey(), VerticesKey(),
BodyKey(), BodyKey(),
ContentTypeKey(), ContentTypeKey(),
IsVolatileKey(),
JournalSizeKey(), JournalSizeKey(),
ParametersKey(), ParametersKey(),
PathKey(), PathKey(),
@ -314,6 +315,12 @@ typedef struct TRI_v8_global_s {
v8::Persistent<v8::String> HeadersKey; v8::Persistent<v8::String> HeadersKey;
////////////////////////////////////////////////////////////////////////////////
/// @brief "isVolatile" key name
////////////////////////////////////////////////////////////////////////////////
v8::Persistent<v8::String> IsVolatileKey;
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief "journalSize" key name /// @brief "journalSize" key name
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////