mirror of https://gitee.com/bigwinds/arangodb
Merge branch 'devel' of github.com:triAGENS/ArangoDB into devel
This commit is contained in:
commit
01532b024e
|
@ -39,6 +39,7 @@
|
|||
#include "VocBase/marker.h"
|
||||
#include "VocBase/server.h"
|
||||
#include "VocBase/vocbase.h"
|
||||
#include "VocBase/voc-shaper.h"
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- private constants
|
||||
|
@ -562,6 +563,12 @@ static bool Compactifier (TRI_df_marker_t const* marker,
|
|||
if (res != TRI_ERROR_NO_ERROR) {
|
||||
LOG_FATAL_AND_EXIT("cannot write shape marker to compactor file: %s", TRI_last_error());
|
||||
}
|
||||
|
||||
res = TRI_MoveMarkerVocShaper(primary->_shaper, result);
|
||||
|
||||
if (res != TRI_ERROR_NO_ERROR) {
|
||||
LOG_FATAL_AND_EXIT("cannot re-locate shape marker");
|
||||
}
|
||||
|
||||
context->_dfi._numberShapes++;
|
||||
context->_dfi._sizeShapes += (int64_t) marker->_size;
|
||||
|
@ -576,6 +583,12 @@ static bool Compactifier (TRI_df_marker_t const* marker,
|
|||
LOG_FATAL_AND_EXIT("cannot write attribute marker to compactor file: %s", TRI_last_error());
|
||||
}
|
||||
|
||||
res = TRI_MoveMarkerVocShaper(primary->_shaper, result);
|
||||
|
||||
if (res != TRI_ERROR_NO_ERROR) {
|
||||
LOG_FATAL_AND_EXIT("cannot re-locate shape marker");
|
||||
}
|
||||
|
||||
context->_dfi._numberAttributes++;
|
||||
context->_dfi._sizeAttributes += (int64_t) marker->_size;
|
||||
}
|
||||
|
|
|
@ -76,7 +76,6 @@ typedef struct weighted_attribute_s {
|
|||
TRI_shape_aid_t _aid;
|
||||
int64_t _weight;
|
||||
TRI_shaped_json_t _value;
|
||||
const TRI_shaper_t* _shaper;
|
||||
}
|
||||
weighted_attribute_t;
|
||||
|
||||
|
@ -453,7 +452,7 @@ static TRI_shape_aid_t FindAttributeByName (TRI_shaper_t* shaper, char const* na
|
|||
if (weightedAttribute != NULL) {
|
||||
weightedAttribute->_aid = markerResult->_aid;
|
||||
weightedAttribute->_weight = TRI_VOC_UNDEFINED_ATTRIBUTE_WEIGHT;
|
||||
weightedAttribute->_attribute = (char*)(markerResult) + sizeof(TRI_df_attribute_marker_t);
|
||||
weightedAttribute->_attribute = TRI_DuplicateStringZ(TRI_UNKNOWN_MEM_ZONE, name);
|
||||
weightedAttribute->_next = NULL;
|
||||
|
||||
// ..........................................................................
|
||||
|
@ -740,9 +739,9 @@ static TRI_shape_t const* FindShape (TRI_shaper_t* shaper,
|
|||
/// @brief compares to weighted attributes
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static int attributeWeightCompareFunction (const void* leftItem, const void* rightItem) {
|
||||
const weighted_attribute_t* l = (const weighted_attribute_t*)(leftItem);
|
||||
const weighted_attribute_t* r = (const weighted_attribute_t*)(rightItem);
|
||||
static int AttributeWeightCompareFunction (const void* leftItem, const void* rightItem) {
|
||||
const weighted_attribute_t* l = (const weighted_attribute_t*) leftItem;
|
||||
const weighted_attribute_t* r = (const weighted_attribute_t*) rightItem;
|
||||
|
||||
if (l->_weight < r->_weight) {
|
||||
return -1;
|
||||
|
@ -760,7 +759,7 @@ static int attributeWeightCompareFunction (const void* leftItem, const void* rig
|
|||
/// comparisions.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static void freeShapeTypeJsonArrayHelper (weighted_attribute_t** leftWeightedList,
|
||||
static void FreeShapeTypeJsonArrayHelper (weighted_attribute_t** leftWeightedList,
|
||||
weighted_attribute_t** rightWeightedList) {
|
||||
if (*leftWeightedList != NULL) {
|
||||
TRI_Free(TRI_UNKNOWN_MEM_ZONE, *leftWeightedList);
|
||||
|
@ -777,7 +776,7 @@ static void freeShapeTypeJsonArrayHelper (weighted_attribute_t** leftWeightedLis
|
|||
/// @brief returns the number of entries
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static int compareShapeTypeJsonArrayHelper (const TRI_shape_t* shape,
|
||||
static int CompareShapeTypeJsonArrayHelper (const TRI_shape_t* shape,
|
||||
const TRI_shaper_t* shaper,
|
||||
const TRI_shaped_json_t* shapedJson,
|
||||
weighted_attribute_t** attributeArray) {
|
||||
|
@ -847,7 +846,6 @@ static int compareShapeTypeJsonArrayHelper (const TRI_shape_t* shape,
|
|||
(*attributeArray)[j]._value._sid = sids[j];
|
||||
(*attributeArray)[j]._value._data.data = shapedJson->_data.data + offsets[j];
|
||||
(*attributeArray)[j]._value._data.length = offsets[j + 1] - offsets[j];
|
||||
(*attributeArray)[j]._shaper = shaper;
|
||||
}
|
||||
|
||||
offsets = (const TRI_shape_size_t*)(shapedJson->_data.data);
|
||||
|
@ -858,7 +856,6 @@ static int compareShapeTypeJsonArrayHelper (const TRI_shape_t* shape,
|
|||
(*attributeArray)[jj]._value._sid = sids[jj];
|
||||
(*attributeArray)[jj]._value._data.data = shapedJson->_data.data + offsets[j];
|
||||
(*attributeArray)[jj]._value._data.length = offsets[j + 1] - offsets[j];
|
||||
(*attributeArray)[jj]._shaper = shaper;
|
||||
}
|
||||
|
||||
return (fixedEntries + variableEntries);
|
||||
|
@ -969,11 +966,11 @@ static uint64_t HashElementWeightedAttribute (TRI_associative_pointer_t* array,
|
|||
static int InitStep1VocShaper (voc_shaper_t* shaper) {
|
||||
int res;
|
||||
|
||||
shaper->base.findAttributeByName = FindAttributeByName;
|
||||
shaper->base.findAttributeByName = FindAttributeByName;
|
||||
shaper->base.lookupAttributeByName = LookupAttributeByName;
|
||||
shaper->base.lookupAttributeId = LookupAttributeId;
|
||||
shaper->base.findShape = FindShape;
|
||||
shaper->base.lookupShapeId = LookupShapeId;
|
||||
shaper->base.lookupAttributeId = LookupAttributeId;
|
||||
shaper->base.findShape = FindShape;
|
||||
shaper->base.lookupShapeId = LookupShapeId;
|
||||
|
||||
res = TRI_InitAssociativeSynced(&shaper->_attributeNames,
|
||||
TRI_UNKNOWN_MEM_ZONE,
|
||||
|
@ -1217,6 +1214,12 @@ void TRI_DestroyVocShaper (TRI_shaper_t* s) {
|
|||
weightedAttribute = (shaper->_weights)._first;
|
||||
while (weightedAttribute != NULL) {
|
||||
nextWeightedAttribute = weightedAttribute->_next;
|
||||
|
||||
// free attribute name
|
||||
if (weightedAttribute->_attribute != NULL) {
|
||||
TRI_Free(TRI_UNKNOWN_MEM_ZONE, weightedAttribute->_attribute);
|
||||
}
|
||||
|
||||
TRI_Free(TRI_UNKNOWN_MEM_ZONE, weightedAttribute);
|
||||
weightedAttribute = nextWeightedAttribute;
|
||||
}
|
||||
|
@ -1256,6 +1259,61 @@ int TRI_InitVocShaper (TRI_shaper_t* s) {
|
|||
return InitStep3VocShaper(shaper);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief move a shape marker, called during compaction
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
int TRI_MoveMarkerVocShaper (TRI_shaper_t* s,
|
||||
TRI_df_marker_t* marker) {
|
||||
voc_shaper_t* shaper = (voc_shaper_t*) s;
|
||||
|
||||
if (marker->_type == TRI_DF_MARKER_SHAPE) {
|
||||
char* p = ((char*) marker) + sizeof(TRI_df_shape_marker_t);
|
||||
TRI_shape_t* l = (TRI_shape_t*) p;
|
||||
void* f;
|
||||
|
||||
// remove the old marker
|
||||
f = TRI_RemoveKeyAssociativeSynced(&shaper->_shapeIds, &l->_sid);
|
||||
assert(f != NULL);
|
||||
|
||||
// re-insert the marker with the new pointer
|
||||
f = TRI_InsertKeyAssociativeSynced(&shaper->_shapeIds, &l->_sid, l);
|
||||
assert(f == NULL);
|
||||
|
||||
// same for the shape dictionary
|
||||
f = TRI_RemoveElementAssociativeSynced(&shaper->_shapeDictionary, l);
|
||||
assert(f != NULL);
|
||||
|
||||
// re-insert
|
||||
f = TRI_InsertElementAssociativeSynced(&shaper->_shapeDictionary, l);
|
||||
assert(f == NULL);
|
||||
}
|
||||
else if (marker->_type == TRI_DF_MARKER_ATTRIBUTE) {
|
||||
TRI_df_attribute_marker_t* m = (TRI_df_attribute_marker_t*) marker;
|
||||
char* p = ((char*) m) + sizeof(TRI_df_attribute_marker_t);
|
||||
void* f;
|
||||
|
||||
// remove attribute by name (p points to new location of name, but names
|
||||
// are identical in old and new marker)
|
||||
f = TRI_RemoveKeyAssociativeSynced(&shaper->_attributeNames, p);
|
||||
assert(f != NULL);
|
||||
|
||||
// now re-insert same attribute with adjusted pointer
|
||||
f = TRI_InsertKeyAssociativeSynced(&shaper->_attributeNames, p, m);
|
||||
assert(f == NULL);
|
||||
|
||||
// same for attribute ids
|
||||
f = TRI_RemoveKeyAssociativeSynced(&shaper->_attributeIds, &m->_aid);
|
||||
assert(f != NULL);
|
||||
|
||||
// now re-insert same attribute with adjusted pointer
|
||||
f = TRI_InsertKeyAssociativeSynced(&shaper->_attributeIds, &m->_aid, m);
|
||||
assert(f == NULL);
|
||||
}
|
||||
|
||||
return TRI_ERROR_NO_ERROR;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief insert a shape, called when opening a collection
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -1321,7 +1379,7 @@ int TRI_InsertAttributeVocShaper (TRI_shaper_t* s,
|
|||
|
||||
weightedAttribute->_aid = m->_aid;
|
||||
weightedAttribute->_weight = TRI_VOC_UNDEFINED_ATTRIBUTE_WEIGHT;
|
||||
weightedAttribute->_attribute = (char*) m + sizeof(TRI_df_attribute_marker_t);
|
||||
weightedAttribute->_attribute = TRI_DuplicateStringZ(TRI_UNKNOWN_MEM_ZONE, (char*) m + sizeof(TRI_df_attribute_marker_t));
|
||||
weightedAttribute->_next = NULL;
|
||||
|
||||
// ..........................................................................
|
||||
|
@ -1849,8 +1907,8 @@ int TRI_CompareShapeTypes (TRI_doc_mptr_t* leftDocument,
|
|||
// generate the left and right lists.
|
||||
// ............................................................................
|
||||
|
||||
leftNumWeightedList = compareShapeTypeJsonArrayHelper(leftShape, leftShaper, &left, &leftWeightedList);
|
||||
rightNumWeightedList = compareShapeTypeJsonArrayHelper(rightShape, rightShaper, &right, &rightWeightedList);
|
||||
leftNumWeightedList = CompareShapeTypeJsonArrayHelper(leftShape, leftShaper, &left, &leftWeightedList);
|
||||
rightNumWeightedList = CompareShapeTypeJsonArrayHelper(rightShape, rightShaper, &right, &rightWeightedList);
|
||||
|
||||
// ............................................................................
|
||||
// If the left and right both resulted in errors, we return equality for want
|
||||
|
@ -1858,7 +1916,7 @@ int TRI_CompareShapeTypes (TRI_doc_mptr_t* leftDocument,
|
|||
// ............................................................................
|
||||
|
||||
if ( (leftNumWeightedList < 0) && (rightNumWeightedList < 0) ) { // probably out of memory error
|
||||
freeShapeTypeJsonArrayHelper(&leftWeightedList, &rightWeightedList);
|
||||
FreeShapeTypeJsonArrayHelper(&leftWeightedList, &rightWeightedList);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1867,7 +1925,7 @@ int TRI_CompareShapeTypes (TRI_doc_mptr_t* leftDocument,
|
|||
// ............................................................................
|
||||
|
||||
if (leftNumWeightedList < 0) { // probably out of memory error
|
||||
freeShapeTypeJsonArrayHelper(&leftWeightedList, &rightWeightedList);
|
||||
FreeShapeTypeJsonArrayHelper(&leftWeightedList, &rightWeightedList);
|
||||
return -1; // attempt to compare as low as possible
|
||||
}
|
||||
|
||||
|
@ -1876,7 +1934,7 @@ int TRI_CompareShapeTypes (TRI_doc_mptr_t* leftDocument,
|
|||
// ............................................................................
|
||||
|
||||
if (rightNumWeightedList < 0) {
|
||||
freeShapeTypeJsonArrayHelper(&leftWeightedList, &rightWeightedList);
|
||||
FreeShapeTypeJsonArrayHelper(&leftWeightedList, &rightWeightedList);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -1885,7 +1943,7 @@ int TRI_CompareShapeTypes (TRI_doc_mptr_t* leftDocument,
|
|||
// ............................................................................
|
||||
|
||||
if ( (leftNumWeightedList == 0) && (rightNumWeightedList == 0) ) {
|
||||
freeShapeTypeJsonArrayHelper(&leftWeightedList, &rightWeightedList);
|
||||
FreeShapeTypeJsonArrayHelper(&leftWeightedList, &rightWeightedList);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1894,7 +1952,7 @@ int TRI_CompareShapeTypes (TRI_doc_mptr_t* leftDocument,
|
|||
// ............................................................................
|
||||
|
||||
if (leftNumWeightedList == 0) {
|
||||
freeShapeTypeJsonArrayHelper(&leftWeightedList, &rightWeightedList);
|
||||
FreeShapeTypeJsonArrayHelper(&leftWeightedList, &rightWeightedList);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -1903,7 +1961,7 @@ int TRI_CompareShapeTypes (TRI_doc_mptr_t* leftDocument,
|
|||
// ............................................................................
|
||||
|
||||
if (rightNumWeightedList == 0) {
|
||||
freeShapeTypeJsonArrayHelper(&leftWeightedList, &rightWeightedList);
|
||||
FreeShapeTypeJsonArrayHelper(&leftWeightedList, &rightWeightedList);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -1911,8 +1969,8 @@ int TRI_CompareShapeTypes (TRI_doc_mptr_t* leftDocument,
|
|||
// We now have to sort the left and right weighted list according to attribute weight
|
||||
// ..............................................................................
|
||||
|
||||
qsort(leftWeightedList, leftNumWeightedList, sizeof(weighted_attribute_t), attributeWeightCompareFunction);
|
||||
qsort(rightWeightedList, rightNumWeightedList, sizeof(weighted_attribute_t), attributeWeightCompareFunction);
|
||||
qsort(leftWeightedList, leftNumWeightedList, sizeof(weighted_attribute_t), AttributeWeightCompareFunction);
|
||||
qsort(rightWeightedList, rightNumWeightedList, sizeof(weighted_attribute_t), AttributeWeightCompareFunction);
|
||||
|
||||
// ..............................................................................
|
||||
// check the weight and if equal check the values. Notice that numWeightedList
|
||||
|
@ -1970,7 +2028,7 @@ int TRI_CompareShapeTypes (TRI_doc_mptr_t* leftDocument,
|
|||
// Deallocate any memory for the comparisions and return the result
|
||||
// ..............................................................................
|
||||
|
||||
freeShapeTypeJsonArrayHelper(&leftWeightedList, &rightWeightedList);
|
||||
FreeShapeTypeJsonArrayHelper(&leftWeightedList, &rightWeightedList);
|
||||
return result;
|
||||
}
|
||||
} // end of switch (rightType)
|
||||
|
|
|
@ -126,6 +126,13 @@ void TRI_FreeVocShaper (TRI_shaper_t*);
|
|||
|
||||
int TRI_InitVocShaper (TRI_shaper_t*);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief move a shape marker, called during compaction
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
int TRI_MoveMarkerVocShaper (TRI_shaper_t*,
|
||||
TRI_df_marker_t*);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief insert a shape, called when opening a collection
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
REPLICATION_LOGGER_CONFIGURE, REPLICATION_APPLIER_CONFIGURE, REPLICATION_APPLIER_START,
|
||||
REPLICATION_APPLIER_STOP, REPLICATION_APPLIER_FORGET, REPLICATION_APPLIER_STATE,
|
||||
REPLICATION_SYNCHRONISE, REPLICATION_SERVER_ID, CONFIGURE_ENDPOINT, REMOVE_ENDPOINT, LIST_ENDPOINTS,
|
||||
SYS_BASE64DECODE, SYS_BASE64ENCODE,
|
||||
SYS_BASE64DECODE, SYS_BASE64ENCODE, SYS_DEBUG_SEGFAULT,
|
||||
SYS_DEBUG_CAN_USE_FAILAT, SYS_DEBUG_SET_FAILAT, SYS_DEBUG_REMOVE_FAILAT, SYS_DEBUG_CLEAR_FAILAT,
|
||||
SYS_DOWNLOAD, SYS_EXECUTE, SYS_LOAD, SYS_LOG_LEVEL, SYS_MD5, SYS_OUTPUT, SYS_PROCESS_STATISTICS,
|
||||
SYS_RAND, SYS_SERVER_STATISTICS, SYS_SPRINTF, SYS_TIME, SYS_START_PAGER, SYS_STOP_PAGER,
|
||||
|
@ -375,6 +375,15 @@
|
|||
delete SYS_BASE64ENCODE;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief debugSegfault
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
if (typeof SYS_DEBUG_SEGFAULT !== "undefined") {
|
||||
exports.debugSegfault = SYS_DEBUG_SEGFAULT;
|
||||
delete SYS_DEBUG_SEGFAULT;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief debugSetFailAt
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
REPLICATION_LOGGER_CONFIGURE, REPLICATION_APPLIER_CONFIGURE, REPLICATION_APPLIER_START,
|
||||
REPLICATION_APPLIER_STOP, REPLICATION_APPLIER_FORGET, REPLICATION_APPLIER_STATE,
|
||||
REPLICATION_SYNCHRONISE, REPLICATION_SERVER_ID, CONFIGURE_ENDPOINT, REMOVE_ENDPOINT, LIST_ENDPOINTS,
|
||||
SYS_BASE64DECODE, SYS_BASE64ENCODE,
|
||||
SYS_BASE64DECODE, SYS_BASE64ENCODE, SYS_DEBUG_SEGFAULT,
|
||||
SYS_DEBUG_CAN_USE_FAILAT, SYS_DEBUG_SET_FAILAT, SYS_DEBUG_REMOVE_FAILAT, SYS_DEBUG_CLEAR_FAILAT,
|
||||
SYS_DOWNLOAD, SYS_EXECUTE, SYS_LOAD, SYS_LOG_LEVEL, SYS_MD5, SYS_OUTPUT, SYS_PROCESS_STATISTICS,
|
||||
SYS_RAND, SYS_SERVER_STATISTICS, SYS_SPRINTF, SYS_TIME, SYS_START_PAGER, SYS_STOP_PAGER,
|
||||
|
@ -375,6 +375,15 @@
|
|||
delete SYS_BASE64ENCODE;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief debugSegfault
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
if (typeof SYS_DEBUG_SEGFAULT !== "undefined") {
|
||||
exports.debugSegfault = SYS_DEBUG_SEGFAULT;
|
||||
delete SYS_DEBUG_SEGFAULT;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief debugSetFailAt
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -41,6 +41,194 @@ function CompactionSuite () {
|
|||
|
||||
return {
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief test shapes
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
testShapes1 : function () {
|
||||
var cn = "example";
|
||||
internal.db._drop(cn);
|
||||
var c1 = internal.db._create(cn, { "journalSize" : 1048576 });
|
||||
|
||||
var i;
|
||||
|
||||
// prefill with "trash"
|
||||
for (i = 0; i < 1000; ++i) {
|
||||
c1.save({ _key: "test" + i });
|
||||
}
|
||||
|
||||
// this accesses all documents, and creates shape accessors for all of them
|
||||
c1.toArray();
|
||||
|
||||
c1.truncate();
|
||||
c1.rotate();
|
||||
|
||||
// create lots of different shapes
|
||||
for (i = 0; i < 100; ++i) {
|
||||
var doc = { _key: "test" + i };
|
||||
doc["number" + i] = i;
|
||||
doc["string" + i] = "test" + i;
|
||||
doc["bool" + i] = (i % 2 == 0);
|
||||
c1.save(doc);
|
||||
}
|
||||
|
||||
// make sure compaction moves the shapes
|
||||
c1.rotate();
|
||||
internal.wait(5);
|
||||
c1.truncate();
|
||||
internal.wait(5);
|
||||
|
||||
for (i = 0; i < 100; ++i) {
|
||||
var doc = { _key: "test" + i };
|
||||
doc["number" + i] = i + 1;
|
||||
doc["string" + i] = "test" + (i + 1);
|
||||
doc["bool" + i] = (i % 2 != 0);
|
||||
c1.save(doc);
|
||||
}
|
||||
|
||||
for (i = 0; i < 100; ++i) {
|
||||
var doc = c1.document("test" + i);
|
||||
assertTrue(doc.hasOwnProperty("number" + i));
|
||||
assertTrue(doc.hasOwnProperty("string" + i));
|
||||
assertTrue(doc.hasOwnProperty("bool" + i));
|
||||
|
||||
assertEqual(i + 1, doc["number" + i]);
|
||||
assertEqual("test" + (i + 1), doc["string" + i]);
|
||||
assertEqual(i % 2 != 0, doc["bool" + i]);
|
||||
}
|
||||
|
||||
internal.db._drop(cn);
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief test shapes
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
testShapes2 : function () {
|
||||
var cn = "example";
|
||||
internal.db._drop(cn);
|
||||
var c1 = internal.db._create(cn, { "journalSize" : 1048576 });
|
||||
|
||||
var i;
|
||||
// prefill with "trash"
|
||||
for (i = 0; i < 1000; ++i) {
|
||||
c1.save({ _key: "test" + i });
|
||||
}
|
||||
c1.truncate();
|
||||
c1.rotate();
|
||||
|
||||
// create lots of different shapes
|
||||
for (i = 0; i < 100; ++i) {
|
||||
var doc = { _key: "test" + i };
|
||||
doc["number" + i] = i;
|
||||
doc["string" + i] = "test" + i;
|
||||
doc["bool" + i] = (i % 2 == 0);
|
||||
c1.save(doc);
|
||||
}
|
||||
|
||||
c1.save({ _key: "foo", name: { first: "foo", last: "bar" } });
|
||||
c1.save({ _key: "bar", name: { first: "bar", last: "baz", middle: "foo" }, age: 22 });
|
||||
|
||||
// remove most of the shapes
|
||||
for (i = 0; i < 100; ++i) {
|
||||
c1.remove("test" + i);
|
||||
}
|
||||
|
||||
// make sure compaction moves the shapes
|
||||
c1.rotate();
|
||||
internal.wait(5);
|
||||
|
||||
var doc = c1.document("foo");
|
||||
assertTrue(doc.hasOwnProperty("name"));
|
||||
assertFalse(doc.hasOwnProperty("age"));
|
||||
assertEqual({ first: "foo", last: "bar" }, doc.name);
|
||||
|
||||
doc = c1.document("bar");
|
||||
assertTrue(doc.hasOwnProperty("name"));
|
||||
assertTrue(doc.hasOwnProperty("age"));
|
||||
assertEqual({ first: "bar", last: "baz", middle: "foo" }, doc.name);
|
||||
assertEqual(22, doc.age);
|
||||
|
||||
internal.db._drop(cn);
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief test shapes
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
testShapesUnloadReload : function () {
|
||||
var cn = "example";
|
||||
internal.db._drop(cn);
|
||||
var c1 = internal.db._create(cn, { "journalSize" : 1048576 });
|
||||
|
||||
var i;
|
||||
|
||||
// create lots of different shapes
|
||||
for (i = 0; i < 100; ++i) {
|
||||
var doc = { _key: "test" + i };
|
||||
doc["number" + i] = i;
|
||||
doc["string" + i] = "test" + i;
|
||||
doc["bool" + i] = (i % 2 == 0);
|
||||
c1.save(doc);
|
||||
}
|
||||
|
||||
c1.save({ _key: "foo", name: { first: "foo", last: "bar" } });
|
||||
c1.save({ _key: "bar", name: { first: "bar", last: "baz", middle: "foo" }, age: 22 });
|
||||
|
||||
// this accesses all documents, and creates shape accessors for all of them
|
||||
c1.toArray();
|
||||
|
||||
// remove most of the shapes
|
||||
for (i = 0; i < 100; ++i) {
|
||||
c1.remove("test" + i);
|
||||
}
|
||||
|
||||
// make sure compaction moves the shapes
|
||||
c1.rotate();
|
||||
internal.wait(5);
|
||||
// unload the collection
|
||||
c1.unload();
|
||||
c1 = null;
|
||||
internal.wait(5);
|
||||
|
||||
c1 = internal.db._collection(cn);
|
||||
|
||||
// check if documents are still there
|
||||
var doc = c1.document("foo");
|
||||
assertTrue(doc.hasOwnProperty("name"));
|
||||
assertFalse(doc.hasOwnProperty("age"));
|
||||
assertEqual({ first: "foo", last: "bar" }, doc.name);
|
||||
|
||||
doc = c1.document("bar");
|
||||
assertTrue(doc.hasOwnProperty("name"));
|
||||
assertTrue(doc.hasOwnProperty("age"));
|
||||
assertEqual({ first: "bar", last: "baz", middle: "foo" }, doc.name);
|
||||
assertEqual(22, doc.age);
|
||||
|
||||
// create docs with already existing shapes
|
||||
for (i = 0; i < 100; ++i) {
|
||||
var doc = { _key: "test" + i };
|
||||
doc["number" + i] = i;
|
||||
doc["string" + i] = "test" + i;
|
||||
doc["bool" + i] = (i % 2 == 0);
|
||||
c1.save(doc);
|
||||
}
|
||||
|
||||
// check if the documents work
|
||||
for (i = 0; i < 100; ++i) {
|
||||
var doc = c1.document("test" + i);
|
||||
assertTrue(doc.hasOwnProperty("number" + i));
|
||||
assertTrue(doc.hasOwnProperty("string" + i));
|
||||
assertTrue(doc.hasOwnProperty("bool" + i));
|
||||
|
||||
assertEqual(i, doc["number" + i]);
|
||||
assertEqual("test" + i, doc["string" + i]);
|
||||
assertEqual(i % 2 == 0, doc["bool" + i]);
|
||||
}
|
||||
|
||||
internal.db._drop(cn);
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief test journals
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -48,7 +236,7 @@ function CompactionSuite () {
|
|||
testJournals : function () {
|
||||
var cn = "example";
|
||||
internal.db._drop(cn);
|
||||
var c1 = internal.db._create(cn, { "journalSize" : 1048576 } );
|
||||
var c1 = internal.db._create(cn, { "journalSize" : 1048576 });
|
||||
|
||||
// empty collection
|
||||
var fig = c1.figures();
|
||||
|
@ -232,7 +420,7 @@ function CompactionSuite () {
|
|||
}
|
||||
|
||||
internal.db._drop(cn);
|
||||
var c1 = internal.db._create(cn, { "journalSize" : 1048576, "doCompact" : false } );
|
||||
var c1 = internal.db._create(cn, { "journalSize" : 1048576, "doCompact" : false });
|
||||
|
||||
for (var i = 0; i < n; ++i) {
|
||||
c1.save({ _key: "test" + i, value : i, payload : payload });
|
||||
|
@ -310,7 +498,7 @@ function CompactionSuite () {
|
|||
}
|
||||
|
||||
internal.db._drop(cn);
|
||||
var c1 = internal.db._create(cn, { "journalSize" : 1048576 } );
|
||||
var c1 = internal.db._create(cn, { "journalSize" : 1048576 });
|
||||
|
||||
for (var i = 0; i < n; ++i) {
|
||||
c1.save({ _key: "test" + i, value : i, payload : payload });
|
||||
|
@ -430,7 +618,7 @@ function CompactionSuite () {
|
|||
}
|
||||
|
||||
internal.db._drop(cn);
|
||||
var c1 = internal.db._create(cn, { "journalSize" : 1048576 } );
|
||||
var c1 = internal.db._create(cn, { "journalSize" : 1048576 });
|
||||
|
||||
for (var i = 0; i < n; ++i) {
|
||||
c1.save({ value : i, payload : payload });
|
||||
|
|
|
@ -34,11 +34,6 @@
|
|||
// --SECTION-- private variables
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @addtogroup Debugging
|
||||
/// @{
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief a global string containing the currently registered failure points
|
||||
/// the string is a comma-separated list of point names
|
||||
|
@ -60,19 +55,10 @@ TRI_read_write_lock_t FailurePointsLock;
|
|||
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- private functions
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @addtogroup Debugging
|
||||
/// @{
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief make a delimited value from a string, so we can unambigiously
|
||||
/// search for it (e.g. searching for just "foo" would find "foo" and "foobar",
|
||||
|
@ -102,19 +88,23 @@ static char* MakeValue (char const* value) {
|
|||
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- public functions
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @addtogroup Debugging
|
||||
/// @{
|
||||
/// @brief cause a segmentation violation
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void TRI_SegfaultDebugging (char const* message) {
|
||||
|
||||
#ifdef TRI_ENABLE_MAINTAINER_MODE
|
||||
fprintf(stderr, "causing intentional segfault: %s\n", message);
|
||||
*((char*) -1) = '!';
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief check whether we should fail at a specific failure point
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -357,10 +347,6 @@ void TRI_ShutdownDebugging () {
|
|||
#endif
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- END-OF-FILE
|
||||
// -----------------------------------------------------------------------------
|
||||
|
|
|
@ -75,6 +75,12 @@ extern "C" {
|
|||
/// @{
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief cause a segmentation violation
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void TRI_SegfaultDebugging (char const*);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief check whether we should fail at a failure point
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -2180,6 +2180,31 @@ static v8::Handle<v8::Value> JS_Wait (v8::Arguments const& argv) {
|
|||
return scope.Close(v8::Undefined());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief intentionally cause a segfault
|
||||
///
|
||||
/// @FUN{internal.debugSegfault(@FA{message})}
|
||||
///
|
||||
/// intentionally cause a segmentation violation
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static v8::Handle<v8::Value> JS_DebugSegfault (v8::Arguments const& argv) {
|
||||
v8::HandleScope scope;
|
||||
|
||||
// extract arguments
|
||||
if (argv.Length() != 1) {
|
||||
TRI_V8_EXCEPTION_USAGE(scope, "debugSegfault(<message>)");
|
||||
}
|
||||
|
||||
const string message = TRI_ObjectToString(argv[0]);
|
||||
|
||||
TRI_SegfaultDebugging(message.c_str());
|
||||
|
||||
// we may get here if we are in non-maintainer mode
|
||||
|
||||
return scope.Close(v8::Undefined());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief set a failure point
|
||||
///
|
||||
|
@ -2820,6 +2845,7 @@ void TRI_InitV8Utils (v8::Handle<v8::Context> context,
|
|||
TRI_AddGlobalFunctionVocbase(context, "SYS_WAIT", JS_Wait);
|
||||
|
||||
// debugging functions
|
||||
TRI_AddGlobalFunctionVocbase(context, "SYS_DEBUG_SEGFAULT", JS_DebugSegfault);
|
||||
TRI_AddGlobalFunctionVocbase(context, "SYS_DEBUG_SET_FAILAT", JS_DebugSetFailAt);
|
||||
TRI_AddGlobalFunctionVocbase(context, "SYS_DEBUG_REMOVE_FAILAT", JS_DebugRemoveFailAt);
|
||||
TRI_AddGlobalFunctionVocbase(context, "SYS_DEBUG_CLEAR_FAILAT", JS_DebugClearFailAt);
|
||||
|
|
Loading…
Reference in New Issue