internal PersistentMapImpl(Storage storage, Type keyType, int initialSize) : base(storage) { type = ClassDescriptor.getTypeCode(keyType); keys = new IComparable[initialSize]; values = storage.CreateLink(initialSize); }
internal void exportMultiFieldIndex(int oid, byte[] data) { Btree btree = new Btree(data, ObjectHeader.Sizeof); storage.assignOid(btree, oid); writer.Write(" <Perst.Impl.BtreeMultiFieldIndex id=\"" + oid + "\" unique=\"" + (btree.unique ? '1' : '0') + "\" class="); int offs = exportString(data, Btree.Sizeof); int nFields = Bytes.unpack4(data, offs); offs += 4; for (int i = 0; i < nFields; i++) { writer.Write(" field" + i + "="); offs = exportString(data, offs); } writer.Write(">\n"); int nTypes = Bytes.unpack4(data, offs); offs += 4; compoundKeyTypes = new ClassDescriptor.FieldType[nTypes]; for (int i = 0; i < nTypes; i++) { compoundKeyTypes[i] = (ClassDescriptor.FieldType)Bytes.unpack4(data, offs); offs += 4; } btree.export(this); compoundKeyTypes = null; writer.Write(" </Perst.Impl.BtreeMultiFieldIndex>\n"); }
private ThickFieldIndex(StorageImpl db, Type cls, string fieldName, KeyMember mbr) : base(db, mbr.type) #endif { this.mbr = mbr; this.cls = cls; this.fieldName = fieldName; type = ClassDescriptor.convertToNotNullable(ClassDescriptor.getTypeCode(mbr.type)); }
public override void init(Type cls, ClassDescriptor.FieldType type, string[] fieldNames, bool unique, long autoincCount) { this.cls = cls; this.unique = unique; this.fieldName = fieldNames[0]; this.className = ClassDescriptor.getTypeName(cls); this.autoincCount = autoincCount; lookupField(fieldNames[0]); this.type = checkType(mbrType); }
public override void init(Type cls, ClassDescriptor.FieldType type, string[] fieldNames, bool unique, long autoincCount) { this.cls = cls; this.unique = unique; this.fieldNames = fieldNames; this.className = ClassDescriptor.getTypeName(cls); locateFields(); this.type = ClassDescriptor.FieldType.tpArrayOfByte; types = new ClassDescriptor.FieldType[fieldNames.Length]; for (int i = 0; i < types.Length; i++) { Type mbrType = mbr[i] is FieldInfo ? ((FieldInfo)mbr[i]).FieldType : ((PropertyInfo)mbr[i]).PropertyType; types[i] = checkType(mbrType); } }
internal void exportAssoc(int oid, byte[] body, int offs, int size, ClassDescriptor.FieldType type) { writer.Write(" <ref id=\"" + oid + "\""); if ((exportedBitmap[oid >> 5] & (1 << (oid & 31))) == 0) { markedBitmap[oid >> 5] |= 1 << (oid & 31); } if (compoundKeyTypes != null) { exportCompoundKey(body, offs, size, type); } else { writer.Write(" key=\""); exportKey(body, offs, size, type); writer.Write("\""); } writer.Write("/>\n"); }
void exportCompoundKey(byte[] body, int offs, int size, ClassDescriptor.FieldType type) { Debug.Assert(type == ClassDescriptor.FieldType.tpArrayOfByte); int end = offs + size; for (int i = 0; i < compoundKeyTypes.Length; i++) { type = compoundKeyTypes[i]; if (type == ClassDescriptor.FieldType.tpArrayOfByte || type == ClassDescriptor.FieldType.tpString) { size = Bytes.unpack4(body, offs); offs += 4; } writer.Write(" key" + i + "=\""); offs = exportKey(body, offs, size, type); writer.Write("\""); } Debug.Assert(offs == end); }
internal void exportCompoundIndex(int oid, byte[] data, string name) { Btree btree = createBtree(oid, data); name = exportIdentifier(name); writer.Write(" <" + name + " id=\"" + oid + "\" unique=\"" + (btree.IsUnique ? '1' : '0') + "\""); int offs = btree.HeaderSize; int nTypes = Bytes.unpack4(data, offs); offs += 4; compoundKeyTypes = new ClassDescriptor.FieldType[nTypes]; for (int i = 0; i < nTypes; i++) { ClassDescriptor.FieldType type = (ClassDescriptor.FieldType)Bytes.unpack4(data, offs); compoundKeyTypes[i] = type; writer.Write(" type" + i + "=\"" + type + "\""); offs += 4; } writer.Write(">\n"); btree.export(this); compoundKeyTypes = null; writer.Write(" </" + name + ">\n"); }
private int packKeyPart(ByteBuffer buf, int dst, ClassDescriptor.FieldType type, object val) { switch (type) { case ClassDescriptor.FieldType.tpBoolean: dst = buf.packBool(dst, (bool)val); break; case ClassDescriptor.FieldType.tpByte: dst = buf.packI1(dst, (byte)val); break; case ClassDescriptor.FieldType.tpSByte: dst = buf.packI1(dst, (sbyte)val); break; case ClassDescriptor.FieldType.tpShort: dst = buf.packI2(dst, (short)val); break; case ClassDescriptor.FieldType.tpUShort: dst = buf.packI2(dst, (ushort)val); break; case ClassDescriptor.FieldType.tpChar: dst = buf.packI2(dst, (char)val); break; case ClassDescriptor.FieldType.tpInt: case ClassDescriptor.FieldType.tpOid: case ClassDescriptor.FieldType.tpEnum: dst = buf.packI4(dst, (int)val); break; case ClassDescriptor.FieldType.tpUInt: dst = buf.packI4(dst, (int)(uint)val); break; case ClassDescriptor.FieldType.tpObject: dst = buf.packI4(dst, val != null ? (int)((IPersistent)val).Oid : 0); break; case ClassDescriptor.FieldType.tpLong: dst = buf.packI8(dst, (long)val); break; case ClassDescriptor.FieldType.tpULong: dst = buf.packI8(dst, (long)(ulong)val); break; case ClassDescriptor.FieldType.tpDate: dst = buf.packDate(dst, (DateTime)val); break; case ClassDescriptor.FieldType.tpFloat: dst = buf.packF4(dst, (float)val); break; case ClassDescriptor.FieldType.tpDouble: dst = buf.packF8(dst, (double)val); break; case ClassDescriptor.FieldType.tpDecimal: dst = buf.packDecimal(dst, (decimal)val); break; case ClassDescriptor.FieldType.tpGuid: dst = buf.packGuid(dst, (Guid)val); break; case ClassDescriptor.FieldType.tpString: dst = buf.packString(dst, (string)val); break; case ClassDescriptor.FieldType.tpArrayOfByte: buf.extend(dst + 4); if (val != null) { byte[] arr = (byte[])val; int len = arr.Length; Bytes.pack4(buf.arr, dst, len); dst += 4; buf.extend(dst + len); Array.Copy(arr, 0, buf.arr, dst, len); dst += len; } else { Bytes.pack4(buf.arr, dst, 0); dst += 4; } break; default: Debug.Assert(false, "Invalid type"); break; } return(dst); }
internal void extract(Page pg, int offs, ClassDescriptor.FieldType type) { byte[] data = pg.data; switch (type) { case ClassDescriptor.FieldType.tpBoolean: key = new Key(data[offs] != 0); break; case ClassDescriptor.FieldType.tpSByte: key = new Key((sbyte)data[offs]); break; case ClassDescriptor.FieldType.tpByte: key = new Key(data[offs]); break; case ClassDescriptor.FieldType.tpShort: key = new Key(Bytes.unpack2(data, offs)); break; case ClassDescriptor.FieldType.tpUShort: key = new Key((ushort)Bytes.unpack2(data, offs)); break; case ClassDescriptor.FieldType.tpChar: key = new Key((char)Bytes.unpack2(data, offs)); break; case ClassDescriptor.FieldType.tpInt: key = new Key(Bytes.unpack4(data, offs)); break; case ClassDescriptor.FieldType.tpEnum: case ClassDescriptor.FieldType.tpUInt: case ClassDescriptor.FieldType.tpObject: case ClassDescriptor.FieldType.tpOid: key = new Key((uint)Bytes.unpack4(data, offs)); break; case ClassDescriptor.FieldType.tpLong: key = new Key(Bytes.unpack8(data, offs)); break; case ClassDescriptor.FieldType.tpDate: case ClassDescriptor.FieldType.tpULong: key = new Key((ulong)Bytes.unpack8(data, offs)); break; case ClassDescriptor.FieldType.tpFloat: key = new Key(Bytes.unpackF4(data, offs)); break; case ClassDescriptor.FieldType.tpDouble: key = new Key(Bytes.unpackF8(data, offs)); break; case ClassDescriptor.FieldType.tpGuid: key = new Key(Bytes.unpackGuid(data, offs)); break; case ClassDescriptor.FieldType.tpDecimal: key = new Key(Bytes.unpackDecimal(data, offs)); break; default: Debug.Assert(false, "Invalid type"); break; } }
internal void createIndex(String indexType) { XMLScanner.Token tkn; int oid = 0; bool unique = false; String className = null; String fieldName = null; String[] fieldNames = null; long autoinc = 0; String type = null; ClassDescriptor.FieldType[] types = null; while ((tkn = scanner.scan()) == XMLScanner.Token.IDENT) { string attrName = scanner.Identifier; if (scanner.scan() != XMLScanner.Token.EQ || scanner.scan() != XMLScanner.Token.SCONST) { throwException("Attribute value expected"); } string attrValue = scanner.String; if (attrName.Equals("id")) { oid = mapId(parseInt(attrValue)); } else if (attrName.Equals("unique")) { unique = parseInt(attrValue) != 0; } else if (attrName.Equals("class")) { className = attrValue; } else if (attrName.Equals("type")) { type = attrValue; } else if (attrName.Equals("autoinc")) { autoinc = parseInt(attrValue); } else if (attrName.Equals("field")) { fieldName = attrValue; } else if (attrName.StartsWith("field")) { int fieldNo = Int32.Parse(attrName.Substring(5)); if (fieldNames == null || fieldNames.Length <= fieldNo) { String[] newFieldNames = new String[fieldNo+1]; if (fieldNames != null) { Array.Copy(fieldNames, 0, newFieldNames, 0, fieldNames.Length); } fieldNames = newFieldNames; } fieldNames[fieldNo] = attrValue; } else if (attrName.StartsWith("type")) { int typeNo = Int32.Parse(attrName.Substring(4)); if (types == null || types.Length <= typeNo) { ClassDescriptor.FieldType[] newTypes = new ClassDescriptor.FieldType[typeNo+1]; if (types != null) { Array.Copy(types, 0, newTypes, 0, types.Length); } types = newTypes; } types[typeNo] = mapType(attrValue); } } if (tkn != XMLScanner.Token.GT) { throwException("Unclosed element tag"); } if (oid == 0) { throwException("ID is not specified or index"); } #if USE_GENERICS ClassDescriptor desc = storage.getClassDescriptor(findClassByName(indexType)); Btree btree = (Btree)desc.newInstance(); #else Btree btree = null; #endif if (className != null) { Type cls = findClassByName(className); if (fieldName != null) { #if USE_GENERICS btree.init(cls, null, new string[]{fieldName}, unique, autoinc); #else btree = indexType.StartsWith("Perst.Impl.BtreeCaseInsensitiveFieldIndex") ? (Btree)new BtreeCaseInsensitiveFieldIndex(cls, fieldName, unique, autoinc) : (Btree)new BtreeFieldIndex(cls, fieldName, unique, autoinc); #endif } else if (fieldNames != null) { #if USE_GENERICS btree.init(cls, null, fieldNames, unique, autoinc); #else btree = indexType.StartsWith("Perst.Impl.BtreeCaseInsensitiveMultiFieldIndex") ? (Btree)new BtreeCaseInsensitiveMultiFieldIndex(cls, fieldNames, unique) : (Btree)new BtreeMultiFieldIndex(cls, fieldNames, unique); #endif } else { throwException("Field name is not specified for field index"); } } else { if (types != null) { #if USE_GENERICS btree.init(null, types, null, unique, autoinc); #else btree = new BtreeCompoundIndex(types, unique); #endif } else if (type == null) { if (indexType.StartsWith("Perst.Impl.PersistentSet")) { #if !USE_GENERICS btree = new PersistentSet(unique); #endif } else { throwException("Key type is not specified for index"); } } else { if (indexType.StartsWith("org.garret.perst.impl.BitIndexImpl")) { #if !USE_GENERICS btree = new BitIndexImpl(); #endif } else { #if USE_GENERICS btree.init(null, new ClassDescriptor.FieldType[]{mapType(type)}, null, unique, autoinc); #else btree = new Btree(mapType(type), unique); #endif } } } storage.AssignOid(btree, oid, false); while ((tkn = scanner.scan()) == XMLScanner.Token.LT) { if (scanner.scan() != XMLScanner.Token.IDENT || !scanner.Identifier.Equals("ref")) { throwException("<ref> element expected"); } XMLElement refElem = readElement("ref"); Key key; if (fieldNames != null) { String[] values = new String[fieldNames.Length]; #if USE_GENERICS types = btree.FieldTypes; #else types = ((BtreeMultiFieldIndex)btree).types; #endif for (int i = 0; i < values.Length; i++) { values[i] = getAttribute(refElem, "key"+i); } key = createCompoundKey(types, values); } else if (types != null) { String[] values = new String[fieldNames.Length]; for (int i = 0; i < values.Length; i++) { values[i] = getAttribute(refElem, "key"+i); } key = createCompoundKey(types, values); } else { key = createKey(btree.FieldType, getAttribute(refElem, "key")); } object obj = new PersistentStub(storage, mapId(getIntAttribute(refElem, "id"))); btree.insert(key, obj, false); } if (tkn != XMLScanner.Token.LTS || scanner.scan() != XMLScanner.Token.IDENT || !scanner.Identifier.Equals(indexType) || scanner.scan() != XMLScanner.Token.GT) { throwException("Element is not closed"); } #if USE_GENERICS ByteBuffer buf = new ByteBuffer(); buf.extend(ObjectHeader.Sizeof); int size = storage.packObject(btree, desc, ObjectHeader.Sizeof, buf); byte[] data = buf.arr; ObjectHeader.setSize(data, 0, size); ObjectHeader.setType(data, 0, desc.Oid); #else byte[] data = storage.packObject(btree, false); int size = ObjectHeader.getSize(data, 0); #endif long pos = storage.allocate(size, 0); storage.setPos(oid, pos | StorageImpl.dbModifiedFlag); storage.pool.put(pos & ~ StorageImpl.dbFlagsMask, data, size); }
int exportKey(byte[] body, int offs, int size, ClassDescriptor.FieldType type) { switch (type) { case ClassDescriptor.FieldType.tpBoolean: writer.Write(body[offs++] != 0?"1":"0"); break; case ClassDescriptor.FieldType.tpByte: writer.Write(System.Convert.ToString((byte)body[offs++])); break; case ClassDescriptor.FieldType.tpSByte: writer.Write(System.Convert.ToString((sbyte)body[offs++])); break; case ClassDescriptor.FieldType.tpChar: writer.Write(System.Convert.ToString((ushort)Bytes.unpack2(body, offs))); offs += 2; break; case ClassDescriptor.FieldType.tpShort: writer.Write(System.Convert.ToString((ushort)Bytes.unpack2(body, offs))); offs += 2; break; case ClassDescriptor.FieldType.tpUShort: writer.Write(System.Convert.ToString((ushort)Bytes.unpack2(body, offs))); offs += 2; break; case ClassDescriptor.FieldType.tpInt: writer.Write(System.Convert.ToString(Bytes.unpack4(body, offs))); offs += 4; break; case ClassDescriptor.FieldType.tpUInt: case ClassDescriptor.FieldType.tpObject: case ClassDescriptor.FieldType.tpEnum: writer.Write(System.Convert.ToString((uint)Bytes.unpack4(body, offs))); offs += 4; break; case ClassDescriptor.FieldType.tpLong: writer.Write(System.Convert.ToString(Bytes.unpack8(body, offs))); offs += 8; break; case ClassDescriptor.FieldType.tpULong: writer.Write(System.Convert.ToString((ulong)Bytes.unpack8(body, offs))); offs += 8; break; case ClassDescriptor.FieldType.tpFloat: writer.Write(System.Convert.ToString(Bytes.unpackF4(body, offs))); offs += 4; break; case ClassDescriptor.FieldType.tpDouble: writer.Write(System.Convert.ToString(Bytes.unpackF8(body, offs))); offs += 8; break; case ClassDescriptor.FieldType.tpGuid: writer.Write(Bytes.unpackGuid(body, offs).ToString()); offs += 16; break; case ClassDescriptor.FieldType.tpDecimal: writer.Write(Bytes.unpackDecimal(body, offs).ToString()); offs += 16; break; case ClassDescriptor.FieldType.tpString: for (int i = 0; i < size; i++) { exportChar((char)Bytes.unpack2(body, offs)); offs += 2; } break; case ClassDescriptor.FieldType.tpArrayOfByte: for (int i = 0; i < size; i++) { byte b = body[offs++]; writer.Write(hexDigit[(b >> 4) & 0xF]); writer.Write(hexDigit[b & 0xF]); } break; case ClassDescriptor.FieldType.tpDate: writer.Write(Bytes.unpackDate(body, offs).ToString()); offs += 8; break; default: Debug.Assert(false, "Invalid type"); break; } return(offs); }