bool objectHashEqual(LCObjectRef object1, LCObjectRef object2) { char hash1[HASH_LENGTH]; char hash2[HASH_LENGTH]; objectHash(object1, hash1); objectHash(object2, hash2); return strcmp(hash1, hash2)==0; }
static char* test_object_persistence_with_store(LCStoreRef store, char *storeType) { LCContextRef context = contextCreate(store, NULL, 0); mu_assert("contextStringToType", contextStringToType(context, "LCString") == LCTypeString); char* string = "abcdef"; LCStringRef test = LCStringCreate(string); objectStore(test, context); objectDeleteCache(test, context); mu_assert("string persistence", LCStringEqualCString(test, string)); char hash[HASH_LENGTH]; objectHash(test, hash); FILE *fd = storeReadData(store, LCTypeString, hash); LCStringRef stringFromFile = objectCreateFromFile(context, fd); mu_assert("objectCreateFromFile", LCStringEqualCString(stringFromFile, string)); LCStringRef string1 = LCStringCreate("abc"); LCStringRef string2 = LCStringCreate("def"); LCStringRef string3 = LCStringCreate("ghi"); LCStringRef stringArray[] = {string1, string2, string3}; LCArrayRef array = LCArrayCreate(stringArray, 3); objectStore(array, context); objectDeleteCache(array, context); LCStringRef *strings = LCArrayObjects(array); mu_assert("array persistence", LCStringEqual(string1, strings[0]) && LCStringEqual(string2, strings[1]) && LCStringEqual(string3, strings[2])); LCKeyValueRef keyValue = LCKeyValueCreate(string1, array); objectStore(keyValue, context); objectDeleteCache(keyValue, context); objectCache(keyValue); mu_assert("keyValue persistence", LCStringEqual(LCKeyValueKey(keyValue), string1)); LCArrayRef mArray = LCMutableArrayCreate(stringArray, 3); objectStore(mArray, context); objectDeleteCache(mArray, context); LCMutableArrayAddObject(mArray, string1); objectStore(mArray, context); objectDeleteCache(mArray, context); objectCache(mArray); LCStringRef *strings1 = LCMutableArrayObjects(mArray); mu_assert("mutable array persistence", LCStringEqual(string1, strings1[0]) && LCStringEqual(string2, strings1[1]) && LCStringEqual(string3, strings1[2]) && LCStringEqual(string1, strings1[3])); LCMutableArrayAddObject(mArray, LCStringCreate("test1")); objectStoreAsComposite(mArray, context); objectDeleteCache(mArray, context); LCStringRef *strings2 = LCMutableArrayObjects(mArray); mu_assert("composite persistence", LCStringEqual(string1, strings2[0]) && LCStringEqual(string2, strings2[1]) && LCStringEqual(string3, strings2[2]) && LCStringEqual(string1, strings2[3])); return 0; }
TypePtr staticType(ObjectPtr obj) { int h = objectHash(obj); h &= staticTypes.size() - 1; vector<StaticTypePtr> &bucket = staticTypes[h]; for (unsigned i = 0; i < bucket.size(); ++i) { if (objectEquals(obj, bucket[i]->obj)) return bucket[i].ptr(); } StaticTypePtr t = new StaticType(obj); bucket.push_back(t); return t.ptr(); }
TypePtr variantType(VariantPtr variant, const vector<ObjectPtr> ¶ms) { int h = pointerHash(variant.ptr()); for (unsigned i = 0; i < params.size(); ++i) h += objectHash(params[i]); h &= variantTypes.size() - 1; vector<VariantTypePtr> &bucket = variantTypes[h]; for (unsigned i = 0; i < bucket.size(); ++i) { VariantType *t = bucket[i].ptr(); if ((t->variant == variant) && objectVectorEquals(t->params, params)) return t; } VariantTypePtr t = new VariantType(variant); for (unsigned i = 0; i < params.size(); ++i) t->params.push_back(params[i]); bucket.push_back(t); return t.ptr(); }
static void objectStoreWithCompositeParam(LCObjectRef object, bool composite, LCContextRef context) { char hash[HASH_LENGTH]; objectHash(object, hash); if (!object->type->immutable) { _objectSetHash(object, hash); } if (storeFileExists(context->store, objectType(object), hash)) { return; } FILE* fp = storeWriteData(context->store, objectType(object), hash); if (composite) { objectSerializeAsComposite(object, fp); } else { objectSerialize(object, fp); objectWalkChildren(object, context, storeChildCallback); } fclose(fp); }
TypePtr recordType(RecordPtr record, const vector<ObjectPtr> ¶ms) { int h = pointerHash(record.ptr()); vector<ObjectPtr>::const_iterator pi, pend; for (pi = params.begin(), pend = params.end(); pi != pend; ++pi) h += objectHash(*pi); h &= recordTypes.size() - 1; vector<RecordTypePtr>::iterator i, end; for (i = recordTypes[h].begin(), end = recordTypes[h].end(); i != end; ++i) { RecordType *t = i->ptr(); if ((t->record == record) && objectVectorEquals(t->params, params)) return t; } RecordTypePtr t = new RecordType(record); for (pi = params.begin(), pend = params.end(); pi != pend; ++pi) t->params.push_back(*pi); recordTypes[h].push_back(t); initializeRecordFields(t); return t.ptr(); }
InvokeSetPtr lookupInvokeSet(ObjectPtr callable, const vector<TypePtr> &argsKey) { if (!invokeTablesInitialized) initInvokeTables(); int h = objectHash(callable) + objectVectorHash(argsKey); h &= (invokeTable.size() - 1); vector<InvokeSetPtr> &bucket = invokeTable[h]; for (unsigned i = 0; i < bucket.size(); ++i) { InvokeSetPtr invokeSet = bucket[i]; if (objectEquals(invokeSet->callable, callable) && objectVectorEquals(invokeSet->argsKey, argsKey)) { return invokeSet; } } OverloadPtr interface = callableInterface(callable); const vector<OverloadPtr> &overloads = callableOverloads(callable); InvokeSetPtr invokeSet = new InvokeSet(callable, argsKey, interface, overloads); bucket.push_back(invokeSet); return invokeSet; }
InvokeSet* lookupInvokeSet(ObjectPtr callable, llvm::ArrayRef<TypePtr> argsKey) { if (!invokeTablesInitialized) initInvokeTables(); int h = objectHash(callable) + objectVectorHash(argsKey); h &= (invokeTable.size() - 1); llvm::SmallVector<InvokeSet*, 2> &bucket = invokeTable[h]; for (unsigned i = 0; i < bucket.size(); ++i) { InvokeSet* invokeSet = bucket[i]; if (objectEquals(invokeSet->callable, callable) && objectVectorEquals(invokeSet->argsKey, argsKey)) { return invokeSet; } } OverloadPtr interface = callableInterface(callable); llvm::ArrayRef<OverloadPtr> overloads = callableOverloads(callable); InvokeSet* invokeSet = new InvokeSet(callable, argsKey, interface, overloads); invokeSet->shouldLog = shouldLogCallable(callable); bucket.push_back(invokeSet); return invokeSet; }
LCStringRef objectCreateHashString(LCObjectRef object) { char hash[HASH_LENGTH]; objectHash(object, hash); return LCStringCreate(hash); }
static char* test_array() { LCStringRef string1 = LCStringCreate("abc"); LCStringRef string2 = LCStringCreate("def"); LCStringRef string3 = LCStringCreate("ghi"); LCStringRef stringArray[] = {string1, string2, string3}; LCArrayRef array = LCArrayCreate(stringArray, 3); mu_assert("LCArray stores elements correctly", (LCArrayObjectAtIndex(array, 0)==string1) && (LCArrayObjectAtIndex(array, 1)==string2)); LCArrayRef subArray = LCArrayCreateSubArray(array, 1, -1); LCArrayRef subArray1 = LCArrayCreateSubArray(array, 1, 2); mu_assert("LCArrayCreateSubArray(array, start, -1) is correct", (LCArrayObjectAtIndex(subArray, 0)==string2) && (LCArrayObjectAtIndex(subArray, 1)==string3)); mu_assert("LCArrayCreateSubArray is correct", (LCArrayObjectAtIndex(subArray1, 0)==string2) && (LCArrayObjectAtIndex(subArray1, 1)==string3)); LCArrayRef arrayAppend = LCArrayCreateAppendingObjects(array, stringArray, 3); LCObjectRef* arrayAppendObjs = LCArrayObjects(arrayAppend); mu_assert("LCArrayCreateAppendingObjects", (arrayAppendObjs[3] == string1) && (arrayAppendObjs[4] == string2) && (arrayAppendObjs[5] == string3)); LCMutableArrayRef mArray = LCMutableArrayCreate(stringArray, 3); mu_assert("LCMutableArrayCreate", (LCMutableArrayObjectAtIndex(mArray, 0)==string1) && (LCMutableArrayObjectAtIndex(mArray, 1)==string2) && (LCMutableArrayObjectAtIndex(mArray, 2)==string3)); LCStringRef string4 = LCStringCreate("jkl"); LCMutableArrayAddObject(mArray, string4); mu_assert("LCMutableArrayAddObject", LCMutableArrayObjectAtIndex(mArray, 3) == string4); for (LCInteger i=0; i<50; i++) { LCMutableArrayAddObject(mArray, string4); } mu_assert("LCMutableArrayAddObject 50 times", (LCMutableArrayObjectAtIndex(mArray, 50) == string4) && (LCMutableArrayObjectAtIndex(mArray, 1) == string2)); LCMutableArrayRemoveIndex(mArray, 1); mu_assert("LCMutableArrayRemoveIndex1", (LCMutableArrayObjectAtIndex(mArray, 0)==string1) && (LCMutableArrayObjectAtIndex(mArray, 1)==string3) && (LCMutableArrayObjectAtIndex(mArray, 2)==string4)); LCMutableArrayRemoveIndex(mArray, 0); mu_assert("LCMutableArrayRemoveIndex2", LCMutableArrayObjectAtIndex(mArray, 0)==string3); LCMutableArrayRemoveObject(mArray, string3); mu_assert("LCMutableArrayRemoveObject", LCMutableArrayObjectAtIndex(mArray, 0)==string4); LCStringRef sortStrings[] = {string2, string3, string1}; LCMutableArrayRef sortArray = LCMutableArrayCreate(sortStrings, 3); LCMutableArraySort(sortArray); LCStringRef* sorted = LCMutableArrayObjects(sortArray); mu_assert("LCMutableArraySort", (sorted[0] == string1) && (sorted[1] == string2) && (sorted[2] == string3)); LCArrayRef arrays[] = {array, array}; LCArrayRef mergedArray = LCArrayCreateFromArrays(arrays, 2); mu_assert("LCArrayCreateFromArrays", LCArrayLength(mergedArray)==2*LCArrayLength(array)); LCArrayRef mappedArray = LCArrayCreateArrayWithMap(array, NULL, arrayMap); char string1Hash[HASH_LENGTH]; objectHash(string1, string1Hash); mu_assert("LCArrayCreateArrayWithMap", LCStringEqualCString(LCArrayObjectAtIndex(mappedArray, 0), string1Hash)); LCArrayRef pathArray1 = createPathArray(LCStringCreate("123/457/789")); LCArrayRef pathArray2 = createPathArray(LCStringCreate("123/678/789")); LCArrayRef pathArray3 = createPathArray(LCStringCreate("234")); mu_assert("LCArray compare", objectCompare(pathArray1, pathArray2)==LCSmaller && objectCompare(pathArray1, pathArray3)==LCSmaller && objectCompare(pathArray2, pathArray1)==LCGreater && objectCompare(pathArray2, pathArray3)==LCSmaller); return 0; }
static LCObjectRef arrayMap(LCInteger i, void* info, LCObjectRef each) { LCStringRef string = (LCStringRef)each; char hash[HASH_LENGTH]; objectHash(string, hash); return LCStringCreate(hash); }