{$IfDef FPC}{$CodePage cp1251}{$EndIf FPC}
unit m3AttrIndexWriter;
{* Писатель индекса атрибутов в "упрощённом виде".
[RequestLink:901972048] }
// --------------------------------------------------------------------------
// Родители: "Indexer" <> MUID: (58DE48000209) :: "m3" <> MUID: (58DE47D500CA) :: "Shared Delphi For Archi" <> MUID: (4ABA2360025A)
// --------------------------------------------------------------------------
// Модуль: "w:\common\components\rtl\Garant\m3\m3AttrIndexWriter.pas" GeneratorVersion: 1.0.0.883901
// Стереотип: "<>"
// Элемент модели: "Tm3AttrIndexWriter" MUID: (69AC2E42033D)
// --------------------------------------------------------------------------
//#UC START# *69AC2E42033DbeforeDefines*
//#UC END# *69AC2E42033DbeforeDefines*
{$Include m3Define.inc}
interface
uses
l3IntfUses
, l3SimpleObject
, l3BaseStream
, m3SearcherInterfaces
, l3Ranges
, TypInfo
, l3CoreInterfaces
, SysUtils
, l3IntegerToIntegerMap
, m3IndexElements
//#UC START# *69AC2E42033Dintf_uses*
;
(*type
T64to32 = packed record
rLow : Integer;
rHigh : Integer;
end;//T64to32
T64toSmallInts = packed array [0..3] of SmallInt;
T64toBytes = packed array [0..7] of Byte;*)
type
Tm3BodyFrameInfo = packed record
rCount : Integer;
rMinKeyID : Int64;
rMaxKeyID : Int64;
rNextPartPos : Int64;
end;//Tm3BodyFrameInfo
const
c_m3AttrIndexWriterGUID : TGUID = '{2020CBAD-78CC-494B-84B0-2EF18ADEA65A}';
cSequentialVersion = 2;
cOurVersion = cSequentialVersion;
cSignature = 1400951
//#UC END# *69AC2E42033Dintf_uses*
;
type
Tm3AttrIndexWriterSubStreamInfoPtr = ^Tm3AttrIndexWriterSubStreamInfo;
{* Указатель на Tm3AttrIndexWriterSubStreamInfo }
Tm3AttrIndexWriterBodyElementPtr = ^Tm3AttrIndexWriterBodyElement;
{* Указатель на Tm3AttrIndexWriterBodyElement }
Tm3AttrIndexWriterHeaderPtr = ^Tm3AttrIndexWriterHeader;
{* Указатель на Tm3AttrIndexWriterHeader }
(*
_Mm3AttrIndexWriter_ = interface
procedure WriteVersions(const aVersions: Im3IndexedVersions);
procedure WriteModified(const aModified: Il3RangeEnumerable;
aTimeStamp: TDateTime);
procedure WriteRange(const aRange: Tl3Range);
procedure WriteOperation(anOperation: Tm3GroupOperation);
procedure StartBody(aCount: Integer);
procedure FinishBody;
procedure WriteBodyElement(aKey: Integer;
const aValue: Il3RangeEnumerable);
end;//_Mm3AttrIndexWriter_
*)
Tm3AttrIndexWriter = class;
Im3AttrIndexWriter = interface
['{59C707EB-8FD8-433F-901D-DBC22A0ABA21}']
procedure WriteVersions(const aVersions: Im3IndexedVersions);
procedure WriteModified(const aModified: Il3RangeEnumerable;
aTimeStamp: TDateTime);
procedure WriteRange(const aRange: Tl3Range);
procedure WriteOperation(anOperation: Tm3GroupOperation);
procedure StartBody(aCount: Integer);
procedure FinishBody;
procedure WriteBodyElement(aKey: Integer;
const aValue: Il3RangeEnumerable);
end;//Im3AttrIndexWriter
Tm3AttrIndexWriterSubStreamInfo = packed record
//#UC START# *69AFF780026Apubl*
rPos : Int64;
rSize : Int64;
//#UC END# *69AFF780026Apubl*
end;//Tm3AttrIndexWriterSubStreamInfo
Tm3ElementType = (
m3_etNone
, m3_etSingle
, m3_etPair
, m3_etMultiply
, m3_etLZO
, m3_etZLib
, m3_et4
, m3_et8
, m3_etRange
);//Tm3ElementType
Tm3AttrIndexWriterBodyElement = packed record
//#UC START# *69AC79CD0094publ*
rType : Tm3ElementType;
rKey : Int64;
rValue : Int64;
//#UC END# *69AC79CD0094publ*
end;//Tm3AttrIndexWriterBodyElement
Tm3AttrIndexWriterHeader = packed record
//#UC START# *69AC312A0001publ*
rZeroStart : Integer;
rVer : array [0..2] of AnsiChar;
rVersion : Integer;
rSig : array [0..2] of AnsiChar;
rSignature : Integer;
rTim : array [0..2] of AnsiChar;
rTimeStamp : Int64;
//rTimeStamp : TDateTime;
rHea : array [0..2] of AnsiChar;
rHeaderStart : Int64;
rHeaderEnd : Int64;
rStr : array [0..2] of AnsiChar;
rStreamEnd : Int64;
rRan : array [0..2] of AnsiChar;
rRange : Tm3IDRange;
rOper : array [0..3] of AnsiChar;
rOperation : Tm3GroupOperation;
rMod : array [0..2] of AnsiChar;
rModified : Tm3AttrIndexWriterSubStreamInfo;
rVers : array [0..3] of AnsiChar;
rVersions : Tm3AttrIndexWriterSubStreamInfo;
rBod : array [0..2] of AnsiChar;
rBody : Tm3AttrIndexWriterSubStreamInfo;
rCnt : array [0..2] of AnsiChar;
rElementsCount : Integer;
rMin : array [0..2] of AnsiChar;
rMinKeyID : Integer;
rMax : array [0..2] of AnsiChar;
rMaxKeyID : Integer;
rNextPartPos : Int64;
rZeroEnd : Integer;
//#UC END# *69AC312A0001publ*
end;//Tm3AttrIndexWriterHeader
Tm3PlainAttrIndexDumperElementEnumerator = class(Tl3SimpleObject, Im3AttrIndexElementEnumerator)
private
f_Count: Integer;
f_Index: Integer;
f_Current: Im3AttrIndexElement;
f_FileName: TFileName;
f_Stream: Tl3Stream;
f_Body: Tm3AttrIndexWriterSubStreamInfo;
protected
function Get_Current: Im3AttrIndexElement;
procedure Cleanup; override;
{* Функция очистки полей объекта. }
procedure ClearFields; override;
public
constructor Create(aCount: Integer;
const aFileName: TFileName;
const aBody: Tm3AttrIndexWriterSubStreamInfo); reintroduce;
class function Make(aCount: Integer;
const aFileName: TFileName;
const aBody: Tm3AttrIndexWriterSubStreamInfo): Im3AttrIndexElementEnumerator; reintroduce;
{$If NOT Defined(l3NoSRT)}
function SetRefTo(var thePlace: Tm3PlainAttrIndexDumperElementEnumerator): Boolean; overload; {$If Defined(l3HasInl)}inline;{$IfEnd}
{$IfEnd} // NOT Defined(l3NoSRT)
function MoveNext: Boolean;
{* Перемещается на следующий элемент контейнера.
Возвращает true если элемент валидный. }
function pCurrent: Im3AttrIndexElementEnumerator_PCurrentItemType;
{* Указатель на текущий элемент. Он "закеширован" }
function CanMoveNext: Boolean;
{* Определяет - можно ли переместиться на следующий элемент контейнера. }
public
property Current: Im3AttrIndexElement
read Get_Current;
{* Текущий элемент. Он "закеширован" }
end;//Tm3PlainAttrIndexDumperElementEnumerator
Tm3PlainAttrIndexDumperElement = class(Tl3SimpleObject, Im3AttrIndexElement)
private
f_Element: Tm3AttrIndexWriterBodyElement;
f_FileName: TFileName;
f_Values: Il3RangeEnumerable;
protected
function Get_ID: Integer;
function Get_Values: Il3RangeEnumerable;
procedure Cleanup; override;
{* Функция очистки полей объекта. }
procedure ClearFields; override;
public
constructor Create(const anElement: Tm3AttrIndexWriterBodyElement;
const aFileName: TFileName); reintroduce;
class function Make(const anElement: Tm3AttrIndexWriterBodyElement;
const aFileName: TFileName): Im3AttrIndexElement; reintroduce;
{$If NOT Defined(l3NoSRT)}
function SetRefTo(var thePlace: Tm3PlainAttrIndexDumperElement): Boolean; overload; {$If Defined(l3HasInl)}inline;{$IfEnd}
{$IfEnd} // NOT Defined(l3NoSRT)
end;//Tm3PlainAttrIndexDumperElement
//#UC START# *69AE74DB018Aci*
//#UC END# *69AE74DB018Aci*
Tm3PlainAttrIndexDumper = class(Tl3SimpleObject, Im3AttrIndexDumper)
{* Читатель индекса атрибутов в "упрощённом виде".
[RequestLink:901972048] }
private
f_Header: Tm3AttrIndexWriterHeader;
f_FileName: TFileName;
f_Modified: Il3RangeEnumerable;
f_Versions: Tl3IntegerToIntegerMap;
f_Stream: Tl3Stream;
{* Наверное потому что на всё наше время жизни поток надо держать открытым. Чтобы его не удалили }
f_SearchMode: Tm3SearchMode;
f_EnumeratorForSeq: Im3AttrIndexElementEnumerator;
f_Sequential: Boolean;
protected
function pm_GetFirst: Il3RangeEnumerable;
function pm_GetLast: Il3RangeEnumerable;
function pm_GetCount: Integer;
function ModifiedDocuments: Il3RangeEnumerable;
function IndexedVersions: Im3IndexedVersions;
function Get_Range: Tm3IDRange;
function ValuesByKey(aKey: Integer): Il3RangeEnumerable;
function TimeStamp: TDateTime;
function Get_MaxKeyID: Integer;
function Get_Operation: Tm3GroupOperation;
function Get_MinKeyID: Integer;
procedure Set_SearchMode(aValue: Tm3SearchMode);
function Get_Sequential: Boolean;
function ToTheLeftOf(const anOther: Im3AttrIndexDumper): Boolean;
procedure Cleanup; override;
{* Функция очистки полей объекта. }
procedure ClearFields; override;
public
constructor Create(const aFileName: TFileName;
aStream: Tl3Stream = nil); reintroduce;
class function Make(const aFileName: TFileName;
aStream: Tl3Stream = nil): Im3AttrIndexDumper; reintroduce;
class function TryMake(const aFileName: TFileName;
out theDumper: Im3AttrIndexDumper): Boolean;
{$If NOT Defined(l3NoSRT)}
function SetRefTo(var thePlace: Tm3PlainAttrIndexDumper): Boolean; overload; {$If Defined(l3HasInl)}inline;{$IfEnd}
{$IfEnd} // NOT Defined(l3NoSRT)
function GetEnumerator: Im3AttrIndexElementEnumerator;
{* Получает Enumerator для перебора элементов "контейнера".
Вся эта конструкция совместима с "синтаксическим сахаром" вида:
for Item in Container do Process(Item);
Который поддерживается в "новых" Delphi.
См. http://mdp.garant.ru/pages/viewpage.action?pageId=152961307 }
public
property First: Il3RangeEnumerable
read pm_GetFirst;
{* Первый элемент. }
property Last: Il3RangeEnumerable
read pm_GetLast;
{* Последний элемент. }
property Count: Integer
read pm_GetCount;
{* Число элементов. }
//#UC START# *69AE74DB018Apubl*
//#UC END# *69AE74DB018Apubl*
end;//Tm3PlainAttrIndexDumper
//#UC START# *69AC2E42033Dci*
//#UC END# *69AC2E42033Dci*
Tm3AttrIndexWriter = class(Tl3SimpleObject, Im3AttrIndexWriter)
{* Писатель индекса атрибутов в "упрощённом виде".
[RequestLink:901972048] }
private
f_Stream: Tl3Stream;
f_Header: Tm3AttrIndexWriterHeader;
f_HeaderSave: Tm3AttrIndexWriterHeader;
f_IsDirect: Boolean;
f_Sequential: Boolean;
private
procedure WriteEOL;
procedure SaveHeader;
protected
procedure Cleanup; override;
{* Функция очистки полей объекта. }
procedure BeforeRelease; override;
public
constructor Create(aStream: Tl3Stream;
aIsDirect: Boolean); reintroduce;
class function Make(aStream: Tl3Stream;
aIsDirect: Boolean): Im3AttrIndexWriter; reintroduce;
{$If NOT Defined(l3NoSRT)}
function SetRefTo(var thePlace: Tm3AttrIndexWriter): Boolean; overload; {$If Defined(l3HasInl)}inline;{$IfEnd}
{$IfEnd} // NOT Defined(l3NoSRT)
procedure WriteVersions(const aVersions: Im3IndexedVersions);
procedure WriteModified(const aModified: Il3RangeEnumerable;
aTimeStamp: TDateTime);
procedure WriteRange(const aRange: Tl3Range);
procedure WriteOperation(anOperation: Tm3GroupOperation);
procedure StartBody(aCount: Integer);
procedure FinishBody;
procedure WriteBodyElement(aKey: Integer;
const aValue: Il3RangeEnumerable);
//#UC START# *69AC2E42033Dpubl*
private
f_PrevKey : Int64;
f_DeclaredCapacity : Integer;
f_Capacity : Integer;
f_FrameInfoPos : Int64;
f_FrameInfo : Tm3BodyFrameInfo;
f_SequentialInfoPos : Int64;
private
procedure ifWriteEOL;
procedure WriteStart(const aStr: Ansistring);
procedure WriteEnd(const aStr: Ansistring);
//#UC END# *69AC2E42033Dpubl*
end;//Tm3AttrIndexWriter
IBoxFor_Tm3AttrIndexWriterSubStreamInfo = interface(Il3Box)
['{253213BB-4BDA-4461-89E5-00D7F7D0F05D}']
function Get_Boxed: Tm3AttrIndexWriterSubStreamInfo;
function Get_pBoxed: Tm3AttrIndexWriterSubStreamInfoPtr;
property Boxed: Tm3AttrIndexWriterSubStreamInfo
read Get_Boxed;
property pBoxed: Tm3AttrIndexWriterSubStreamInfoPtr
read Get_pBoxed;
end;//IBoxFor_Tm3AttrIndexWriterSubStreamInfo
IBoxFor_Tm3AttrIndexWriterBodyElement = interface(Il3Box)
['{3109FDED-F5C6-4174-901E-B215D8CEE051}']
function Get_Boxed: Tm3AttrIndexWriterBodyElement;
function Get_pBoxed: Tm3AttrIndexWriterBodyElementPtr;
property Boxed: Tm3AttrIndexWriterBodyElement
read Get_Boxed;
property pBoxed: Tm3AttrIndexWriterBodyElementPtr
read Get_pBoxed;
end;//IBoxFor_Tm3AttrIndexWriterBodyElement
IBoxFor_Tm3AttrIndexWriterHeader = interface(Il3Box)
['{39FD53E2-BF26-44EA-80F2-B41EC80E03DC}']
function Get_Boxed: Tm3AttrIndexWriterHeader;
function Get_pBoxed: Tm3AttrIndexWriterHeaderPtr;
property Boxed: Tm3AttrIndexWriterHeader
read Get_Boxed;
property pBoxed: Tm3AttrIndexWriterHeaderPtr
read Get_pBoxed;
end;//IBoxFor_Tm3AttrIndexWriterHeader
function Tm3AttrIndexWriterSubStreamInfo_TypeInfo: PTypeInfo;
{$If NOT Defined(NoScripts)}
function Tm3AttrIndexWriterSubStreamInfo_ToValue(const aSelf: Tm3AttrIndexWriterSubStreamInfo): TtfwStackValue;
{$IfEnd} // NOT Defined(NoScripts)
{$If NOT Defined(NoScripts)}
function TtfwStackValue_C(const aSelf: Tm3AttrIndexWriterSubStreamInfo): TtfwStackValue; overload;
{$IfEnd} // NOT Defined(NoScripts)
{$If NOT Defined(NoScripts)}
function Tm3AttrIndexWriterSubStreamInfo_ToBox(const aSelf: Tm3AttrIndexWriterSubStreamInfo): Il3Box;
{$IfEnd} // NOT Defined(NoScripts)
{$If NOT Defined(NoScripts)}
function Tm3AttrIndexWriterSubStreamInfo_FromValue(const aValue: TtfwStackValue): Tm3AttrIndexWriterSubStreamInfo;
{$IfEnd} // NOT Defined(NoScripts)
function Tm3AttrIndexWriterBodyElement_TypeInfo: PTypeInfo;
{$If NOT Defined(NoScripts)}
function Tm3AttrIndexWriterBodyElement_ToValue(const aSelf: Tm3AttrIndexWriterBodyElement): TtfwStackValue;
{$IfEnd} // NOT Defined(NoScripts)
{$If NOT Defined(NoScripts)}
function TtfwStackValue_C(const aSelf: Tm3AttrIndexWriterBodyElement): TtfwStackValue; overload;
{$IfEnd} // NOT Defined(NoScripts)
{$If NOT Defined(NoScripts)}
function Tm3AttrIndexWriterBodyElement_ToBox(const aSelf: Tm3AttrIndexWriterBodyElement): Il3Box;
{$IfEnd} // NOT Defined(NoScripts)
{$If NOT Defined(NoScripts)}
function Tm3AttrIndexWriterBodyElement_FromValue(const aValue: TtfwStackValue): Tm3AttrIndexWriterBodyElement;
{$IfEnd} // NOT Defined(NoScripts)
function Tm3AttrIndexWriterHeader_TypeInfo: PTypeInfo;
{$If NOT Defined(NoScripts)}
function Tm3AttrIndexWriterHeader_ToValue(const aSelf: Tm3AttrIndexWriterHeader): TtfwStackValue;
{$IfEnd} // NOT Defined(NoScripts)
{$If NOT Defined(NoScripts)}
function TtfwStackValue_C(const aSelf: Tm3AttrIndexWriterHeader): TtfwStackValue; overload;
{$IfEnd} // NOT Defined(NoScripts)
{$If NOT Defined(NoScripts)}
function Tm3AttrIndexWriterHeader_ToBox(const aSelf: Tm3AttrIndexWriterHeader): Il3Box;
{$IfEnd} // NOT Defined(NoScripts)
{$If NOT Defined(NoScripts)}
function Tm3AttrIndexWriterHeader_FromValue(const aValue: TtfwStackValue): Tm3AttrIndexWriterHeader;
{$IfEnd} // NOT Defined(NoScripts)
implementation
uses
l3ImplUses
{$If NOT Defined(NoScripts)}
, tfwClassProcedure
{$IfEnd} // NOT Defined(NoScripts)
{$If NOT Defined(NoScripts)}
, tfwWordInfo
{$IfEnd} // NOT Defined(NoScripts)
{$If NOT Defined(NoScripts)}
, tfwScriptingInterfaces
{$IfEnd} // NOT Defined(NoScripts)
{$If NOT Defined(NoScripts)}
, tfwAxiomaticsResNameGetter
{$IfEnd} // NOT Defined(NoScripts)
, l3BoxForStruct
{$If NOT Defined(NoScripts)}
, TtfwTypeRegistrator_Proxy
{$IfEnd} // NOT Defined(NoScripts)
{$If NOT Defined(NoScripts)}
, TtfwClassRef_Proxy
{$IfEnd} // NOT Defined(NoScripts)
{$If NOT Defined(NoScripts)}
, tfwTypeInfo
{$IfEnd} // NOT Defined(NoScripts)
, l3Interfaces
, l3String
{$If NOT Defined(NoScripts)}
, tfwValueTypes
{$IfEnd} // NOT Defined(NoScripts)
{$If NOT Defined(NoScripts)}
, tfwRegisterableWordPrim
{$IfEnd} // NOT Defined(NoScripts)
, tfwCStringFactory
, l3NamedFileStream
, l3Stream
, m2COMLib
, l3Types
//#UC START# *69AC2E42033Dimpl_uses*
, Classes
, DateUtils
//, l3Types
, l3PointerUtils
, l3Date
, l3Enumerators
, m2MemLib
, m3Exceptions
, m3DBTools
, m3RangedDocumentsList
, m3LZODeflateStreamNew
, m3LZOInflateStreamNew
, l3TempMemoryStream
, m3ZLibDeflateStreamNew
, m3ZLibInflateStreamNew
, l3ZLibCompressStream
, l3ZLibDecompressStream
, l3Base
;
const
cFirstFrameInfoMark : AnsiString = 'ffi';
cSequentialMark : AnsiString = 'seq'
//#UC END# *69AC2E42033Dimpl_uses*
;
{$If NOT Defined(NoScripts)}
type
TkwIm3AttrIndexWriterWriteVersions = TtfwClassProcedure;
{* Слово скрипта m3AttrIndexWriter:WriteVersions }
{$IfEnd} // NOT Defined(NoScripts)
{$If NOT Defined(NoScripts)}
type
TkwIm3AttrIndexWriterWriteRange = TtfwClassProcedure;
{* Слово скрипта m3AttrIndexWriter:WriteRange }
{$IfEnd} // NOT Defined(NoScripts)
{$If NOT Defined(NoScripts)}
type
TkwIm3AttrIndexWriterWriteOperation = TtfwClassProcedure;
{* Слово скрипта m3AttrIndexWriter:WriteOperation }
{$IfEnd} // NOT Defined(NoScripts)
{$If NOT Defined(NoScripts)}
type
TkwIm3AttrIndexWriterStartBody = TtfwClassProcedure;
{* Слово скрипта m3AttrIndexWriter:StartBody }
{$IfEnd} // NOT Defined(NoScripts)
{$If NOT Defined(NoScripts)}
type
TkwIm3AttrIndexWriterFinishBody = TtfwClassProcedure;
{* Слово скрипта m3AttrIndexWriter:FinishBody }
{$IfEnd} // NOT Defined(NoScripts)
{$If NOT Defined(NoScripts)}
type
TkwIm3AttrIndexWriterWriteBodyElement = TtfwClassProcedure;
{* Слово скрипта m3AttrIndexWriter:WriteBodyElement }
{$IfEnd} // NOT Defined(NoScripts)
{$If NOT Defined(NoScripts)}
type
TIm3AttrIndexWriterKeywordsPackResNameGetter = {final} class(TtfwAxiomaticsResNameGetter)
{* Регистрация скриптованой аксиоматики }
public
class function ResName: AnsiString; override;
end;//TIm3AttrIndexWriterKeywordsPackResNameGetter
{$IfEnd} // NOT Defined(NoScripts)
{$If NOT Defined(NoScripts)}
type
TBoxFor_Tm3AttrIndexWriterSubStreamInfo = {final} class(Tl3BoxForStruct, IBoxFor_Tm3AttrIndexWriterSubStreamInfo)
private
f_Boxed: Tm3AttrIndexWriterSubStreamInfo;
protected
function Get_Boxed: Tm3AttrIndexWriterSubStreamInfo;
function Get_pBoxed: Tm3AttrIndexWriterSubStreamInfoPtr;
function GetDataPtr: Pointer; override;
function GetDataSize: Integer; override;
function GetBoxTypeInfo: PTypeInfo; override;
function GetAsPrintable(const aCtx: TtfwContextStub): Il3CString; override;
procedure ClearFields; override;
public
constructor Create(const aBoxed: Tm3AttrIndexWriterSubStreamInfo); reintroduce;
class function Make(const aBoxed: Tm3AttrIndexWriterSubStreamInfo): IBoxFor_Tm3AttrIndexWriterSubStreamInfo; reintroduce;
//#UC START# *69AFF780026ATBoxpubl*
//#UC END# *69AFF780026ATBoxpubl*
end;//TBoxFor_Tm3AttrIndexWriterSubStreamInfo
{$IfEnd} // NOT Defined(NoScripts)
{$If NOT Defined(NoScripts)}
type
TBoxFor_Tm3AttrIndexWriterBodyElement = {final} class(Tl3BoxForStruct, IBoxFor_Tm3AttrIndexWriterBodyElement)
private
f_Boxed: Tm3AttrIndexWriterBodyElement;
protected
function Get_Boxed: Tm3AttrIndexWriterBodyElement;
function Get_pBoxed: Tm3AttrIndexWriterBodyElementPtr;
function GetDataPtr: Pointer; override;
function GetDataSize: Integer; override;
function GetBoxTypeInfo: PTypeInfo; override;
function GetAsPrintable(const aCtx: TtfwContextStub): Il3CString; override;
procedure ClearFields; override;
public
constructor Create(const aBoxed: Tm3AttrIndexWriterBodyElement); reintroduce;
class function Make(const aBoxed: Tm3AttrIndexWriterBodyElement): IBoxFor_Tm3AttrIndexWriterBodyElement; reintroduce;
//#UC START# *69AC79CD0094TBoxpubl*
//#UC END# *69AC79CD0094TBoxpubl*
end;//TBoxFor_Tm3AttrIndexWriterBodyElement
{$IfEnd} // NOT Defined(NoScripts)
{$If NOT Defined(NoScripts)}
type
TBoxFor_Tm3AttrIndexWriterHeader = {final} class(Tl3BoxForStruct, IBoxFor_Tm3AttrIndexWriterHeader)
private
f_Boxed: Tm3AttrIndexWriterHeader;
protected
function Get_Boxed: Tm3AttrIndexWriterHeader;
function Get_pBoxed: Tm3AttrIndexWriterHeaderPtr;
function GetDataPtr: Pointer; override;
function GetDataSize: Integer; override;
function GetBoxTypeInfo: PTypeInfo; override;
function GetAsPrintable(const aCtx: TtfwContextStub): Il3CString; override;
procedure ClearFields; override;
public
constructor Create(const aBoxed: Tm3AttrIndexWriterHeader); reintroduce;
class function Make(const aBoxed: Tm3AttrIndexWriterHeader): IBoxFor_Tm3AttrIndexWriterHeader; reintroduce;
//#UC START# *69AC312A0001TBoxpubl*
//#UC END# *69AC312A0001TBoxpubl*
end;//TBoxFor_Tm3AttrIndexWriterHeader
{$IfEnd} // NOT Defined(NoScripts)
{$If NOT Defined(NoScripts)}
procedure TkwIm3AttrIndexWriterWriteVersions_ImplWriteVersions(const aCtx: TtfwContext;
const aSelf: Im3AttrIndexWriter;
const aVersions: Im3IndexedVersions);
begin
if (aSelf = nil) then
begin
Exit;
end;
aSelf.WriteVersions(aVersions);
end;//TkwIm3AttrIndexWriterWriteVersions_ImplWriteVersions
{$IfEnd} // NOT Defined(NoScripts)
{$If NOT Defined(NoScripts)}
function TkwIm3AttrIndexWriterWriteVersions_ParamsTypes: PTypeInfoArray;
begin
Result := TtfwWord.OpenTypesToTypes([TtfwParamInfo_C('aSelf', TypeInfo(Im3AttrIndexWriter)), TtfwParamInfo_C('aVersions', TtfwValueTypes.MakeTypedef('Im3IndexedVersions', TypeInfo(Im3IndexedVersions)))]);
end;//TkwIm3AttrIndexWriterWriteVersions_ParamsTypes
{$IfEnd} // NOT Defined(NoScripts)
{$If NOT Defined(NoScripts)}
procedure TkwIm3AttrIndexWriterWriteVersions_DoIt(const aCtx: TtfwContext);
var l_aSelf: Im3AttrIndexWriter;
var l_aVersions: Im3IndexedVersions;
begin
try
l_aSelf := Im3AttrIndexWriter(aCtx.rEngine.Pop.AsIntf(TypeInfo(Im3AttrIndexWriter)));
except
on E: Exception do
begin
aCtx.GetParamError('aSelf: Im3AttrIndexWriter : ', E);
Exit;
end;//on E: Exception
end;//try..except
try
l_aVersions := Im3IndexedVersions(aCtx.rEngine.Pop.AsIntf(TypeInfo(Im3IndexedVersions)));
except
on E: Exception do
begin
aCtx.GetParamError('aVersions: Im3IndexedVersions : ', E);
Exit;
end;//on E: Exception
end;//try..except
TkwIm3AttrIndexWriterWriteVersions_ImplWriteVersions(aCtx, l_aSelf, l_aVersions);
end;//TkwIm3AttrIndexWriterWriteVersions_DoIt
{$IfEnd} // NOT Defined(NoScripts)
{$If NOT Defined(NoScripts)}
procedure TkwIm3AttrIndexWriterWriteRange_ImplWriteRange(const aCtx: TtfwContext;
const aSelf: Im3AttrIndexWriter;
const aRange: Tl3Range);
begin
if (aSelf = nil) then
begin
Exit;
end;
aSelf.WriteRange(aRange);
end;//TkwIm3AttrIndexWriterWriteRange_ImplWriteRange
{$IfEnd} // NOT Defined(NoScripts)
{$If NOT Defined(NoScripts)}
function TkwIm3AttrIndexWriterWriteRange_ParamsTypes: PTypeInfoArray;
begin
Result := TtfwWord.OpenTypesToTypes([TtfwParamInfo_C('aSelf', TypeInfo(Im3AttrIndexWriter)), TtfwParamInfo_C('aRange', TtfwValueTypes.MakeBox('Tl3Range', Tl3Range_TypeInfo))]);
end;//TkwIm3AttrIndexWriterWriteRange_ParamsTypes
{$IfEnd} // NOT Defined(NoScripts)
{$If NOT Defined(NoScripts)}
procedure TkwIm3AttrIndexWriterWriteRange_DoIt(const aCtx: TtfwContext);
var l_aSelf: Im3AttrIndexWriter;
var l_aRange: IBoxFor_Tl3Range;
begin
try
l_aSelf := Im3AttrIndexWriter(aCtx.rEngine.Pop.AsIntf(TypeInfo(Im3AttrIndexWriter)));
except
on E: Exception do
begin
aCtx.GetParamError('aSelf: Im3AttrIndexWriter : ', E);
Exit;
end;//on E: Exception
end;//try..except
try
l_aRange := IBoxFor_Tl3Range(aCtx.rEngine.Pop.AsIntf(TypeInfo(IBoxFor_Tl3Range)));
except
on E: Exception do
begin
aCtx.GetParamError('aRange: IBoxFor_Tl3Range : ', E);
Exit;
end;//on E: Exception
end;//try..except
TkwIm3AttrIndexWriterWriteRange_ImplWriteRange(aCtx, l_aSelf, l_aRange.pBoxed^);
end;//TkwIm3AttrIndexWriterWriteRange_DoIt
{$IfEnd} // NOT Defined(NoScripts)
{$If NOT Defined(NoScripts)}
procedure TkwIm3AttrIndexWriterWriteOperation_ImplWriteOperation(const aCtx: TtfwContext;
const aSelf: Im3AttrIndexWriter;
anOperation: Tm3GroupOperation);
begin
if (aSelf = nil) then
begin
Exit;
end;
aSelf.WriteOperation(anOperation);
end;//TkwIm3AttrIndexWriterWriteOperation_ImplWriteOperation
{$IfEnd} // NOT Defined(NoScripts)
{$If NOT Defined(NoScripts)}
function TkwIm3AttrIndexWriterWriteOperation_ParamsTypes: PTypeInfoArray;
begin
Result := TtfwWord.OpenTypesToTypes([TtfwParamInfo_C('aSelf', TypeInfo(Im3AttrIndexWriter)), TtfwParamInfo_C('anOperation', TypeInfo(Tm3GroupOperation))]);
end;//TkwIm3AttrIndexWriterWriteOperation_ParamsTypes
{$IfEnd} // NOT Defined(NoScripts)
{$If NOT Defined(NoScripts)}
procedure TkwIm3AttrIndexWriterWriteOperation_DoIt(const aCtx: TtfwContext);
var l_aSelf: Im3AttrIndexWriter;
var l_anOperation: Tm3GroupOperation;
begin
try
l_aSelf := Im3AttrIndexWriter(aCtx.rEngine.Pop.AsIntf(TypeInfo(Im3AttrIndexWriter)));
except
on E: Exception do
begin
aCtx.GetParamError('aSelf: Im3AttrIndexWriter : ', E);
Exit;
end;//on E: Exception
end;//try..except
try
l_anOperation := Tm3GroupOperation(aCtx.rEngine.PopInt(TypeInfo(Tm3GroupOperation)));
except
on E: Exception do
begin
aCtx.GetParamError('anOperation: Tm3GroupOperation : ', E);
Exit;
end;//on E: Exception
end;//try..except
TkwIm3AttrIndexWriterWriteOperation_ImplWriteOperation(aCtx, l_aSelf, l_anOperation);
end;//TkwIm3AttrIndexWriterWriteOperation_DoIt
{$IfEnd} // NOT Defined(NoScripts)
{$If NOT Defined(NoScripts)}
procedure TkwIm3AttrIndexWriterStartBody_ImplStartBody(const aCtx: TtfwContext;
const aSelf: Im3AttrIndexWriter;
aCount: Integer);
begin
if (aSelf = nil) then
begin
Exit;
end;
aSelf.StartBody(aCount);
end;//TkwIm3AttrIndexWriterStartBody_ImplStartBody
{$IfEnd} // NOT Defined(NoScripts)
{$If NOT Defined(NoScripts)}
function TkwIm3AttrIndexWriterStartBody_ParamsTypes: PTypeInfoArray;
begin
Result := TtfwWord.OpenTypesToTypes([TtfwParamInfo_C('aSelf', TypeInfo(Im3AttrIndexWriter)), TtfwParamInfo_C('aCount', TtfwTypeInfo.MakeInteger)]);
end;//TkwIm3AttrIndexWriterStartBody_ParamsTypes
{$IfEnd} // NOT Defined(NoScripts)
{$If NOT Defined(NoScripts)}
procedure TkwIm3AttrIndexWriterStartBody_DoIt(const aCtx: TtfwContext);
var l_aSelf: Im3AttrIndexWriter;
var l_aCount: Integer;
begin
try
l_aSelf := Im3AttrIndexWriter(aCtx.rEngine.Pop.AsIntf(TypeInfo(Im3AttrIndexWriter)));
except
on E: Exception do
begin
aCtx.GetParamError('aSelf: Im3AttrIndexWriter : ', E);
Exit;
end;//on E: Exception
end;//try..except
try
l_aCount := aCtx.rEngine.PopInt(TypeInfo(Integer));
except
on E: Exception do
begin
aCtx.GetParamError('aCount: Integer : ', E);
Exit;
end;//on E: Exception
end;//try..except
TkwIm3AttrIndexWriterStartBody_ImplStartBody(aCtx, l_aSelf, l_aCount);
end;//TkwIm3AttrIndexWriterStartBody_DoIt
{$IfEnd} // NOT Defined(NoScripts)
{$If NOT Defined(NoScripts)}
procedure TkwIm3AttrIndexWriterFinishBody_ImplFinishBody(const aCtx: TtfwContext;
const aSelf: Im3AttrIndexWriter);
begin
if (aSelf = nil) then
begin
Exit;
end;
aSelf.FinishBody;
end;//TkwIm3AttrIndexWriterFinishBody_ImplFinishBody
{$IfEnd} // NOT Defined(NoScripts)
{$If NOT Defined(NoScripts)}
procedure TkwIm3AttrIndexWriterFinishBody_DoIt(const aCtx: TtfwContext);
var l_aSelf: Im3AttrIndexWriter;
begin
try
l_aSelf := Im3AttrIndexWriter(aCtx.rEngine.Pop.AsIntf(TypeInfo(Im3AttrIndexWriter)));
except
on E: Exception do
begin
aCtx.GetParamError('aSelf: Im3AttrIndexWriter : ', E);
Exit;
end;//on E: Exception
end;//try..except
TkwIm3AttrIndexWriterFinishBody_ImplFinishBody(aCtx, l_aSelf);
end;//TkwIm3AttrIndexWriterFinishBody_DoIt
{$IfEnd} // NOT Defined(NoScripts)
{$If NOT Defined(NoScripts)}
procedure TkwIm3AttrIndexWriterWriteBodyElement_ImplWriteBodyElement(const aCtx: TtfwContext;
const aSelf: Im3AttrIndexWriter;
aKey: Integer;
const aValue: Il3RangeEnumerable);
begin
if (aSelf = nil) then
begin
Exit;
end;
aSelf.WriteBodyElement(aKey, aValue);
end;//TkwIm3AttrIndexWriterWriteBodyElement_ImplWriteBodyElement
{$IfEnd} // NOT Defined(NoScripts)
{$If NOT Defined(NoScripts)}
function TkwIm3AttrIndexWriterWriteBodyElement_ParamsTypes: PTypeInfoArray;
begin
Result := TtfwWord.OpenTypesToTypes([TtfwParamInfo_C('aSelf', TypeInfo(Im3AttrIndexWriter)), TtfwParamInfo_C('aKey', TtfwTypeInfo.MakeInteger), TtfwParamInfo_C('aValue', TypeInfo(Il3RangeEnumerable))]);
end;//TkwIm3AttrIndexWriterWriteBodyElement_ParamsTypes
{$IfEnd} // NOT Defined(NoScripts)
{$If NOT Defined(NoScripts)}
procedure TkwIm3AttrIndexWriterWriteBodyElement_DoIt(const aCtx: TtfwContext);
var l_aSelf: Im3AttrIndexWriter;
var l_aKey: Integer;
var l_aValue: Il3RangeEnumerable;
begin
try
l_aSelf := Im3AttrIndexWriter(aCtx.rEngine.Pop.AsIntf(TypeInfo(Im3AttrIndexWriter)));
except
on E: Exception do
begin
aCtx.GetParamError('aSelf: Im3AttrIndexWriter : ', E);
Exit;
end;//on E: Exception
end;//try..except
try
l_aKey := aCtx.rEngine.PopInt(TypeInfo(Integer));
except
on E: Exception do
begin
aCtx.GetParamError('aKey: Integer : ', E);
Exit;
end;//on E: Exception
end;//try..except
try
l_aValue := Il3RangeEnumerable(aCtx.rEngine.Pop.AsIntf(TypeInfo(Il3RangeEnumerable)));
except
on E: Exception do
begin
aCtx.GetParamError('aValue: Il3RangeEnumerable : ', E);
Exit;
end;//on E: Exception
end;//try..except
TkwIm3AttrIndexWriterWriteBodyElement_ImplWriteBodyElement(aCtx, l_aSelf, l_aKey, l_aValue);
end;//TkwIm3AttrIndexWriterWriteBodyElement_DoIt
{$IfEnd} // NOT Defined(NoScripts)
{$If NOT Defined(NoScripts)}
function Im3AttrIndexWriterKeywordsPack_Im3AttrIndexWriter_SelfTypeInfo: TtfwValueTypes;
begin
Result := TtfwValueTypes.Make(TypeInfo(Im3AttrIndexWriter));
end;//Im3AttrIndexWriterKeywordsPack_Im3AttrIndexWriter_SelfTypeInfo
{$IfEnd} // NOT Defined(NoScripts)
function Tm3AttrIndexWriterSubStreamInfo_TypeInfo: PTypeInfo;
begin
Result := TypeInfo(IBoxFor_Tm3AttrIndexWriterSubStreamInfo);
end;//Tm3AttrIndexWriterSubStreamInfo_TypeInfo
{$If NOT Defined(NoScripts)}
function Tm3AttrIndexWriterSubStreamInfo_ToValue(const aSelf: Tm3AttrIndexWriterSubStreamInfo): TtfwStackValue;
begin
Result := TtfwStackValue_C(Tm3AttrIndexWriterSubStreamInfo_ToBox(aSelf), Tm3AttrIndexWriterSubStreamInfo_TypeInfo);
end;//Tm3AttrIndexWriterSubStreamInfo_ToValue
{$IfEnd} // NOT Defined(NoScripts)
{$If NOT Defined(NoScripts)}
function TtfwStackValue_C(const aSelf: Tm3AttrIndexWriterSubStreamInfo): TtfwStackValue;
begin
Result := TtfwStackValue_C(Tm3AttrIndexWriterSubStreamInfo_ToBox(aSelf), Tm3AttrIndexWriterSubStreamInfo_TypeInfo);
end;//TtfwStackValue_C
{$IfEnd} // NOT Defined(NoScripts)
{$If NOT Defined(NoScripts)}
function Tm3AttrIndexWriterSubStreamInfo_ToBox(const aSelf: Tm3AttrIndexWriterSubStreamInfo): Il3Box;
begin
Result := TBoxFor_Tm3AttrIndexWriterSubStreamInfo.Make(aSelf);
end;//Tm3AttrIndexWriterSubStreamInfo_ToBox
{$IfEnd} // NOT Defined(NoScripts)
{$If NOT Defined(NoScripts)}
function Tm3AttrIndexWriterSubStreamInfo_FromValue(const aValue: TtfwStackValue): Tm3AttrIndexWriterSubStreamInfo;
begin
System.FillChar(Result, SizeOf(Result), 0);
Result := IBoxFor_Tm3AttrIndexWriterSubStreamInfo(aValue.AsIntf(Tm3AttrIndexWriterSubStreamInfo_TypeInfo)).pBoxed^;
end;//Tm3AttrIndexWriterSubStreamInfo_FromValue
{$IfEnd} // NOT Defined(NoScripts)
function Tm3AttrIndexWriterBodyElement_TypeInfo: PTypeInfo;
begin
Result := TypeInfo(IBoxFor_Tm3AttrIndexWriterBodyElement);
end;//Tm3AttrIndexWriterBodyElement_TypeInfo
{$If NOT Defined(NoScripts)}
function Tm3AttrIndexWriterBodyElement_ToValue(const aSelf: Tm3AttrIndexWriterBodyElement): TtfwStackValue;
begin
Result := TtfwStackValue_C(Tm3AttrIndexWriterBodyElement_ToBox(aSelf), Tm3AttrIndexWriterBodyElement_TypeInfo);
end;//Tm3AttrIndexWriterBodyElement_ToValue
{$IfEnd} // NOT Defined(NoScripts)
{$If NOT Defined(NoScripts)}
function TtfwStackValue_C(const aSelf: Tm3AttrIndexWriterBodyElement): TtfwStackValue;
begin
Result := TtfwStackValue_C(Tm3AttrIndexWriterBodyElement_ToBox(aSelf), Tm3AttrIndexWriterBodyElement_TypeInfo);
end;//TtfwStackValue_C
{$IfEnd} // NOT Defined(NoScripts)
{$If NOT Defined(NoScripts)}
function Tm3AttrIndexWriterBodyElement_ToBox(const aSelf: Tm3AttrIndexWriterBodyElement): Il3Box;
begin
Result := TBoxFor_Tm3AttrIndexWriterBodyElement.Make(aSelf);
end;//Tm3AttrIndexWriterBodyElement_ToBox
{$IfEnd} // NOT Defined(NoScripts)
{$If NOT Defined(NoScripts)}
function Tm3AttrIndexWriterBodyElement_FromValue(const aValue: TtfwStackValue): Tm3AttrIndexWriterBodyElement;
begin
System.FillChar(Result, SizeOf(Result), 0);
Result := IBoxFor_Tm3AttrIndexWriterBodyElement(aValue.AsIntf(Tm3AttrIndexWriterBodyElement_TypeInfo)).pBoxed^;
end;//Tm3AttrIndexWriterBodyElement_FromValue
{$IfEnd} // NOT Defined(NoScripts)
function Tm3AttrIndexWriterHeader_TypeInfo: PTypeInfo;
begin
Result := TypeInfo(IBoxFor_Tm3AttrIndexWriterHeader);
end;//Tm3AttrIndexWriterHeader_TypeInfo
{$If NOT Defined(NoScripts)}
function Tm3AttrIndexWriterHeader_ToValue(const aSelf: Tm3AttrIndexWriterHeader): TtfwStackValue;
begin
Result := TtfwStackValue_C(Tm3AttrIndexWriterHeader_ToBox(aSelf), Tm3AttrIndexWriterHeader_TypeInfo);
end;//Tm3AttrIndexWriterHeader_ToValue
{$IfEnd} // NOT Defined(NoScripts)
{$If NOT Defined(NoScripts)}
function TtfwStackValue_C(const aSelf: Tm3AttrIndexWriterHeader): TtfwStackValue;
begin
Result := TtfwStackValue_C(Tm3AttrIndexWriterHeader_ToBox(aSelf), Tm3AttrIndexWriterHeader_TypeInfo);
end;//TtfwStackValue_C
{$IfEnd} // NOT Defined(NoScripts)
{$If NOT Defined(NoScripts)}
function Tm3AttrIndexWriterHeader_ToBox(const aSelf: Tm3AttrIndexWriterHeader): Il3Box;
begin
Result := TBoxFor_Tm3AttrIndexWriterHeader.Make(aSelf);
end;//Tm3AttrIndexWriterHeader_ToBox
{$IfEnd} // NOT Defined(NoScripts)
{$If NOT Defined(NoScripts)}
function Tm3AttrIndexWriterHeader_FromValue(const aValue: TtfwStackValue): Tm3AttrIndexWriterHeader;
begin
Finalize(Result);
System.FillChar(Result, SizeOf(Result), 0);
Result := IBoxFor_Tm3AttrIndexWriterHeader(aValue.AsIntf(Tm3AttrIndexWriterHeader_TypeInfo)).pBoxed^;
end;//Tm3AttrIndexWriterHeader_FromValue
{$IfEnd} // NOT Defined(NoScripts)
constructor Tm3PlainAttrIndexDumperElementEnumerator.Create(aCount: Integer;
const aFileName: TFileName;
const aBody: Tm3AttrIndexWriterSubStreamInfo);
//#UC START# *69AF4C8F003A_69AE79CA0044_var*
//#UC END# *69AF4C8F003A_69AE79CA0044_var*
begin
//#UC START# *69AF4C8F003A_69AE79CA0044_impl*
inherited Create;
f_Count := aCount;
f_Index := -1;
f_FileName := aFileName;
f_Body := aBody;
//#UC END# *69AF4C8F003A_69AE79CA0044_impl*
end;//Tm3PlainAttrIndexDumperElementEnumerator.Create
class function Tm3PlainAttrIndexDumperElementEnumerator.Make(aCount: Integer;
const aFileName: TFileName;
const aBody: Tm3AttrIndexWriterSubStreamInfo): Im3AttrIndexElementEnumerator;
var
l_Inst : Tm3PlainAttrIndexDumperElementEnumerator;
begin
l_Inst := Create(aCount, aFileName, aBody);
try
Result := l_Inst;
finally
l_Inst.Free;
end;//try..finally
end;//Tm3PlainAttrIndexDumperElementEnumerator.Make
{$If NOT Defined(l3NoSRT)}
function Tm3PlainAttrIndexDumperElementEnumerator.SetRefTo(var thePlace: Tm3PlainAttrIndexDumperElementEnumerator): Boolean;
begin
if (thePlace = Self) then
Result := false
else
begin
Result := true;
thePlace.Free;
thePlace := Self.Use;
end;//thePlace = Self
end;//Tm3PlainAttrIndexDumperElementEnumerator.SetRefTo
{$IfEnd} // NOT Defined(l3NoSRT)
function Tm3PlainAttrIndexDumperElementEnumerator.MoveNext: Boolean;
{* Перемещается на следующий элемент контейнера.
Возвращает true если элемент валидный. }
//#UC START# *5ACB6780016E_69AE79CA0044_var*
//#UC END# *5ACB6780016E_69AE79CA0044_var*
begin
//#UC START# *5ACB6780016E_69AE79CA0044_impl*
Result := CanMoveNext;
if Result then
begin
Dec(f_Count);
Inc(f_Index);
f_Current := nil;
// - инициализироваться он будет в pCurrent
end;//Result
//#UC END# *5ACB6780016E_69AE79CA0044_impl*
end;//Tm3PlainAttrIndexDumperElementEnumerator.MoveNext
function Tm3PlainAttrIndexDumperElementEnumerator.pCurrent: Im3AttrIndexElementEnumerator_PCurrentItemType;
{* Указатель на текущий элемент. Он "закеширован" }
//#UC START# *5C4EFC140038_69AE79CA0044_var*
var
l_Stream : Tl3Stream;
l_Element : Tm3AttrIndexWriterBodyElement;
//#UC END# *5C4EFC140038_69AE79CA0044_var*
begin
//#UC START# *5C4EFC140038_69AE79CA0044_impl*
if (f_Current = nil) then
begin
if (f_Body.rPos <= 0)
OR (f_Body.rSize <= 0) then
Assert(false);
if (f_Stream = nil) then
begin
f_Stream := Tl3NamedFileStream.Create(f_FileName, l3_fmRead);
f_Stream.Seek(f_Body.rPos, soBeginning);
l_Stream := Tl3SubStream.Create(f_Stream, f_Body.rPos, f_Body.rSize);
try
l_Stream.SetRefTo(f_Stream);
finally
FreeAndNil(l_Stream);
end;//try..finally
end;//f_Stream = nil
f_Stream.Seek(f_Index * SizeOf(l_Element), soBeginning);
f_Stream.ReadBuffer(l_Element, SizeOf(l_Element));
f_Current := Tm3PlainAttrIndexDumperElement.Make(l_Element, Self.f_FileName);
end;//f_Current = nil
Result := @f_Current;
//#UC END# *5C4EFC140038_69AE79CA0044_impl*
end;//Tm3PlainAttrIndexDumperElementEnumerator.pCurrent
function Tm3PlainAttrIndexDumperElementEnumerator.CanMoveNext: Boolean;
{* Определяет - можно ли переместиться на следующий элемент контейнера. }
//#UC START# *5E60D4B30164_69AE79CA0044_var*
//#UC END# *5E60D4B30164_69AE79CA0044_var*
begin
//#UC START# *5E60D4B30164_69AE79CA0044_impl*
Result := f_Count > 0;
//#UC END# *5E60D4B30164_69AE79CA0044_impl*
end;//Tm3PlainAttrIndexDumperElementEnumerator.CanMoveNext
function Tm3PlainAttrIndexDumperElementEnumerator.Get_Current: Im3AttrIndexElement;
//#UC START# *6739C0470374_69AE79CA0044get_var*
//#UC END# *6739C0470374_69AE79CA0044get_var*
begin
//#UC START# *6739C0470374_69AE79CA0044get_impl*
Result := Self.pCurrent^;
//#UC END# *6739C0470374_69AE79CA0044get_impl*
end;//Tm3PlainAttrIndexDumperElementEnumerator.Get_Current
procedure Tm3PlainAttrIndexDumperElementEnumerator.Cleanup;
{* Функция очистки полей объекта. }
//#UC START# *479731C50290_69AE79CA0044_var*
//#UC END# *479731C50290_69AE79CA0044_var*
begin
//#UC START# *479731C50290_69AE79CA0044_impl*
FreeAndNil(f_Stream);
inherited;
//#UC END# *479731C50290_69AE79CA0044_impl*
end;//Tm3PlainAttrIndexDumperElementEnumerator.Cleanup
procedure Tm3PlainAttrIndexDumperElementEnumerator.ClearFields;
begin
f_Current := nil;
inherited;
end;//Tm3PlainAttrIndexDumperElementEnumerator.ClearFields
constructor Tm3PlainAttrIndexDumperElement.Create(const anElement: Tm3AttrIndexWriterBodyElement;
const aFileName: TFileName);
//#UC START# *69AF4D9C03E5_69AE7A520320_var*
//#UC END# *69AF4D9C03E5_69AE7A520320_var*
begin
//#UC START# *69AF4D9C03E5_69AE7A520320_impl*
inherited Create;
f_Element := anElement;
f_FileName := aFileName;
//#UC END# *69AF4D9C03E5_69AE7A520320_impl*
end;//Tm3PlainAttrIndexDumperElement.Create
class function Tm3PlainAttrIndexDumperElement.Make(const anElement: Tm3AttrIndexWriterBodyElement;
const aFileName: TFileName): Im3AttrIndexElement;
var
l_Inst : Tm3PlainAttrIndexDumperElement;
begin
l_Inst := Create(anElement, aFileName);
try
Result := l_Inst;
finally
l_Inst.Free;
end;//try..finally
end;//Tm3PlainAttrIndexDumperElement.Make
{$If NOT Defined(l3NoSRT)}
function Tm3PlainAttrIndexDumperElement.SetRefTo(var thePlace: Tm3PlainAttrIndexDumperElement): Boolean;
begin
if (thePlace = Self) then
Result := false
else
begin
Result := true;
thePlace.Free;
thePlace := Self.Use;
end;//thePlace = Self
end;//Tm3PlainAttrIndexDumperElement.SetRefTo
{$IfEnd} // NOT Defined(l3NoSRT)
function Tm3PlainAttrIndexDumperElement.Get_ID: Integer;
//#UC START# *666AD8510295_69AE7A520320get_var*
//#UC END# *666AD8510295_69AE7A520320get_var*
begin
//#UC START# *666AD8510295_69AE7A520320get_impl*
Result := f_Element.rKey;
//#UC END# *666AD8510295_69AE7A520320get_impl*
end;//Tm3PlainAttrIndexDumperElement.Get_ID
function Tm3PlainAttrIndexDumperElement.Get_Values: Il3RangeEnumerable;
//#UC START# *666ADD3000B4_69AE7A520320get_var*
var
l_Stream : Tl3Stream;
l_SubStream : Tl3Stream;
l_Size : Int64;
//#UC END# *666ADD3000B4_69AE7A520320get_var*
begin
//#UC START# *666ADD3000B4_69AE7A520320get_impl*
if (f_Values = nil) then
begin
Case f_Element.rType of
m3_etNone:
f_Values := Tm3RangedDocumentsList.MakeEnum;
m3_etSingle:
f_Values := Tm3RangedDocumentsList.MakeEnum(f_Element.rValue);
m3_etPair:
f_Values := Tm3RangedDocumentsList.MakeEnum(T64to32(f_Element.rValue));
m3_et4:
f_Values := Tm3RangedDocumentsList.MakeEnum(T64toSmallInts(f_Element.rValue));
m3_et8:
f_Values := Tm3RangedDocumentsList.MakeEnum(T64toBytes(f_Element.rValue));
m3_etRange:
f_Values := Tm3RangedDocumentsList.MakeEnum(Tm3IDRange(f_Element.rValue));
m3_etMultiply
, m3_etLZO
, m3_etZLib:
begin
Assert(f_Element.rValue > 0);
l_Stream := Tl3NamedFileStream.Create(f_FileName, l3_fmRead);
try
l_Stream.Seek(f_Element.rValue, soBeginning);
l_Stream.ReadBuffer(l_Size, SizeOf(l_Size));
Assert(l_Size > 0);
l_SubStream := Tl3SubStream.Create(l_Stream, f_Element.rValue + SizeOf(l_Size), l_Size);
try
FreeAndNil(l_Stream);
// - отпускаем, дабы не читать не из того потока
Case f_Element.rType of
m3_etLZO:
begin
l_Stream := Tm3LZOInflateStreamNew.Create(l_SubStream);
try
f_Values := Il3RangeEnumerable_CreateFromStream(l_Stream);
finally
FreeAndNil(l_Stream);
end;//try..finally
end;//m3_etLZO
m3_etZLib:
begin
l_Stream := Tl3ZLibDecompressStream.Create(l_SubStream);
try
f_Values := Il3RangeEnumerable_CreateFromStream(l_Stream);
finally
FreeAndNil(l_Stream);
end;//try..finally
end;//m3_etZLib
else
f_Values := Il3RangeEnumerable_CreateFromStream(l_SubStream);
end;//Case f_Element.rType
finally
FreeAndNil(l_SubStream);
end;//try..finally
finally
FreeAndNil(l_Stream);
end;//try..finally
end;//m3_etMultiply
else
l3NI;
end;//Case f_Element.rType
end;//f_Values = nil
Result := f_Values;
//#UC END# *666ADD3000B4_69AE7A520320get_impl*
end;//Tm3PlainAttrIndexDumperElement.Get_Values
procedure Tm3PlainAttrIndexDumperElement.Cleanup;
{* Функция очистки полей объекта. }
//#UC START# *479731C50290_69AE7A520320_var*
//#UC END# *479731C50290_69AE7A520320_var*
begin
//#UC START# *479731C50290_69AE7A520320_impl*
inherited;
//#UC END# *479731C50290_69AE7A520320_impl*
end;//Tm3PlainAttrIndexDumperElement.Cleanup
procedure Tm3PlainAttrIndexDumperElement.ClearFields;
begin
Finalize(f_Element);
f_Values := nil;
inherited;
end;//Tm3PlainAttrIndexDumperElement.ClearFields
constructor Tm3PlainAttrIndexDumper.Create(const aFileName: TFileName;
aStream: Tl3Stream = nil);
//#UC START# *69AE76AD032F_69AE74DB018A_var*
var
l_GUID : AnsiString;
l_HeaderPos : Int64;
//#UC END# *69AE76AD032F_69AE74DB018A_var*
begin
//#UC START# *69AE76AD032F_69AE74DB018A_impl*
//f_LastSeqIndex := -1;
//f_LastSeqKey := Low(f_LastSeqKey);
inherited Create;
f_SearchMode := m3_smRandom;
f_FileName := aFileName;
if (aStream = nil) then
f_Stream := Tl3NamedFileStream.Create(f_FileName, l3_fmRead)
else
begin
aStream.SetRefTo(f_Stream);
f_Stream.Seek(0, soBeginning);
end;//aStream = nil
l_GUID := m2COMCLSIDFromStream(f_Stream);
if (l_GUID = GUIDToString(c_m3AttrIndexWriterGUID)) then
begin
f_Stream.Seek(Length(l_GUID), soBeginning);
f_Stream.ReadBuffer(l_HeaderPos, SizeOf(l_HeaderPos));
f_Stream.Seek(l_HeaderPos, soBeginning);
f_Stream.ReadBuffer(f_Header, SizeOf(f_Header));
Em3Exception.Check(f_Header.rZeroStart = 0, 'f_Header.rZeroStart = 0');
Em3Exception.Check(f_Header.rZeroEnd = 0, 'f_Header.rZeroEnd = 0');
Em3Exception.Check(f_Header.rVersion > 0, 'f_Header.rVersion > 0');
Em3Exception.Check(f_Header.rVersion <= cOurVersion, 'f_Header.rVersion <= cOurVersion');
Em3Exception.Check(f_Header.rSignature = cSignature, 'f_Header.rSignature = cSignature');
Em3Exception.Check(f_Header.rTim = 'tim', 'f_Header.rTim = ''tim''');
Em3Exception.Check(f_Header.rHeaderStart = l_HeaderPos, 'f_Header.rHeaderStart = l_HeaderPos');
Em3Exception.Check(f_Header.rHeaderEnd = l_HeaderPos + SizeOf(f_Header), 'f_Header.rHeaderEnd = l_HeaderPos + SizeOf(f_Header)');
Em3Exception.Check(f_Header.rBod = 'bod', 'f_Header.rBod = ''bod''');
Em3Exception.Check(f_Header.rMod = 'mod', 'f_Header.rMod = ''mod''');
Em3Exception.Check(f_Header.rVers = 'vers', 'f_Header.rVers = ''vers''');
f_Sequential := false;
if (f_Header.rVersion >= cSequentialVersion) then
begin
f_Stream.Seek(f_Header.rBody.rPos - SizeOf(f_Sequential), soBeginning);
f_Stream.ReadBuffer(f_Sequential, SizeOf(f_Sequential));
end;//f_Header.rVersion >= cSequentialVersion
end//l_GUID = GUIDToString(c_m3AttrIndexWriterGUID)
else
begin
raise Em3Exception.Create(l3ForceUTF8FPC('Индекс не нового формата: ' + aFileName + ' GUID = ' + l_GUID));
end;//l_GUID = GUIDToString(c_m3AttrIndexWriterGUID)
//#UC END# *69AE76AD032F_69AE74DB018A_impl*
end;//Tm3PlainAttrIndexDumper.Create
class function Tm3PlainAttrIndexDumper.Make(const aFileName: TFileName;
aStream: Tl3Stream = nil): Im3AttrIndexDumper;
var
l_Inst : Tm3PlainAttrIndexDumper;
begin
l_Inst := Create(aFileName, aStream);
try
Result := l_Inst;
finally
l_Inst.Free;
end;//try..finally
end;//Tm3PlainAttrIndexDumper.Make
class function Tm3PlainAttrIndexDumper.TryMake(const aFileName: TFileName;
out theDumper: Im3AttrIndexDumper): Boolean;
//#UC START# *69AEDDE802BD_69AE74DB018A_var*
var
l_Stream : Tl3Stream;
l_GUID : AnsiString;
//#UC END# *69AEDDE802BD_69AE74DB018A_var*
begin
//#UC START# *69AEDDE802BD_69AE74DB018A_impl*
Result := false;
l_Stream := Tl3NamedFileStream.Create(aFileName, l3_fmRead);
try
l_GUID := m2COMCLSIDFromStream(l_Stream);
if (l_GUID = GUIDToString(c_m3AttrIndexWriterGUID)) then
begin
Result := true;
//FreeAndNil(l_Stream);
// - отпускаем поток здесь, чтобы не мешать экземпляру Dumper'а
theDumper := Self.Make(aFileName, l_Stream);
end;//l_GUID = GUIDToString(c_m3AttrIndexWriterGUID)
finally
FreeAndNil(l_Stream);
end;//try..finally
//#UC END# *69AEDDE802BD_69AE74DB018A_impl*
end;//Tm3PlainAttrIndexDumper.TryMake
{$If NOT Defined(l3NoSRT)}
function Tm3PlainAttrIndexDumper.SetRefTo(var thePlace: Tm3PlainAttrIndexDumper): Boolean;
begin
if (thePlace = Self) then
Result := false
else
begin
Result := true;
thePlace.Free;
thePlace := Self.Use;
end;//thePlace = Self
end;//Tm3PlainAttrIndexDumper.SetRefTo
{$IfEnd} // NOT Defined(l3NoSRT)
function Tm3PlainAttrIndexDumper.pm_GetFirst: Il3RangeEnumerable;
//#UC START# *47D8233603DD_69AE74DB018Aget_var*
//#UC END# *47D8233603DD_69AE74DB018Aget_var*
begin
//#UC START# *47D8233603DD_69AE74DB018Aget_impl*
Result := nil;
l3NI;
//#UC END# *47D8233603DD_69AE74DB018Aget_impl*
end;//Tm3PlainAttrIndexDumper.pm_GetFirst
function Tm3PlainAttrIndexDumper.pm_GetLast: Il3RangeEnumerable;
//#UC START# *47D823570315_69AE74DB018Aget_var*
//#UC END# *47D823570315_69AE74DB018Aget_var*
begin
//#UC START# *47D823570315_69AE74DB018Aget_impl*
Result := nil;
l3NI;
//#UC END# *47D823570315_69AE74DB018Aget_impl*
end;//Tm3PlainAttrIndexDumper.pm_GetLast
function Tm3PlainAttrIndexDumper.pm_GetCount: Integer;
//#UC START# *4BB08B8902F2_69AE74DB018Aget_var*
//#UC END# *4BB08B8902F2_69AE74DB018Aget_var*
begin
//#UC START# *4BB08B8902F2_69AE74DB018Aget_impl*
Result := f_Header.rElementsCount;
//#UC END# *4BB08B8902F2_69AE74DB018Aget_impl*
end;//Tm3PlainAttrIndexDumper.pm_GetCount
function Tm3PlainAttrIndexDumper.GetEnumerator: Im3AttrIndexElementEnumerator;
{* Получает Enumerator для перебора элементов "контейнера".
Вся эта конструкция совместима с "синтаксическим сахаром" вида:
for Item in Container do Process(Item);
Который поддерживается в "новых" Delphi.
См. http://mdp.garant.ru/pages/viewpage.action?pageId=152961307 }
//#UC START# *5AB8C6B0003A_69AE74DB018A_var*
//#UC END# *5AB8C6B0003A_69AE74DB018A_var*
begin
//#UC START# *5AB8C6B0003A_69AE74DB018A_impl*
Result := Tm3PlainAttrIndexDumperElementEnumerator.Make(f_Header.rElementsCount, f_FileName, f_Header.rBody);
//#UC END# *5AB8C6B0003A_69AE74DB018A_impl*
end;//Tm3PlainAttrIndexDumper.GetEnumerator
function Tm3PlainAttrIndexDumper.ModifiedDocuments: Il3RangeEnumerable;
//#UC START# *5B2B66730195_69AE74DB018A_var*
var
l_Stream : Tl3Stream;
//#UC END# *5B2B66730195_69AE74DB018A_var*
begin
//#UC START# *5B2B66730195_69AE74DB018A_impl*
if (f_Modified = nil) then
begin
if (f_Header.rModified.rPos > 0)
AND (f_Header.rModified.rSize > 0) then
begin
f_Stream.Seek(f_Header.rModified.rPos, soBeginning);
l_Stream := Tl3SubStream.Create(f_Stream, f_Header.rModified.rPos, f_Header.rModified.rSize);
try
f_Modified := Il3RangeEnumerable_CreateFromStream(l_Stream);
finally
FreeAndNil(l_Stream);
end;//try..finally
end//f_Header.rModified.rPos > 0
else
f_Modified := Tm3RangedDocumentsList.MakeEnum;
end;//f_Modified = nil
Result := f_Modified;
//#UC END# *5B2B66730195_69AE74DB018A_impl*
end;//Tm3PlainAttrIndexDumper.ModifiedDocuments
function Tm3PlainAttrIndexDumper.IndexedVersions: Im3IndexedVersions;
//#UC START# *5B2E194003AE_69AE74DB018A_var*
var
l_Stream : Tl3Stream;
//#UC END# *5B2E194003AE_69AE74DB018A_var*
begin
//#UC START# *5B2E194003AE_69AE74DB018A_impl*
if (f_Versions = nil) then
begin
f_Versions := Tl3IntegerToIntegerMap.Create;
if (f_Header.rVersions.rPos > 0)
AND (f_Header.rVersions.rSize > 0) then
begin
f_Stream.Seek(f_Header.rVersions.rPos, soBeginning);
l_Stream := Tl3SubStream.Create(f_Stream, f_Header.rVersions.rPos, f_Header.rVersions.rSize);
try
m3LoadVersionsFromStream(f_Versions, l_Stream);
finally
FreeAndNil(l_Stream);
end;//try..finally
end;//f_Header.rVersions.rPos > 0
end;//f_Versions = nil
Result := f_Versions.AsEnumerable;
//#UC END# *5B2E194003AE_69AE74DB018A_impl*
end;//Tm3PlainAttrIndexDumper.IndexedVersions
function Tm3PlainAttrIndexDumper.Get_Range: Tm3IDRange;
//#UC START# *5DA9C0270207_69AE74DB018Aget_var*
//#UC END# *5DA9C0270207_69AE74DB018Aget_var*
begin
//#UC START# *5DA9C0270207_69AE74DB018Aget_impl*
Result := f_Header.rRange;
//#UC END# *5DA9C0270207_69AE74DB018Aget_impl*
end;//Tm3PlainAttrIndexDumper.Get_Range
function Tm3PlainAttrIndexDumper.ValuesByKey(aKey: Integer): Il3RangeEnumerable;
//#UC START# *66B4B9740318_69AE74DB018A_var*
var
l_FileStream : Tl3Stream;
l_Element : Tm3AttrIndexWriterBodyElement;
procedure ElementToResult;
var
l_E : Im3AttrIndexElement;
l_Size : Int64;
l_Stream : Tl3Stream;
l_CStream : Tl3Stream;
begin
Case l_Element.rType of
m3_etNone:
Result := Tm3RangedDocumentsList.MakeEnum;
m3_etSingle:
Result := Tm3RangedDocumentsList.MakeEnum(l_Element.rValue);
m3_etPair:
Result := Tm3RangedDocumentsList.MakeEnum(T64to32(l_Element.rValue));
m3_et4:
Result := Tm3RangedDocumentsList.MakeEnum(T64toSmallInts(l_Element.rValue));
m3_et8:
Result := Tm3RangedDocumentsList.MakeEnum(T64toBytes(l_Element.rValue));
m3_etRange:
Result := Tm3RangedDocumentsList.MakeEnum(Tm3IDRange(l_Element.rValue));
m3_etMultiply
, m3_etLZO
, m3_etZLib:
begin
// - here we heed to read from l_FileStream
Assert(l_Element.rValue > 0);
l_FileStream.Seek(l_Element.rValue, soBeginning);
l_FileStream.ReadBuffer(l_Size, SizeOf(l_Size));
Assert(l_Size > 0);
l_Stream := Tl3SubStream.Create(l_FileStream, l_Element.rValue + SizeOf(l_Size), l_Size);
try
Case l_Element.rType of
m3_etLZO:
begin
l_CStream := Tm3LZOInflateStreamNew.Create(l_Stream);
try
Result := Il3RangeEnumerable_CreateFromStream(l_CStream);
finally
FreeAndNil(l_CStream);
end;//try..finally
end;//m3_etZLib
m3_etZLib:
begin
l_CStream := Tl3ZLibDecompressStream.Create(l_Stream);
try
Result := Il3RangeEnumerable_CreateFromStream(l_CStream);
finally
FreeAndNil(l_CStream);
end;//try..finally
end;//m3_etZLib
else
Result := Il3RangeEnumerable_CreateFromStream(l_Stream);
end;//Case l_Element.rType
finally
FreeAndNil(l_Stream);
end;//try..finally
(* l_E := Tm3PlainAttrIndexDumperElement.Make(l_Element, Self.f_FileName);
Result := l_E.Values;*)
end;//m3_etMultiply
else
begin
// - here we heed to read from l_FileStream
l_E := Tm3PlainAttrIndexDumperElement.Make(l_Element, Self.f_FileName);
Result := l_E.Values;
end;//else
end;//Case l_Element.rType
end;//ElementToResult
var
//l_It : Im3AttrIndexElementEnumerator;
l_ID : Integer;
L : Integer;
H : Integer;
C : Tl3CompareResult;
i : Integer;
l_Stream : Tl3Stream;
l_KeyPos : Int64;
//#UC END# *66B4B9740318_69AE74DB018A_var*
begin
//#UC START# *66B4B9740318_69AE74DB018A_impl*
Result := nil;
if (aKey < f_Header.rMinKeyID) then
Exit;
if (aKey > f_Header.rMaxKeyID) then
Exit;
if (f_SearchMode = m3_smSeq) then
begin
if (f_EnumeratorForSeq = nil) then
begin
f_EnumeratorForSeq := Self.GetEnumerator;
Assert(f_EnumeratorForSeq <> nil);
if not f_EnumeratorForSeq.MoveNext then
begin
f_EnumeratorForSeq := nil;
Exit;
// - ничего не нашли
// жмём плечами и отваливаем
end;//not f_EnumeratorForSeq.MoveNext
end;//f_EnumeratorForSeq = nil
while true do
// - Move был раньше
//while f_EnumeratorForSeq.MoveNext do
begin
l_ID := f_EnumeratorForSeq.pCurrent.ID;
if (l_ID = aKey) then
begin
Result := f_EnumeratorForSeq.pCurrent.Values;
Exit;
end//l_ID = aKey
else
if (l_ID < aKey) then
// - ключ правее итератора
begin
// Будем искать дальше
if not f_EnumeratorForSeq.MoveNext then
begin
f_EnumeratorForSeq := nil;
Exit;
// - ничего не нашли
// жмём плечами и отваливаем
end;//not f_EnumeratorForSeq.MoveNext
end//l_ID > aKey
else
if (l_ID > aKey) then
// - ключ левее итератора
begin
// ЕСТЬ ВЕРСИЯ, что это ОТСУТСТВУЮЩИЙ КЛЮЧ
Result := nil;
// - явно обозачаем "пусто"
Exit;
// - отваливаем
Assert(false, l3ForceUTF8FPC('Не должны сюда попадать'));
f_EnumeratorForSeq := nil;
// - отпускаем предыдущий
f_EnumeratorForSeq := Self.GetEnumerator;
// - получаем новый
Assert(f_EnumeratorForSeq <> nil);
if not f_EnumeratorForSeq.MoveNext then
begin
f_EnumeratorForSeq := nil;
Exit;
// - ничего не нашли
// жмём плечами и отваливаем
end;//not f_EnumeratorForSeq.MoveNext
continue;
raise Em3Exception.Create(l3ForceUTF8FPC('Похоже на рандомный доступ:')
+ ' aKey = '
+ IntToStr(aKey)
+ ' ID = '
+ IntToStr(l_ID)
);
// - ругаемся
Exit;
// - отваливаем
end;//l_ID > aKey
end;//while f_EnumeratorForSeq.MoveNext
Exit;
// - по-любому больше ничего делать не нужно
end;//f_SearchMode = m3_smSeq
if (aKey = f_Header.rMinKeyID)
OR (aKey = f_Header.rMinKeyID + 1)
OR (aKey < 20)
OR (f_Header.rElementsCount < 50)
OR f_Sequential
then
//if false then
begin
// - линейный поиск
l_FileStream := Tl3NamedFileStream.Create(f_FileName, l3_fmRead);
try
l_FileStream.Seek(f_Header.rBody.rPos, soBeginning);
l_Stream := Tl3SubStream.Create(l_FileStream, f_Header.rBody.rPos, f_Header.rBody.rSize);
try
if f_Sequential then
begin
l_KeyPos := (aKey - f_Header.rMinKeyID);
l_Stream.Seek(l_KeyPos * SizeOf(l_Element), soBeginning);
l_Stream.ReadBuffer(l_Element, SizeOf(l_Element));
Em3Exception.Check(l_Element.rKey = aKey, 'l_Element.rKey = aKey');
ElementToResult;
Exit;
end//f_Sequential
else
begin
i := f_Header.rElementsCount;
while (i > 0) do
begin
//i := (L + H) shr 1;
//l_Stream.Seek(i * SizeOf(l_Element), soBeginning);
l_Stream.ReadBuffer(l_Element, SizeOf(l_Element));
C := l3CompareInt64(l_Element.rKey, aKey);
if (C = 0) then
begin
FreeAndNil(l_Stream);
ElementToResult;
Exit;
end//C = 0
else
if (C > 0) then
// - дальше можно не искать
Exit;
end;//i > 0
end;//f_Sequential
finally
FreeAndNil(l_Stream);
end;//try..finally
finally
FreeAndNil(l_FileStream);
end;//try..finally
(* l_It := Self.GetEnumerator;
// - пока будем искать последовательно, а потом переделаем на поиск делением пополам
if (l_It <> nil) then
begin
while l_It.MoveNext do
begin
l_ID := l_It.pCurrent.ID;
if (l_ID = aKey) then
begin
Result := l_It.pCurrent.Values;
Exit;
end//l_ID = aKey
else
if (l_ID > aKey) then
// - дальше можно не искать
Exit;
end;//while l_It.MoveNext
end;//l_It <> nil*)
end//линейный поиск
else
//if false then
begin
// - поиск делением пополам
C := 0;
L := 0;
H := Pred(f_Header.rElementsCount);
l_FileStream := Tl3NamedFileStream.Create(f_FileName, l3_fmRead);
try
l_FileStream.Seek(f_Header.rBody.rPos, soBeginning);
l_Stream := Tl3SubStream.Create(l_FileStream, f_Header.rBody.rPos, f_Header.rBody.rSize);
try
while (L <= H) do
begin
i := (L + H) shr 1;
l_Stream.Seek(i * SizeOf(l_Element), soBeginning);
l_Stream.ReadBuffer(l_Element, SizeOf(l_Element));
C := l3CompareInt64(l_Element.rKey, aKey);
if (C < 0) then
L := Succ(i)
else
begin
if (C = 0) then
begin
H := Pred(i);
FreeAndNil(l_Stream);
ElementToResult;
Exit;
end//C = 0
else
H := Pred(i);
end;//C < 0
end;//while (L..
finally
FreeAndNil(l_Stream);
end;//try..finally
finally
FreeAndNil(l_FileStream);
end;//try..finally
end;//поиск пополам
//#UC END# *66B4B9740318_69AE74DB018A_impl*
end;//Tm3PlainAttrIndexDumper.ValuesByKey
function Tm3PlainAttrIndexDumper.TimeStamp: TDateTime;
//#UC START# *66C46E6801D3_69AE74DB018A_var*
//#UC END# *66C46E6801D3_69AE74DB018A_var*
begin
//#UC START# *66C46E6801D3_69AE74DB018A_impl*
Result := 0;
System.Move(f_Header.rTimeStamp, Result, SizeOf(f_Header.rTimeStamp));
//#UC END# *66C46E6801D3_69AE74DB018A_impl*
end;//Tm3PlainAttrIndexDumper.TimeStamp
function Tm3PlainAttrIndexDumper.Get_MaxKeyID: Integer;
//#UC START# *671D18210090_69AE74DB018Aget_var*
//#UC END# *671D18210090_69AE74DB018Aget_var*
begin
//#UC START# *671D18210090_69AE74DB018Aget_impl*
Result := f_Header.rMaxKeyID;
//#UC END# *671D18210090_69AE74DB018Aget_impl*
end;//Tm3PlainAttrIndexDumper.Get_MaxKeyID
function Tm3PlainAttrIndexDumper.Get_Operation: Tm3GroupOperation;
//#UC START# *68E135160346_69AE74DB018Aget_var*
//#UC END# *68E135160346_69AE74DB018Aget_var*
begin
//#UC START# *68E135160346_69AE74DB018Aget_impl*
Result := f_Header.rOperation;
//#UC END# *68E135160346_69AE74DB018Aget_impl*
end;//Tm3PlainAttrIndexDumper.Get_Operation
function Tm3PlainAttrIndexDumper.Get_MinKeyID: Integer;
//#UC START# *69B14AAE0155_69AE74DB018Aget_var*
//#UC END# *69B14AAE0155_69AE74DB018Aget_var*
begin
//#UC START# *69B14AAE0155_69AE74DB018Aget_impl*
Result := f_Header.rMinKeyID;
//#UC END# *69B14AAE0155_69AE74DB018Aget_impl*
end;//Tm3PlainAttrIndexDumper.Get_MinKeyID
procedure Tm3PlainAttrIndexDumper.Set_SearchMode(aValue: Tm3SearchMode);
//#UC START# *69BBB8A101BA_69AE74DB018Aset_var*
//#UC END# *69BBB8A101BA_69AE74DB018Aset_var*
begin
//#UC START# *69BBB8A101BA_69AE74DB018Aset_impl*
if (aValue = m3_smRandom) then
f_EnumeratorForSeq := nil;
// - отпусткаем текущий перечислитель
f_SearchMode := aValue;
//#UC END# *69BBB8A101BA_69AE74DB018Aset_impl*
end;//Tm3PlainAttrIndexDumper.Set_SearchMode
function Tm3PlainAttrIndexDumper.Get_Sequential: Boolean;
//#UC START# *69C1D45B01E5_69AE74DB018Aget_var*
//#UC END# *69C1D45B01E5_69AE74DB018Aget_var*
begin
//#UC START# *69C1D45B01E5_69AE74DB018Aget_impl*
Result := f_Sequential;
//#UC END# *69C1D45B01E5_69AE74DB018Aget_impl*
end;//Tm3PlainAttrIndexDumper.Get_Sequential
function Tm3PlainAttrIndexDumper.ToTheLeftOf(const anOther: Im3AttrIndexDumper): Boolean;
//#UC START# *69C1DE0300B2_69AE74DB018A_var*
//#UC END# *69C1DE0300B2_69AE74DB018A_var*
begin
//#UC START# *69C1DE0300B2_69AE74DB018A_impl*
Result := (Self.Get_MaxKeyID < anOther.MinKeyID);
//#UC END# *69C1DE0300B2_69AE74DB018A_impl*
end;//Tm3PlainAttrIndexDumper.ToTheLeftOf
procedure Tm3PlainAttrIndexDumper.Cleanup;
{* Функция очистки полей объекта. }
//#UC START# *479731C50290_69AE74DB018A_var*
//#UC END# *479731C50290_69AE74DB018A_var*
begin
//#UC START# *479731C50290_69AE74DB018A_impl*
//FreeAndNil(f_SubStreamForSeq);
//FreeAndNil(f_StreamForSeq);
f_EnumeratorForSeq := nil;
FreeAndNil(f_Stream);
FreeAndNil(f_Versions);
f_Modified := nil;
inherited;
//#UC END# *479731C50290_69AE74DB018A_impl*
end;//Tm3PlainAttrIndexDumper.Cleanup
procedure Tm3PlainAttrIndexDumper.ClearFields;
begin
f_Modified := nil;
f_EnumeratorForSeq := nil;
inherited;
end;//Tm3PlainAttrIndexDumper.ClearFields
//#UC START# *69AE74DB018Aimpl*
//#UC END# *69AE74DB018Aimpl*
constructor Tm3AttrIndexWriter.Create(aStream: Tl3Stream;
aIsDirect: Boolean);
//#UC START# *69AC2FDB01A1_69AC2E42033D_var*
const
cHeader : AnsiString = 'header';
var
l_S : AnsiString;
l_AfterGUIDPos : Int64;
l_HeaderStart : Int64;
//#UC END# *69AC2FDB01A1_69AC2E42033D_var*
begin
//#UC START# *69AC2FDB01A1_69AC2E42033D_impl*
f_IsDirect := aIsDirect;
Assert(aStream <> nil);
inherited Create;
aStream.SetRefTo(f_Stream);
f_Header.rZeroStart := 0;
f_Header.rVer := 'ver';
f_Header.rVersion := cOurVersion;
f_Header.rSig := 'sig';
f_Header.rSignature := cSignature;
f_Header.rTim := 'tim';
//f_Header.rTimeStamp := BadDateTime;
f_Header.rTimeStamp := 0;
f_Header.rHea := 'hea';
f_Header.rHeaderStart := -1;
f_Header.rHeaderEnd := -1;
f_Header.rStr := 'str';
f_Header.rStreamEnd := -1;
f_Header.rRan := 'ran';
f_Header.rRange := Tl3Range_E;
f_Header.rOper := 'oper';
f_Header.rOperation := m3_gopNone;
f_Header.rMod := 'mod';
f_Header.rModified.rPos := -1;
f_Header.rModified.rSize := 0;
f_Header.rVers := 'vers';
f_Header.rVersions.rPos := -1;
f_Header.rVersions.rSize := 0;
f_Header.rBod := 'bod';
f_Header.rBody.rPos := -1;
f_Header.rBody.rSize := 0;
f_Header.rCnt := 'cnt';
f_Header.rElementsCount := 0;
f_Header.rMin := 'min';
f_Header.rMinKeyID := High(f_Header.rMinKeyID);
f_Header.rMax := 'max';
f_Header.rMaxKeyID := Low(f_Header.rMaxKeyID);
f_Header.rNextPartPos := -1;
f_Header.rZeroEnd := 0;
f_Stream.Seek(0, soBeginning);
l_S := GUIDToString(c_m3AttrIndexWriterGUID);
f_Stream.WriteBuffer(l_S[1], Length(l_S));
l_AfterGUIDPos := f_Stream.Position;
// - позиция после GUID
f_Header.rStreamEnd := l_AfterGUIDPos;
l_HeaderStart := 0;
f_Stream.WriteBuffer(l_HeaderStart, SizeOf(l_HeaderStart));
// - пишем заглушку
Self.WriteStart(cHeader);
// - пишем маркер заголовка
l_HeaderStart := f_Header.rStreamEnd;
//l_HeaderStart := f_Stream.Position;
// - реальная позиция заголовка
//f_Header.rStreamEnd := l_HeaderStart;
f_Header.rHeaderStart := l_HeaderStart;
// - тут у нас закончился заголовок
f_Header.rHeaderEnd := l_HeaderStart + SizeOf(f_Header);
// - в заголовок присваиваем его начало
f_Stream.Seek(l_AfterGUIDPos, soBeginning);
// - смещаемся за GUID
f_Stream.WriteBuffer(l_HeaderStart, SizeOf(l_HeaderStart));
// - пишем реальное значение
f_Stream.Seek(l_HeaderStart, soBeginning);
// - возвращаемся к начало заголовка
f_Stream.WriteBuffer(f_Header, SizeOf(f_Header));
f_HeaderSave := f_Header;
// - пишем заголовок
//f_Header.rHeaderEnd := f_Stream.Position;
// - тут у нас закончился заголовок
Self.WriteEnd(cHeader);
// - пишем маркер заголовка
//f_Header.rStreamEnd := f_Stream.Position;
// - тут в данный момент закончился поток
Self.SaveHeader;
// - перезаписываем заголовок с актуальными значениями
//#UC END# *69AC2FDB01A1_69AC2E42033D_impl*
end;//Tm3AttrIndexWriter.Create
class function Tm3AttrIndexWriter.Make(aStream: Tl3Stream;
aIsDirect: Boolean): Im3AttrIndexWriter;
var
l_Inst : Tm3AttrIndexWriter;
begin
l_Inst := Create(aStream, aIsDirect);
try
Result := l_Inst;
finally
l_Inst.Free;
end;//try..finally
end;//Tm3AttrIndexWriter.Make
procedure Tm3AttrIndexWriter.WriteEOL;
//#UC START# *69AC3E360052_69AC2E42033D_var*
var
l_C : AnsiChar;
//#UC END# *69AC3E360052_69AC2E42033D_var*
begin
//#UC START# *69AC3E360052_69AC2E42033D_impl*
l_C := #13;
f_Stream.WriteBuffer(l_C, SizeOf(l_C));
l_C := #10;
f_Stream.WriteBuffer(l_C, SizeOf(l_C));
//#UC END# *69AC3E360052_69AC2E42033D_impl*
end;//Tm3AttrIndexWriter.WriteEOL
procedure Tm3AttrIndexWriter.SaveHeader;
//#UC START# *69AC40D00345_69AC2E42033D_var*
//#UC END# *69AC40D00345_69AC2E42033D_var*
begin
//#UC START# *69AC40D00345_69AC2E42033D_impl*
if (f_Stream <> nil) then
begin
if (m2MEMCompare(@f_Header, @f_HeaderSave, SizeOf(f_Header)) <> 0) then
begin
f_Stream.Seek(f_Header.rHeaderStart, soBeginning);
f_Stream.WriteBuffer(f_Header, SizeOf(f_Header));
f_HeaderSave := f_Header;
end;//m2MEMCompare(@f_Header, @f_HeaderSave, SizeOf(f_Header)) <> 0
end;//f_Stream <> nil
//#UC END# *69AC40D00345_69AC2E42033D_impl*
end;//Tm3AttrIndexWriter.SaveHeader
{$If NOT Defined(l3NoSRT)}
function Tm3AttrIndexWriter.SetRefTo(var thePlace: Tm3AttrIndexWriter): Boolean;
begin
if (thePlace = Self) then
Result := false
else
begin
Result := true;
thePlace.Free;
thePlace := Self.Use;
end;//thePlace = Self
end;//Tm3AttrIndexWriter.SetRefTo
{$IfEnd} // NOT Defined(l3NoSRT)
procedure Tm3AttrIndexWriter.WriteVersions(const aVersions: Im3IndexedVersions);
//#UC START# *69AC303F0197_69AC2E42033D_var*
const
cVersions : AnsiString = 'versions';
//#UC END# *69AC303F0197_69AC2E42033D_var*
begin
//#UC START# *69AC303F0197_69AC2E42033D_impl*
Assert(f_Header.rVersions.rPos = -1, l3ForceUTF8FPC('Уже писали версии'));
f_Stream.Seek(f_Header.rStreamEnd, soBeginning);
Self.WriteStart(cVersions);
f_Header.rVersions.rPos := f_Header.rStreamEnd;
//f_Header.rVersions.rPos := f_Stream.Position;
m3WriteVersionsToStream(aVersions, f_Stream);
f_Header.rVersions.rSize := f_Stream.Position - f_Header.rVersions.rPos;
Self.WriteEnd(cVersions);
//#UC END# *69AC303F0197_69AC2E42033D_impl*
end;//Tm3AttrIndexWriter.WriteVersions
procedure Tm3AttrIndexWriter.WriteModified(const aModified: Il3RangeEnumerable;
aTimeStamp: TDateTime);
//#UC START# *69AC30920069_69AC2E42033D_var*
const
cModified : AnsiString = 'modified';
var
l_TimeStamp: TDateTime;
//#UC END# *69AC30920069_69AC2E42033D_var*
begin
//#UC START# *69AC30920069_69AC2E42033D_impl*
l_TimeStamp := 0;
f_Header.rTimeStamp := 0;
System.Move(aTimeStamp, f_Header.rTimeStamp, SizeOf(f_Header.rTimeStamp));
System.Move(f_Header.rTimeStamp, l_TimeStamp, SizeOf(f_Header.rTimeStamp));
Assert(SameDateTime(l_TimeStamp, aTimeStamp));
//Assert(SameValue(l_TimeStamp, aTimeStamp));
//f_Header.rTimeStamp := aTimeStamp;
Assert(f_Header.rModified.rPos = -1, l3ForceUTF8FPC('Уже писали модифицированные'));
f_Stream.Seek(f_Header.rStreamEnd, soBeginning);
Self.WriteStart(cModified);
f_Header.rModified.rPos := f_Header.rStreamEnd;
//f_Header.rModified.rPos := f_Stream.Position;
Il3RangeEnumerable_WriteTo(aModified, f_Stream);
f_Header.rModified.rSize := f_Stream.Position - f_Header.rModified.rPos;
Self.WriteEnd(cModified);
//#UC END# *69AC30920069_69AC2E42033D_impl*
end;//Tm3AttrIndexWriter.WriteModified
procedure Tm3AttrIndexWriter.WriteRange(const aRange: Tl3Range);
//#UC START# *69AC30EC01E0_69AC2E42033D_var*
//#UC END# *69AC30EC01E0_69AC2E42033D_var*
begin
//#UC START# *69AC30EC01E0_69AC2E42033D_impl*
f_Header.rRange := aRange;
//Self.SaveHeader;
//#UC END# *69AC30EC01E0_69AC2E42033D_impl*
end;//Tm3AttrIndexWriter.WriteRange
procedure Tm3AttrIndexWriter.WriteOperation(anOperation: Tm3GroupOperation);
//#UC START# *69AC31B40187_69AC2E42033D_var*
//#UC END# *69AC31B40187_69AC2E42033D_var*
begin
//#UC START# *69AC31B40187_69AC2E42033D_impl*
f_Header.rOperation := anOperation;
//Self.SaveHeader;
//#UC END# *69AC31B40187_69AC2E42033D_impl*
end;//Tm3AttrIndexWriter.WriteOperation
procedure Tm3AttrIndexWriter.StartBody(aCount: Integer);
//#UC START# *69AC757C029F_69AC2E42033D_var*
const
cBody : AnsiString = 'body';
var
l_Element : Tm3AttrIndexWriterBodyElement;
l_Index : Integer;
//#UC END# *69AC757C029F_69AC2E42033D_var*
begin
//#UC START# *69AC757C029F_69AC2E42033D_impl*
Assert(f_Header.rBody.rPos = -1, l3ForceUTF8FPC('Уже писали тело'));
f_Sequential := true;
// - будем оптимистами
f_PrevKey := Low(f_PrevKey);
f_Header.rMinKeyID := High(f_Header.rMinKeyID);
f_Header.rMaxKeyID := Low(f_Header.rMaxKeyID);
f_DeclaredCapacity := aCount;
f_Capacity := aCount;
f_Header.rElementsCount := 0;
f_FrameInfo.rCount := 0;
f_FrameInfo.rMinKeyID := High(f_FrameInfo.rMinKeyID);
f_FrameInfo.rMaxKeyID := Low(f_FrameInfo.rMaxKeyID);
f_FrameInfo.rNextPartPos := -1;
f_Stream.Seek(f_Header.rStreamEnd, soBeginning);
Self.WriteStart(cBody);
f_Stream.WriteBuffer(cFirstFrameInfoMark[1], Length(cFirstFrameInfoMark));
f_Header.rStreamEnd := f_Stream.Position;
f_FrameInfoPos := f_Header.rStreamEnd;
f_Stream.WriteBuffer(f_FrameInfo, SizeOf(f_FrameInfo));
// - записываем placeholder'а
f_Header.rStreamEnd := f_Stream.Position;
f_Stream.WriteBuffer(cSequentialMark[1], Length(cSequentialMark));
f_Header.rStreamEnd := f_Stream.Position;
f_SequentialInfoPos := f_Header.rStreamEnd;
f_Stream.WriteBuffer(f_Sequential, SizeOf(f_Sequential));
// - записываем placeholder'а
f_Header.rStreamEnd := f_Stream.Position;
f_Header.rBody.rPos := f_Header.rStreamEnd;
//f_Header.rBody.rPos := f_Stream.Position;
l_Element.rType := m3_etNone;
l_Element.rKey := Low(l_Element.rKey);
l_Element.rValue := Low(l_Element.rValue);
for l_Index := 0 to Pred(aCount) do
begin
f_Stream.WriteBuffer(l_Element, SizeOf(l_Element));
end;//for l_Index
f_Header.rBody.rSize := f_Stream.Position - f_Header.rBody.rPos;
Self.WriteEnd(cBody);
f_Stream.Seek(f_Header.rBody.rPos, soBeginning);
//#UC END# *69AC757C029F_69AC2E42033D_impl*
end;//Tm3AttrIndexWriter.StartBody
procedure Tm3AttrIndexWriter.FinishBody;
//#UC START# *69AC75A80048_69AC2E42033D_var*
//#UC END# *69AC75A80048_69AC2E42033D_var*
begin
//#UC START# *69AC75A80048_69AC2E42033D_impl*
f_Stream.Seek(f_FrameInfoPos, soBeginning);
f_Stream.WriteBuffer(f_FrameInfo, SizeOf(f_FrameInfo));
if not f_Sequential then
begin
f_Stream.Seek(f_SequentialInfoPos, soBeginning);
f_Stream.WriteBuffer(f_Sequential, SizeOf(f_Sequential));
end;//not f_Sequential
//#UC END# *69AC75A80048_69AC2E42033D_impl*
end;//Tm3AttrIndexWriter.FinishBody
procedure Tm3AttrIndexWriter.WriteBodyElement(aKey: Integer;
const aValue: Il3RangeEnumerable);
//#UC START# *69AC818E005F_69AC2E42033D_var*
{.$Define _m3UsePack}
var
l_Element : Tm3AttrIndexWriterBodyElement;
l_Enum : Il3IntegerEnumerable;
l_It : Il3IntegerEnumerator;
l_RangesCount : Integer;
l_Count : Integer;
l_Pos : Int64;
l_Size : Int64;
l_SizePos : Int64;
l_ValuePos : Int64;
l_KeyStr : AnsiString;
l_NeedPack : Boolean;
{.$IfDef _m3UsePack}
l_Orig : Tl3Stream;
l_Packed : Tl3Stream;
l_PackedSize : Int64;
l_PackStream : Tl3Stream;
{.$EndIf _m3UsePack}
i : Integer;
l_R : Tm3IDRange;
l_NeedMultiply : Boolean;
l_NeedCheckSimple : Boolean;
// - https://mdp.garant.ru/pages/viewpage.action?pageId=902725962
//#UC END# *69AC818E005F_69AC2E42033D_var*
begin
//#UC START# *69AC818E005F_69AC2E42033D_impl*
Assert(f_PrevKey < aKey);
if f_Sequential then
if not (f_PrevKey + 1 = aKey) then
if (f_PrevKey <> Low(f_PrevKey)) then
f_Sequential := false;
if (f_Capacity <= 0) then
begin
if (aValue = nil)
OR aValue.Empty then
begin
l3System.Msg2Log(l3ForceUTF8FPC('Для ключа: ') + IntToStr(aKey) + l3ForceUTF8FPC(' не будем писать пустые значения'));
Exit;
// - хрен с этими пустыми значениями
end;//aValue = nil
l3System.Msg2Log(l3ForceUTF8FPC('Для ключа: ') + IntToStr(aKey) + l3ForceUTF8FPC(' потеряны значения при записи. Т.к. исчерпана мощность: ') + IntToStr(f_DeclaredCapacity));
{$IfDef nsTest}
Assert(false, l3ForceUTF8FPC('Исчерпана мощность: ') + IntToStr(f_DeclaredCapacity));
{$EndIf nsTest}
Exit;
// - чтобы уж не порушить весь процесс
end;//f_Capacity <= 0
if f_IsDirect then
begin
if (aValue = nil)
OR aValue.Empty then
begin
Exit;
// - пока не пишем в лог
l3System.Msg2Log(l3ForceUTF8FPC('Для ключа: ') + IntToStr(aKey) + l3ForceUTF8FPC(' не будем писать пустые значения'));
Exit;
// - хрен с этими пустыми значениями
// Чтобы не расходовать мощность впустую.
end;//aValue = nil
end;//f_IsDirect
Dec(f_Capacity);
Inc(f_Header.rElementsCount);
Inc(f_FrameInfo.rCount);
if (aKey > f_Header.rMaxKeyID) then
f_Header.rMaxKeyID := aKey;
if (aKey < f_Header.rMinKeyID) then
f_Header.rMinKeyID := aKey;
if (aKey > f_FrameInfo.rMaxKeyID) then
f_FrameInfo.rMaxKeyID := aKey;
if (aKey < f_FrameInfo.rMinKeyID) then
f_FrameInfo.rMinKeyID := aKey;
f_PrevKey := aKey;
l_Pos := f_Stream.Position;
l_Element.rType := m3_etNone;
l_Element.rKey := aKey;
l_Element.rValue := Low(l_Element.rValue);
if (aValue = nil) then
l_RangesCount := 0
else
l_RangesCount := aValue.Count;
l_R := Tl3Range_E;
if (l_RangesCount = 1) then
begin
l_R := aValue.First;
if (l_R.rLow = l_R.rHigh) then
l_RangesCount := -1;
// - ну пусть будет минус
end;//l_RangesCount = 1
if (l_RangesCount = 1) then
begin
l_Element.rType := m3_etRange;
Tm3IDRange(l_Element.rValue) := l_R;
end//l_RangesCount = 1
else
begin
l_NeedMultiply := true;
if (l_RangesCount = -1) then
l_RangesCount := 1;
l_NeedCheckSimple := true;
if (l_RangesCount = 1) then
begin
Assert(l_R.rLow = l_R.rHigh);
// - сюда не можем попасть, т.к. обработали выше
l_Element.rType := m3_etSingle;
l_Element.rValue := l_R.rLow;
l_NeedCheckSimple := false;
l_NeedMultiply := false;
end//l_RangesCount = 1
else
if (l_RangesCount > 10) then
// https://mdp.garant.ru/pages/viewpage.action?pageId=902725962
// – тут надо сделать проверку l_RangesCount чтобы для больших чисел не преобразовывать Il3RangeEnumerable к Il3IntegerEnumerable.
begin
l_NeedCheckSimple := false;
end;//l_RangesCount > 10
if l_NeedCheckSimple then
// - https://mdp.garant.ru/pages/viewpage.action?pageId=902725962
begin
l_NeedMultiply := false;
// - предполагаем что обойдёмся малой кровью
l_Enum := Il3RangeEnumerable_ToIntegerEnumerable(aValue);
if (l_Enum = nil) then
l_Count := 0
else
l_Count := l_Enum.Count;
if (l_Count = 0) then
l_Element.rType := m3_etNone
else
if (l_Count = 1) then
begin
l_Element.rType := m3_etSingle;
l_Element.rValue := l_Enum.First;
end//l_Count = 1
else
if (l_Count = 2) then
begin
l_Element.rType := m3_etPair;
l_It := l_Enum.GetEnumerator;
if not l_It.MoveNext then
Assert(false);
T64to32(l_Element.rValue).rLow := l_It.Current;
if not l_It.MoveNext then
Assert(false);
T64to32(l_Element.rValue).rHigh := l_It.Current;
end//l_Count = 2
else
l_NeedMultiply := true;
end;//l_NeedCheckSimple
if l_NeedMultiply then
begin
l_NeedPack := false;
l_Element.rType := m3_etMultiply;
if l_NeedCheckSimple then
// - https://mdp.garant.ru/pages/viewpage.action?pageId=902725962
begin
if (l_Count = 4) then
begin
l_Element.rType := m3_et4;
l_It := l_Enum.GetEnumerator;
i := 0;
while l_It.MoveNext do
begin
if (l_It.Current <= High(SmallInt))
AND (l_It.Current >= Low(SmallInt))
then
begin
T64toSmallInts(l_Element.rValue)[i] := l_It.Current;
Inc(i);
end//l_It.Current <= High(SmallInt)
else
begin
l_Element.rType := m3_etMultiply;
break;
end;//l_It.Current <= High(SmallInt)
end;//l_It.MoveNext
end//l_Count = 4
else
if (l_Count = 8) then
begin
l_Element.rType := m3_et8;
l_It := l_Enum.GetEnumerator;
i := 0;
while l_It.MoveNext do
begin
if (l_It.Current <= High(Byte))
AND (l_It.Current >= Low(Byte))
then
begin
T64toBytes(l_Element.rValue)[i] := l_It.Current;
Inc(i);
end//l_It.Current <= High(SmallInt)
else
begin
l_Element.rType := m3_etMultiply;
break;
end;//l_It.Current <= High(SmallInt)
end;//l_It.MoveNext
end;//l_Count = 8
end;//l_NeedCheckSimple
if (l_Element.rType = m3_etMultiply) then
begin
l_Size := 0;
l_KeyStr := IntToStr(aKey);
l_SizePos := f_Header.rStreamEnd;
// - размер будет записан в конец потока
f_Stream.Seek(l_SizePos, soBeginning);
// - смещаемся к концу потока
Self.WriteStart(l_KeyStr);
// - записываем маркер потока
if (l_RangesCount > 1000) then
l_NeedPack := true;
if l_NeedPack then
begin
l_Orig := Tl3TempMemoryStream.Create;
try
Il3RangeEnumerable_WriteTo(aValue, l_Orig);
l_Size := l_Orig.Size;
Assert(l_Size > 0);
l_Packed := Tl3TempMemoryStream.Create;
try
l_PackStream := Tl3ZLibCompressStream.Create(l_Packed);
//l_PackStream := Tm3LZODeflateStreamNew.Create(l_Packed);
try
l_Orig.Seek(0, soBeginning);
l3CopyStream(IStream(l_Orig), IStream(l_PackStream));
//l_PackStream.CopyFrom(l_Orig, 0);
finally
FreeAndNil(l_PackStream);
end;//try..finally
l_PackedSize := l_Packed.Size;
Assert(l_PackedSize > 0);
l_SizePos := f_Header.rStreamEnd;
// - запоминаем место где начнётся Size + Value
if (l_PackedSize < l_Size) then
begin
l_Element.rType := m3_etZLib;
//l_Element.rType := m3_etLZO;
f_Stream.WriteBuffer(l_PackedSize, SizeOf(l_PackedSize));
// - записывем реальный размер (вместо placeholer)
f_Stream.CopyFrom(l_Packed, 0);
end//l_PackedSize < l_Size
else
begin
f_Stream.WriteBuffer(l_Size, SizeOf(l_Size));
// - записывем реальный размер (вместо placeholer)
f_Stream.CopyFrom(l_Orig, 0);
end;//l_PackedSize < l_Size
finally
FreeAndNil(l_Packed);
end;//try..finally
finally
FreeAndNil(l_Orig);
end;//try..finally
Self.WriteEnd(l_KeyStr);
// - записываем маркер потока
end//l_NeedPack
else
begin
l_SizePos := f_Header.rStreamEnd;
// - запоминаем место где начнётся Size + Value
f_Stream.WriteBuffer(l_Size, SizeOf(l_Size));
// - записывем место для Size (placeholer)
l_ValuePos := f_Stream.Position;
// - запоминаем место где начались значения
Il3RangeEnumerable_WriteTo(aValue, f_Stream);
// - записываем значения
f_Header.rStreamEnd := f_Stream.Position;
// - устанавливаем новый конец потока
l_Size := f_Header.rStreamEnd - l_ValuePos;
// - вычисляем размер значений
Self.WriteEnd(l_KeyStr);
// - записываем маркер потока
Assert(l_Size > 0);
f_Stream.Seek(l_SizePos, soBeginning);
// - смещаемся к месту где надо писать размер
f_Stream.WriteBuffer(l_Size, SizeOf(l_Size));
// - записывем реальный размер (вместо placeholer)
end;//l_NeedPack
l_Element.rValue := l_SizePos;
// - отсюда потом будем вычитывать Size + Value
f_Stream.Seek(l_Pos, soBeginning);
// - возвращаем позицию элемента
end;//l_Element.rType = m3_etMultiply
end;//l_NeedMultiply
end;//l_Count = 1
f_Stream.WriteBuffer(l_Element, SizeOf(l_Element));
//#UC END# *69AC818E005F_69AC2E42033D_impl*
end;//Tm3AttrIndexWriter.WriteBodyElement
procedure Tm3AttrIndexWriter.Cleanup;
{* Функция очистки полей объекта. }
//#UC START# *479731C50290_69AC2E42033D_var*
//#UC END# *479731C50290_69AC2E42033D_var*
begin
//#UC START# *479731C50290_69AC2E42033D_impl*
//Self.SaveHeader;
FreeAndNil(f_Stream);
inherited;
//#UC END# *479731C50290_69AC2E42033D_impl*
end;//Tm3AttrIndexWriter.Cleanup
procedure Tm3AttrIndexWriter.BeforeRelease;
//#UC START# *49BFC98902FF_69AC2E42033D_var*
//#UC END# *49BFC98902FF_69AC2E42033D_var*
begin
//#UC START# *49BFC98902FF_69AC2E42033D_impl*
Self.SaveHeader;
inherited;
//#UC END# *49BFC98902FF_69AC2E42033D_impl*
end;//Tm3AttrIndexWriter.BeforeRelease
//#UC START# *69AC2E42033Dimpl*
procedure Tm3AttrIndexWriter.ifWriteEOL;
var
l_Pos : Int64;
l_C : AnsiChar;
begin
l_Pos := f_Stream.Position;
f_Stream.Seek(-1, soCurrent);
f_Stream.ReadBuffer(l_C, SizeOf(l_C));
f_Stream.Seek(l_Pos, soBeginning);
if (l_C <> #10) then
Self.WriteEOL;
end;//Tm3AttrIndexWriter.ifWriteEOL
procedure Tm3AttrIndexWriter.WriteStart(const aStr: Ansistring);
var
l_C : AnsiChar;
l_Pos : Int64;
begin
Self.ifWriteEOL;
l_C := '{';
f_Stream.WriteBuffer(l_C, SizeOf(l_C));
f_Stream.WriteBuffer(aStr[1], Length(aStr));
l_C := '}';
f_Stream.WriteBuffer(l_C, SizeOf(l_C));
Self.WriteEOL;
l_Pos := f_Stream.Position;
if (f_Header.rStreamEnd < l_Pos) then
f_Header.rStreamEnd := l_Pos;
end;//Tm3AttrIndexWriter.WriteStart
procedure Tm3AttrIndexWriter.WriteEnd(const aStr: Ansistring);
var
l_C : AnsiChar;
l_Pos : Int64;
begin
Self.ifWriteEOL;
l_C := '{';
f_Stream.WriteBuffer(l_C, SizeOf(l_C));
l_C := '/';
f_Stream.WriteBuffer(l_C, SizeOf(l_C));
f_Stream.WriteBuffer(aStr[1], Length(aStr));
l_C := '}';
f_Stream.WriteBuffer(l_C, SizeOf(l_C));
Self.WriteEOL;
l_Pos := f_Stream.Position;
if (f_Header.rStreamEnd < l_Pos) then
f_Header.rStreamEnd := l_Pos;
end;//Tm3AttrIndexWriter.WriteEnd
//#UC END# *69AC2E42033Dimpl*
{$If NOT Defined(NoScripts)}
class function TIm3AttrIndexWriterKeywordsPackResNameGetter.ResName: AnsiString;
begin
Result := 'Im3AttrIndexWriterKeywordsPack';
end;//TIm3AttrIndexWriterKeywordsPackResNameGetter.ResName
{$R Im3AttrIndexWriterKeywordsPack.res}
{$IfEnd} // NOT Defined(NoScripts)
{$If NOT Defined(NoScripts)}
constructor TBoxFor_Tm3AttrIndexWriterSubStreamInfo.Create(const aBoxed: Tm3AttrIndexWriterSubStreamInfo);
begin
inherited Create;
f_Boxed := aBoxed;
end;//TBoxFor_Tm3AttrIndexWriterSubStreamInfo.Create
class function TBoxFor_Tm3AttrIndexWriterSubStreamInfo.Make(const aBoxed: Tm3AttrIndexWriterSubStreamInfo): IBoxFor_Tm3AttrIndexWriterSubStreamInfo;
var
l_Inst : TBoxFor_Tm3AttrIndexWriterSubStreamInfo;
begin
l_Inst := Create(aBoxed);
try
Result := l_Inst;
finally
l_Inst.Free;
end;//try..finally
end;//TBoxFor_Tm3AttrIndexWriterSubStreamInfo.Make
function TBoxFor_Tm3AttrIndexWriterSubStreamInfo.Get_Boxed: Tm3AttrIndexWriterSubStreamInfo;
begin
Result := f_Boxed;
end;//TBoxFor_Tm3AttrIndexWriterSubStreamInfo.Get_Boxed
function TBoxFor_Tm3AttrIndexWriterSubStreamInfo.Get_pBoxed: Tm3AttrIndexWriterSubStreamInfoPtr;
begin
Result := @f_Boxed;
end;//TBoxFor_Tm3AttrIndexWriterSubStreamInfo.Get_pBoxed
function TBoxFor_Tm3AttrIndexWriterSubStreamInfo.GetDataPtr: Pointer;
begin
Result := @f_Boxed;
end;//TBoxFor_Tm3AttrIndexWriterSubStreamInfo.GetDataPtr
function TBoxFor_Tm3AttrIndexWriterSubStreamInfo.GetDataSize: Integer;
begin
Result := SizeOf(f_Boxed);
end;//TBoxFor_Tm3AttrIndexWriterSubStreamInfo.GetDataSize
function TBoxFor_Tm3AttrIndexWriterSubStreamInfo.GetBoxTypeInfo: PTypeInfo;
begin
Result := TypeInfo(IBoxFor_Tm3AttrIndexWriterSubStreamInfo);
end;//TBoxFor_Tm3AttrIndexWriterSubStreamInfo.GetBoxTypeInfo
function TBoxFor_Tm3AttrIndexWriterSubStreamInfo.GetAsPrintable(const aCtx: TtfwContextStub): Il3CString;
var
l_Value: AnsiString;
begin
l_Value := '(';
l_Value := l_Value + ' )';
Result := TtfwCStringFactory.C(l_Value);
end;//TBoxFor_Tm3AttrIndexWriterSubStreamInfo.GetAsPrintable
procedure TBoxFor_Tm3AttrIndexWriterSubStreamInfo.ClearFields;
begin
Finalize(f_Boxed);
inherited;
end;//TBoxFor_Tm3AttrIndexWriterSubStreamInfo.ClearFields
//#UC START# *69AFF780026ATBoximpl*
//#UC END# *69AFF780026ATBoximpl*
{$IfEnd} // NOT Defined(NoScripts)
{$If NOT Defined(NoScripts)}
constructor TBoxFor_Tm3AttrIndexWriterBodyElement.Create(const aBoxed: Tm3AttrIndexWriterBodyElement);
begin
inherited Create;
f_Boxed := aBoxed;
end;//TBoxFor_Tm3AttrIndexWriterBodyElement.Create
class function TBoxFor_Tm3AttrIndexWriterBodyElement.Make(const aBoxed: Tm3AttrIndexWriterBodyElement): IBoxFor_Tm3AttrIndexWriterBodyElement;
var
l_Inst : TBoxFor_Tm3AttrIndexWriterBodyElement;
begin
l_Inst := Create(aBoxed);
try
Result := l_Inst;
finally
l_Inst.Free;
end;//try..finally
end;//TBoxFor_Tm3AttrIndexWriterBodyElement.Make
function TBoxFor_Tm3AttrIndexWriterBodyElement.Get_Boxed: Tm3AttrIndexWriterBodyElement;
begin
Result := f_Boxed;
end;//TBoxFor_Tm3AttrIndexWriterBodyElement.Get_Boxed
function TBoxFor_Tm3AttrIndexWriterBodyElement.Get_pBoxed: Tm3AttrIndexWriterBodyElementPtr;
begin
Result := @f_Boxed;
end;//TBoxFor_Tm3AttrIndexWriterBodyElement.Get_pBoxed
function TBoxFor_Tm3AttrIndexWriterBodyElement.GetDataPtr: Pointer;
begin
Result := @f_Boxed;
end;//TBoxFor_Tm3AttrIndexWriterBodyElement.GetDataPtr
function TBoxFor_Tm3AttrIndexWriterBodyElement.GetDataSize: Integer;
begin
Result := SizeOf(f_Boxed);
end;//TBoxFor_Tm3AttrIndexWriterBodyElement.GetDataSize
function TBoxFor_Tm3AttrIndexWriterBodyElement.GetBoxTypeInfo: PTypeInfo;
begin
Result := TypeInfo(IBoxFor_Tm3AttrIndexWriterBodyElement);
end;//TBoxFor_Tm3AttrIndexWriterBodyElement.GetBoxTypeInfo
function TBoxFor_Tm3AttrIndexWriterBodyElement.GetAsPrintable(const aCtx: TtfwContextStub): Il3CString;
var
l_Value: AnsiString;
begin
l_Value := '(';
l_Value := l_Value + ' )';
Result := TtfwCStringFactory.C(l_Value);
end;//TBoxFor_Tm3AttrIndexWriterBodyElement.GetAsPrintable
procedure TBoxFor_Tm3AttrIndexWriterBodyElement.ClearFields;
begin
Finalize(f_Boxed);
inherited;
end;//TBoxFor_Tm3AttrIndexWriterBodyElement.ClearFields
//#UC START# *69AC79CD0094TBoximpl*
//#UC END# *69AC79CD0094TBoximpl*
{$IfEnd} // NOT Defined(NoScripts)
{$If NOT Defined(NoScripts)}
constructor TBoxFor_Tm3AttrIndexWriterHeader.Create(const aBoxed: Tm3AttrIndexWriterHeader);
begin
inherited Create;
f_Boxed := aBoxed;
end;//TBoxFor_Tm3AttrIndexWriterHeader.Create
class function TBoxFor_Tm3AttrIndexWriterHeader.Make(const aBoxed: Tm3AttrIndexWriterHeader): IBoxFor_Tm3AttrIndexWriterHeader;
var
l_Inst : TBoxFor_Tm3AttrIndexWriterHeader;
begin
l_Inst := Create(aBoxed);
try
Result := l_Inst;
finally
l_Inst.Free;
end;//try..finally
end;//TBoxFor_Tm3AttrIndexWriterHeader.Make
function TBoxFor_Tm3AttrIndexWriterHeader.Get_Boxed: Tm3AttrIndexWriterHeader;
begin
Result := f_Boxed;
end;//TBoxFor_Tm3AttrIndexWriterHeader.Get_Boxed
function TBoxFor_Tm3AttrIndexWriterHeader.Get_pBoxed: Tm3AttrIndexWriterHeaderPtr;
begin
Result := @f_Boxed;
end;//TBoxFor_Tm3AttrIndexWriterHeader.Get_pBoxed
function TBoxFor_Tm3AttrIndexWriterHeader.GetDataPtr: Pointer;
begin
Result := @f_Boxed;
end;//TBoxFor_Tm3AttrIndexWriterHeader.GetDataPtr
function TBoxFor_Tm3AttrIndexWriterHeader.GetDataSize: Integer;
begin
Result := SizeOf(f_Boxed);
end;//TBoxFor_Tm3AttrIndexWriterHeader.GetDataSize
function TBoxFor_Tm3AttrIndexWriterHeader.GetBoxTypeInfo: PTypeInfo;
begin
Result := TypeInfo(IBoxFor_Tm3AttrIndexWriterHeader);
end;//TBoxFor_Tm3AttrIndexWriterHeader.GetBoxTypeInfo
function TBoxFor_Tm3AttrIndexWriterHeader.GetAsPrintable(const aCtx: TtfwContextStub): Il3CString;
var
l_Value: AnsiString;
begin
l_Value := '(';
l_Value := l_Value + ' )';
Result := TtfwCStringFactory.C(l_Value);
end;//TBoxFor_Tm3AttrIndexWriterHeader.GetAsPrintable
procedure TBoxFor_Tm3AttrIndexWriterHeader.ClearFields;
begin
Finalize(f_Boxed);
inherited;
end;//TBoxFor_Tm3AttrIndexWriterHeader.ClearFields
//#UC START# *69AC312A0001TBoximpl*
//#UC END# *69AC312A0001TBoximpl*
{$IfEnd} // NOT Defined(NoScripts)
initialization
{$If NOT Defined(NoScripts)}
TtfwTypeRegistrator.RegisterType(TypeInfo(Im3AttrIndexWriter));
{$IfEnd} // NOT Defined(NoScripts)
{$If NOT Defined(NoScripts)}
TkwIm3AttrIndexWriterWriteVersions.RegisterInEngine(TtfwRegisterContext_E
.SetSelfTypeInfo(Im3AttrIndexWriterKeywordsPack_Im3AttrIndexWriter_SelfTypeInfo)
.SetParamsTypesFunc(TkwIm3AttrIndexWriterWriteVersions_ParamsTypes)
.SetDoItProc(TkwIm3AttrIndexWriterWriteVersions_DoIt)
.SetMethodName('WriteVersions'), ['m3AttrIndexWriter:WriteVersions', '.Im3AttrIndexWriter.WriteVersions', 'pop:m3AttrIndexWriter:WriteVersions']);
{$IfEnd} // NOT Defined(NoScripts)
{$If NOT Defined(NoScripts)}
TkwIm3AttrIndexWriterWriteRange.RegisterInEngine(TtfwRegisterContext_E
.SetSelfTypeInfo(Im3AttrIndexWriterKeywordsPack_Im3AttrIndexWriter_SelfTypeInfo)
.SetParamsTypesFunc(TkwIm3AttrIndexWriterWriteRange_ParamsTypes)
.SetDoItProc(TkwIm3AttrIndexWriterWriteRange_DoIt)
.SetMethodName('WriteRange'), ['m3AttrIndexWriter:WriteRange', '.Im3AttrIndexWriter.WriteRange', 'pop:m3AttrIndexWriter:WriteRange']);
{$IfEnd} // NOT Defined(NoScripts)
{$If NOT Defined(NoScripts)}
TkwIm3AttrIndexWriterWriteOperation.RegisterInEngine(TtfwRegisterContext_E
.SetSelfTypeInfo(Im3AttrIndexWriterKeywordsPack_Im3AttrIndexWriter_SelfTypeInfo)
.SetParamsTypesFunc(TkwIm3AttrIndexWriterWriteOperation_ParamsTypes)
.SetDoItProc(TkwIm3AttrIndexWriterWriteOperation_DoIt)
.SetMethodName('WriteOperation'), ['m3AttrIndexWriter:WriteOperation', '.Im3AttrIndexWriter.WriteOperation', 'pop:m3AttrIndexWriter:WriteOperation']);
{$IfEnd} // NOT Defined(NoScripts)
{$If NOT Defined(NoScripts)}
TkwIm3AttrIndexWriterStartBody.RegisterInEngine(TtfwRegisterContext_E
.SetSelfTypeInfo(Im3AttrIndexWriterKeywordsPack_Im3AttrIndexWriter_SelfTypeInfo)
.SetParamsTypesFunc(TkwIm3AttrIndexWriterStartBody_ParamsTypes)
.SetDoItProc(TkwIm3AttrIndexWriterStartBody_DoIt)
.SetMethodName('StartBody'), ['m3AttrIndexWriter:StartBody', '.Im3AttrIndexWriter.StartBody', 'pop:m3AttrIndexWriter:StartBody']);
{$IfEnd} // NOT Defined(NoScripts)
{$If NOT Defined(NoScripts)}
TkwIm3AttrIndexWriterFinishBody.RegisterInEngine(TtfwRegisterContext_E
.SetSelfTypeInfo(Im3AttrIndexWriterKeywordsPack_Im3AttrIndexWriter_SelfTypeInfo)
.SetDoItProc(TkwIm3AttrIndexWriterFinishBody_DoIt)
.SetMethodName('FinishBody'), ['m3AttrIndexWriter:FinishBody', '.Im3AttrIndexWriter.FinishBody', 'pop:m3AttrIndexWriter:FinishBody']);
{$IfEnd} // NOT Defined(NoScripts)
{$If NOT Defined(NoScripts)}
TkwIm3AttrIndexWriterWriteBodyElement.RegisterInEngine(TtfwRegisterContext_E
.SetSelfTypeInfo(Im3AttrIndexWriterKeywordsPack_Im3AttrIndexWriter_SelfTypeInfo)
.SetParamsTypesFunc(TkwIm3AttrIndexWriterWriteBodyElement_ParamsTypes)
.SetDoItProc(TkwIm3AttrIndexWriterWriteBodyElement_DoIt)
.SetMethodName('WriteBodyElement'), ['m3AttrIndexWriter:WriteBodyElement', '.Im3AttrIndexWriter.WriteBodyElement', 'pop:m3AttrIndexWriter:WriteBodyElement']);
{$IfEnd} // NOT Defined(NoScripts)
{$If NOT Defined(NoScripts)}
TIm3AttrIndexWriterKeywordsPackResNameGetter.Register;
{$IfEnd} // NOT Defined(NoScripts)
{$If NOT Defined(NoScripts)}
TtfwTypeRegistrator.RegisterType(TtfwValueTypes.MakeTypedef('Im3IndexedVersions', TypeInfo(Im3IndexedVersions)));
{$IfEnd} // NOT Defined(NoScripts)
{$If NOT Defined(NoScripts)}
TtfwTypeRegistrator.RegisterType(TtfwValueTypes.MakeBox('Tl3Range', Tl3Range_TypeInfo));
{$IfEnd} // NOT Defined(NoScripts)
{$If NOT Defined(NoScripts)}
TtfwTypeRegistrator.RegisterType(TypeInfo(Tm3GroupOperation));
{$IfEnd} // NOT Defined(NoScripts)
{$If NOT Defined(NoScripts)}
TtfwTypeRegistrator.RegisterType(TtfwTypeInfo.MakeInteger
, 'Целое число');
{$IfEnd} // NOT Defined(NoScripts)
{$If NOT Defined(NoScripts)}
TtfwClassRef_Proxy.TtfwClassRef.Register(TypeInfo(Tm3PlainAttrIndexDumperElementEnumerator));
{$IfEnd} // NOT Defined(NoScripts)
{$If NOT Defined(NoScripts)}
TtfwClassRef_Proxy.TtfwClassRef.Register(TypeInfo(Tm3PlainAttrIndexDumperElement));
{$IfEnd} // NOT Defined(NoScripts)
{$If NOT Defined(NoScripts)}
TtfwClassRef_Proxy.TtfwClassRef.Register(TypeInfo(Tm3PlainAttrIndexDumper)
, 'Читатель индекса атрибутов в "упрощённом виде".'
+ #13#10 + '{RequestLink:901972048}');
{$IfEnd} // NOT Defined(NoScripts)
{$If NOT Defined(NoScripts)}
TtfwClassRef_Proxy.TtfwClassRef.Register(TypeInfo(Tm3AttrIndexWriter)
, 'Писатель индекса атрибутов в "упрощённом виде".'
+ #13#10 + '{RequestLink:901972048}');
{$IfEnd} // NOT Defined(NoScripts)
//#UC START# *69AC2E42033DforDiagramm*
(*
[*
+-----------------------------------------------------------------------+
| m3AttrIndexWriter - СТРУКТУРА ИНДЕКСА АТРИБУТОВ |
+-----------------------------------------------------------------------+
1. ФОРМАТ ФАЙЛА ИНДЕКСА
+-----------------------------------------------------------------------+
| |
| +-----------------------------------------------------------------+ |
| | [GUID] {2020CBAD-78CC-494B-84B0-2EF18ADEA65A} | |
| | [HeaderPos] Int64 | |
| | | |
| | +-------------------------------------------------------------+ | |
| | | {header} | | |
| | | +---------------------------------------------------------+ | | |
| | | | Tm3AttrIndexWriterHeader (packed record) | | | |
| | | | +-----------------------------------------------------+ | | | |
| | | | | rVersion : Integer | | | | |
| | | | | rTimeStamp : Int64 | | | | |
| | | | | rRange : Tm3IDRange | | | | |
| | | | | rOperation : Tm3GroupOperation | | | | |
| | | | | rModified : Tm3AttrIndexWriterSubStreamInfo | | | | |
| | | | | rVersions : Tm3AttrIndexWriterSubStreamInfo | | | | |
| | | | | rBody : Tm3AttrIndexWriterSubStreamInfo | | | | |
| | | | | rElementsCount : Integer | | | | |
| | | | | rMinKeyID : Integer | | | | |
| | | | | rMaxKeyID : Integer | | | | |
| | | | | rNextPartPos : Int64 | | | | |
| | | | +-----------------------------------------------------+ | | | |
| | | +---------------------------------------------------------+ | | |
| | | {/header} | | |
| | +-------------------------------------------------------------+ | |
| | | |
| | +-------------------------------------------------------------+ | |
| | | {modified} | | |
| | | +---------------------------------------------------------+ | | |
| | | | Il3RangeEnumerable (модифицированные документы) | | | |
| | | +---------------------------------------------------------+ | | |
| | | {/modified} | | |
| | +-------------------------------------------------------------+ | |
| | | |
| | +-------------------------------------------------------------+ | |
| | | {versions} | | |
| | | +---------------------------------------------------------+ | | |
| | | | Im3IndexedVersions (версии) | | | |
| | | +---------------------------------------------------------+ | | |
| | | {/versions} | | |
| | +-------------------------------------------------------------+ | |
| | | |
| | +-------------------------------------------------------------+ | |
| | | {body} | | |
| | | +---------------------------------------------------------+ | | |
| | | | ffi (маркер фрейма) | | | |
| | | | Tm3BodyFrameInfo | | | |
| | | | seq (маркер sequential) | | | |
| | | | f_Sequential : Boolean | | | |
| | | | | | | |
| | | | [элемент 0] Tm3AttrIndexWriterBodyElement | | | |
| | | | [элемент 1] Tm3AttrIndexWriterBodyElement | | | |
| | | | ... | | | |
| | | | [элемент N-1] Tm3AttrIndexWriterBodyElement | | | |
| | | +---------------------------------------------------------+ | | |
| | | {/body} | | |
| | +-------------------------------------------------------------+ | |
| | | |
| | +-------------------------------------------------------------+ | |
| | | [следующая часть] если rNextPartPos > 0 | | |
| | +-------------------------------------------------------------+ | |
| | | |
| +-----------------------------------------------------------------+ |
| |
+-----------------------------------------------------------------------+
2. СТРУКТУРА ЭЛЕМЕНТА (Tm3AttrIndexWriterBodyElement)
+-----------------------------------------------------------------------+
| |
| +-----------------------------------------------------------------+ |
| | rType : Tm3ElementType | |
| | +-------------------------------------------------------------+ | |
| | | m3_etNone - пусто | | |
| | | m3_etSingle - одно значение | | |
| | | m3_etPair - два значения (T64to32) | | |
| | | m3_et4 - четыре SmallInt | | |
| | | m3_et8 - восемь Byte | | |
| | | m3_etRange - диапазон (Tl3Range) | | |
| | | m3_etMultiply- список значений (упакованный) | | |
| | | m3_etLZO - сжатый LZO | | |
| | | m3_etZLib - сжатый ZLib | | |
| | +-------------------------------------------------------------+ | |
| | rKey : Int64 (ID ключа) | |
| | rValue : Int64 (значение или смещение) | |
| +-----------------------------------------------------------------+ |
| |
+-----------------------------------------------------------------------+
3. КЛАССЫ
+-----------------------------------------------------------------------+
| |
| +-----------------------------------------------------------------+ |
| | Tm3AttrIndexWriter (писатель) | |
| | +-------------------------------------------------------------+ | |
| | | - f_Stream : Tl3Stream | | |
| | | - f_Header : Tm3AttrIndexWriterHeader | | |
| | | - f_IsDirect : Boolean | | |
| | | - f_Sequential : Boolean | | |
| | | - f_FrameInfo : Tm3BodyFrameInfo | | |
| | +-------------------------------------------------------------+ | |
| | | + WriteVersions(aVersions) | | |
| | | + WriteModified(aModified, aTimeStamp) | | |
| | | + WriteRange(aRange) | | |
| | | + WriteOperation(anOperation) | | |
| | | + StartBody(aCount) | | |
| | | + FinishBody | | |
| | | + WriteBodyElement(aKey, aValue) | | |
| | +-------------------------------------------------------------+ | |
| +-----------------------------------------------------------------+ |
| |
| +-----------------------------------------------------------------+ |
| | Tm3PlainAttrIndexDumper (читатель) | |
| | +-------------------------------------------------------------+ | |
| | | - f_Header : Tm3AttrIndexWriterHeader | | |
| | | - f_FileName : TFileName | | |
| | | - f_Stream : Tl3Stream | | |
| | | - f_SearchMode : Tm3SearchMode | | |
| | | - f_Sequential : Boolean | | |
| | +-------------------------------------------------------------+ | |
| | | + ModifiedDocuments : Il3RangeEnumerable | | |
| | | + IndexedVersions : Im3IndexedVersions | | |
| | | + Range : Tm3IDRange | | |
| | | + TimeStamp : TDateTime | | |
| | | + Count : Integer | | |
| | | + ValuesByKey(aKey) : Il3RangeEnumerable | | |
| | | + GetEnumerator : Im3AttrIndexElementEnumerator | | |
| | +-------------------------------------------------------------+ | |
| +-----------------------------------------------------------------+ |
| |
+-----------------------------------------------------------------------+
4. ЛОГИКА ПОИСКА ValuesByKey
+-----------------------------------------------------------------------+
| |
| +-----------------------------------------------------------------+ |
| | if (aKey < MinKeyID) or (aKey > MaxKeyID) then | |
| | Result := nil | |
| | Exit | |
| | | |
| | if SearchMode = m3_smSeq then | |
| | // последовательный перебор | |
| | while Enumerator.MoveNext do | |
| | if ID = aKey then | |
| | Result := Values | |
| | Exit | |
| | | |
| | if Sequential then | |
| | // прямой доступ по индексу | |
| | Pos := (aKey - MinKeyID) * SizeOf(Element) | |
| | ReadElement | |
| | ElementToResult | |
| | | |
| | else | |
| | // бинарный поиск | |
| | L := 0; H := Count - 1 | |
| | while L <= H do | |
| | i := (L + H) shr 1 | |
| | ReadElement | |
| | if Element.Key < aKey then | |
| | L := i + 1 | |
| | else if Element.Key > aKey then | |
| | H := i - 1 | |
| | else | |
| | ElementToResult | |
| | Exit | |
| | | |
| +-----------------------------------------------------------------+ |
| |
+-----------------------------------------------------------------------+
5. ФОРМАТЫ СЕРИАЛИЗАЦИИ
+-----------------------------------------------------------------------+
| |
| +-----------------------------------------------------------------+ |
| | Одиночное значение (m3_etSingle) | |
| | rValue = ID | |
| +-----------------------------------------------------------------+ |
| | | |
| | Диапазон (m3_etRange) | |
| | rValue = (rLow shl 32) or rHigh (Tm3IDRange) | |
| +-----------------------------------------------------------------+ |
| | | |
| | Список значений (m3_etMultiply / m3_etZLib / m3_etLZO) | |
| | rValue = смещение на Size + Data | |
| | [Size] Int64 | |
| | [Data] Il3RangeEnumerable | |
| +-----------------------------------------------------------------+ |
| |
+-----------------------------------------------------------------------+
6. КОНСТАНТЫ
+-----------------------------------------------------------------------+
| |
| c_m3AttrIndexWriterGUID = '{2020CBAD-78CC-494B-84B0-2EF18ADEA65A}' |
| cSequentialVersion = 2 |
| cOurVersion = 2 |
| cSignature = 1400951 |
| |
+-----------------------------------------------------------------------+
*]
*)
//#UC END# *69AC2E42033DforDiagramm*
end.
Заметки о тестировании, программировании и прочий "поток сознания", который жалко писать "в стол"
воскресенье, 12 апреля 2026 г.
m3AttrIndexWriter
Подписаться на:
Комментарии к сообщению (Atom)
Комментариев нет:
Отправить комментарий