{$IfDef FPC}{$CodePage cp1251}{$EndIf FPC}
unit m3AttrIndexDumper;
// --------------------------------------------------------------------------
// Родители: "Attributes" <> MUID: (667D35D300BC) :: "m3" <> MUID: (548712F60101) :: "Shared Delphi Low Level" <> MUID: (4ABCC25A0322)
// --------------------------------------------------------------------------
// Модуль: "w:\common\components\rtl\Garant\m3\m3AttrIndexDumper.pas" GeneratorVersion: 1.0.0.883901
// Стереотип: "<>"
// Элемент модели: "Tm3AttrIndexDumper" MUID: (667D594C030C)
// --------------------------------------------------------------------------
//#UC START# *667D594C030CbeforeDefines*
//#UC END# *667D594C030CbeforeDefines*
{$Include m3Define.inc}
interface
uses
l3IntfUses
, m3IndexDumper
, m3SearcherInterfaces
, l3CoreInterfaces
, l3Types
, SysUtils
, m3StorageInterfaces
, l3Ranges
;
type
Tm3AttrIndexDumper = class(Tm3IndexDumper, Im3AttrIndexDumper)
private
f_Operation: Tm3GroupOperation;
f_Count: Integer;
f_SearchMode: Tm3SearchMode;
protected
function pm_GetFirst: Il3RangeEnumerable;
function pm_GetLast: Il3RangeEnumerable;
function pm_GetCount: Integer;
function ValuesByKey(aKey: Integer): Il3RangeEnumerable;
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;
public
constructor Create(const anIndexName: AnsiString); reintroduce; overload;
class function MakePrim(const anIndexName: AnsiString): Im3AttrIndexDumper; reintroduce;
class procedure MakeCopyFromDumper(var aDumper: Im3AttrIndexDumper;
const aCopyName: Il3CString;
aWriteVersions: Boolean;
aFilesMeter: Tl3ProgressProc;
const aBaseName: TFileName;
aIsDirect: Boolean);
{* Утилитный метод для копирования индексов. }
class function Make(const anIndexName: AnsiString): Im3AttrIndexDumper;
constructor Create(const anIndex: Im3IndexedStorage); reintroduce; overload;
{$If NOT Defined(l3NoSRT)}
function SetRefTo(var thePlace: Tm3AttrIndexDumper): 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;
{* Число элементов. }
end;//Tm3AttrIndexDumper
implementation
uses
l3ImplUses
, Im3AttrIndexElementList
, m3AttrIndexElement
{$If NOT Defined(NoScripts)}
, TtfwTypeRegistrator_Proxy
{$IfEnd} // NOT Defined(NoScripts)
{$If NOT Defined(NoScripts)}
, TtfwClassRef_Proxy
{$IfEnd} // NOT Defined(NoScripts)
//#UC START# *667D594C030Cimpl_uses*
//, SysUtils
{$IfNDef FPC}
, Windows
{$EndIf FPC}
, m3stgmgr
//, m3StorageInterfaces
, l3Interfaces
, l3StringsEnumerator
, l3StoreInterfaces
, l3Date
, l3Base
, l3FileUtils
, l3SysUtils
, l3BaseStream
, m3StorageTools
, l3String
, m2HASLib
, m2COMLib
, m3IndexerTypes
, m3IndexConst
, m3DBTools
, m3ProxyIndexStream
, m3StorageService
, m3AttrIndexWriter
, m3DocumentAttrIndexBuilder // Для g_UseNewIndexesOnly
, m3IndexElements
//#UC END# *667D594C030Cimpl_uses*
;
constructor Tm3AttrIndexDumper.Create(const anIndexName: AnsiString);
//#UC START# *68E135A302D3_667D594C030C_var*
//#UC END# *68E135A302D3_667D594C030C_var*
begin
//#UC START# *68E135A302D3_667D594C030C_impl*
f_Operation := m3_gopNone;
f_Count := -1;
inherited Create(anIndexName);
//#UC END# *68E135A302D3_667D594C030C_impl*
end;//Tm3AttrIndexDumper.Create
class function Tm3AttrIndexDumper.MakePrim(const anIndexName: AnsiString): Im3AttrIndexDumper;
var
l_Inst : Tm3AttrIndexDumper;
begin
l_Inst := Create(anIndexName);
try
Result := l_Inst;
finally
l_Inst.Free;
end;//try..finally
end;//Tm3AttrIndexDumper.MakePrim
class procedure Tm3AttrIndexDumper.MakeCopyFromDumper(var aDumper: Im3AttrIndexDumper;
const aCopyName: Il3CString;
aWriteVersions: Boolean;
aFilesMeter: Tl3ProgressProc;
const aBaseName: TFileName;
aIsDirect: Boolean);
{* Утилитный метод для копирования индексов. }
//#UC START# *671A1493028D_667D594C030C_var*
var
l_UpdateName : String;
procedure DoWrite;
var
l_OutHash : Im3IndexedStorage;
l_Start : Cardinal;
function DoElement(const anElement: Im3AttrIndexElement): Boolean;
const
cTimeDelta = 20 * 60 * 1000;
var
l_St : Il3Stream;
l_N : AnsiString;
l_TimeDelta : Int64;
begin//DoElement
Result := true;
if Assigned(aFilesMeter) then
if (anElement.ID >= 0) then
aFilesMeter(piCurrent, anElement.ID, '');
if (l_OutHash <> nil) then
begin
if (anElement.ID < 0) then
begin
l_N := l3CCP(IntToStr(anElement.ID));
l_St := m3COMOpenStream(l_OutHash,
l3PCharLen(l_N),
m3_saWrite,
true,
true{false});
end//anElement.ID < 0
else
l_St := m3COMOpenStream(l_OutHash,
anElement.ID,
m3_saWrite,
true,
true{false});
try
if (l_St <> nil) then
Il3RangeEnumerable_WriteTo(anElement.Values, l_St.As_IStream);
finally
l_St := nil;
end;//try..finally
end;//l_OutHash <> nil
l_TimeDelta := cTimeDelta;
{$IfNDef nsTest}
if (l3Date.DayOfWeek(SysUtils.Date) <> l3Date.Sunday)
AND (l3Date.DayOfWeek(SysUtils.Date) <> l3Date.Saturday) then
begin
l_TimeDelta := cTimeDelta div 2;
if (l_TimeDelta <= 1000) then
l_TimeDelta := cTimeDelta;
end;//l3Date.DayOfWeek(SysUtils.Date) <> l3Date.Sunday
{$EndIf nsTest}
if l3IsTimeElapsed(l_Start, l_TimeDelta) then
begin
// - здесь будем новые дельты строить
if (aBaseName <> '') then
begin
l3System.Msg2Log('Здесь будем новые дельты строить');
m3DBBuildIndexDelta(aBaseName, nil, true, false{aForceFullIndex});
l3System.Msg2Log('Закончили строить новые дельты');
end;//aBaseName <> ''
l_Start := GetTickCount;
// - новая точка отсчёта
end;//l3IsTimeElapsed(l_Start, l_TimeDelta)
end;//DoElement
var
l_OutIndex: Im3IndexedStorage;
l_Writer : Tm3AttrIndexWriter;
procedure WriteRange;
var
l_St : Il3Stream;
l_Range : Tm3IDRange;
begin//WriteRange
if (l_Writer <> nil) then
begin
l_Range := aDumper.Range;
l_Writer.WriteRange(l_Range);
end;//l_Writer <> nil
if (l_OutIndex <> nil) then
begin
l_St := m3COMOpenStream(l_OutIndex,
l3PCharLen('range'),
m3_saWrite,
true,
false);
try
if (l_St <> nil) then
begin
l_Range := aDumper.Range;
l_Range.WriteTo(l_St.As_IStream);
end;//l_St <> nil
finally
l_St := nil;
end;//try..finally
end;//l_OutIndex <> nil
end;//WriteRange
procedure WriteOperation;
var
l_St : Il3Stream;
l_S : IStream;
l_Op : Tm3GroupOperation;
begin//WriteOperation
l_Op := aDumper.Operation;
if (l_Writer <> nil) then
l_Writer.WriteOperation(l_Op);
if (l_OutIndex <> nil) then
begin
l_St := m3COMOpenStream(l_OutIndex,
l3PCharLen('operation'),
m3_saWrite,
true,
false);
try
if (l_St <> nil) then
begin
l_S := l_St.As_IStream;
m2COMWriteBuffer(l_S, l_Op, SizeOf(l_Op));
end;//l_St <> nil
finally
l_St := nil;
end;//try..finally
end;//l_OutIndex <> nil
end;//WriteOperation
{$IfDef m3UseProxyIndexStream}
{$Define m3LocUseProxyIndexStream}
{$EndIf m3UseProxyIndexStream}
var
l_Enum : Im3AttrIndexElementEnumerator;
l_MaxKeyID : Integer;
{$IfDef m3LocUseProxyIndexStream}
l_Temp : Tl3Stream;
l_H : Im3StorageHolder;
{$EndIf m3LocUseProxyIndexStream}
l_Capacity : Integer;
l_pCurrent : Im3AttrIndexElementEnumerator_PCurrentItemType;
begin//DoWrite
l_Capacity := 0;
l_Writer := nil;
try
{$IfDef m3LocUseProxyIndexStream}
if g_UseNewIndexesOnly then
begin
l_Temp := Tm3ProxyIndexStream.Create(l_UpdateName);
try
l_Writer := Tm3AttrIndexWriter.Create(l_Temp, aIsDirect);
finally
FreeAndNil(l_Temp);
end;//try..finally
end//g_UseNewIndexesOnly
else
if not Tm3StorageService.Instance.UseSplitted then
begin
l_Temp := Tm3ProxyIndexStream.Create(l_UpdateName);
try
l_H := Tm3FullModeExclusiveStorageManager.MakeInterface(l_Temp, c_m3UseVersionedIndexDeltas, def_FullModeStorageUseCompression);
try
l_OutIndex := l_H.Storage;
finally
l_H := nil;
end;//try..finally
finally
FreeAndNil(l_Temp);
end;//try..finally
end//not Tm3StorageService.Instance.UseSplitted
else
l_OutIndex := Tm3FullModeExclusiveStorageManager.MakeInterface(l_UpdateName, c_m3UseVersionedIndexDeltas);
{$Else m3LocUseProxyIndexStream}
l_OutIndex := Tm3FullModeExclusiveStorageManager.MakeInterface(l_UpdateName, c_m3UseVersionedIndexDeltas);
{$EndIf m3LocUseProxyIndexStream}
try
{$IfNDef m3UseVersionedIndexDeltas}
l_OutIndex.ClearAll;
{$EndIf m3UseVersionedIndexDeltas}
l_MaxKeyID := aDumper.MaxKeyID;
if Assigned(aFilesMeter) then
aFilesMeter(piStart, l_MaxKeyID, 'Обновление индекса: ' + ExtractFileName(l_UpdateName));
//aFilesMeter(piStart, Cm2HASDefCount, 'Обновление индекса');
try
if Assigned(aFilesMeter) then
aFilesMeter(piCurrent, 0, 'Запись списка документов');
if (l_Writer <> nil) then
l_Writer.WriteModified(aDumper.ModifiedDocuments, aDumper.TimeStamp);
if (l_OutIndex <> nil) then
m3WriteModified(l_OutIndex, aDumper.ModifiedDocuments, aDumper.TimeStamp);
if aWriteVersions then
begin
if Assigned(aFilesMeter) then
aFilesMeter(piCurrent, 0, 'Запись версий документов');
if (l_Writer <> nil) then
l_Writer.WriteVersions(aDumper.IndexedVersions);
if (l_OutIndex <> nil) then
m3WriteVersions(l_OutIndex, aDumper.IndexedVersions);
end;//aWriteVersions
WriteRange;
WriteOperation;
if (l_Writer <> nil) then
begin
if Assigned(aFilesMeter) then
aFilesMeter(piCurrent, 0, 'Обновление индекса (вычисление Capacity): ' + ExtractFileName(l_UpdateName));
l_Capacity := aDumper.Count;
(* l_Enum := aDumper.GetEnumerator;
Assert(l_Enum <> nil);
l_Capacity := 0;
while l_Enum.MoveNext do
Inc(l_Capacity);*)
if Assigned(aFilesMeter) then
aFilesMeter(piCurrent, 0, 'Обновление индекса: ' + ExtractFileName(l_UpdateName));
l_Writer.StartBody(l_Capacity);
try
l_Enum := aDumper.GetEnumerator;
Assert(l_Enum <> nil);
while l_Enum.MoveNext do
begin
l_pCurrent := l_Enum.pCurrent;
Assert(l_pCurrent <> nil);
if Assigned(aFilesMeter) then
if (l_pCurrent.ID >= 0) then
aFilesMeter(piCurrent, l_pCurrent.ID, '');
l_Writer.WriteBodyElement(l_pCurrent.ID, l_pCurrent.Values);
end;//while l_Enum.MoveNext
finally
l_Writer.FinishBody;
end;//try..finally
end;//l_Writer <> nil
if (l_OutIndex <> nil) then
begin
l_OutHash := m3COMOpenStorage(l_OutIndex,
l3PCharLen(AnsiString(m3HashDataName)),
m3_saReadWrite,
true);
if (l_OutHash <> nil) then
if (l_MaxKeyID <= 32767) then
l_OutHash.SetIndexParam(16, 16);
// - MaxElementID тут возможно прикрутить
try
l_OutIndex := nil; // - типа можно отпустить
if Assigned(aFilesMeter) then
aFilesMeter(piCurrent, 0, 'Обновление индекса: ' + ExtractFileName(l_UpdateName));
l_Enum := aDumper.GetEnumerator;
aDumper := nil;
// - типа можно отпустить
try
l_Start := GetTickCount;
Assert(l_Enum <> nil);
while l_Enum.MoveNext do
if not DoElement(l_Enum.Current) then
break;
finally
l_Enum := nil;
end;//try..finally
finally
l_OutHash := nil;
end;//try..finally
end;//l_OutIndex <> nil
finally
if Assigned(aFilesMeter) then
aFilesMeter(piEnd, 0, '');
end;//try..finally
finally
l_OutIndex := nil;
end;//try..finally
finally
FreeAndNil(l_Writer);
end;//try..finally
end;//DoWrite
var
l_UpdateNameBak : String;
//#UC END# *671A1493028D_667D594C030C_var*
begin
//#UC START# *671A1493028D_667D594C030C_impl*
l_UpdateName := Il3CString_ToFileName(aCopyName);
if Tm3StorageManager.StorageFileExists(l_UpdateName) then
begin
l_UpdateNameBak := l_UpdateName + cBackExt;
Tm3StorageManager.DeleteStorageFile(l_UpdateNameBak);
Tm3StorageManager.RenameStorageFile(l_UpdateName, l_UpdateNameBak);
end;//Tm3StorageManager.StorageFileExists(l_UpdateName)
DoWrite;
//#UC END# *671A1493028D_667D594C030C_impl*
end;//Tm3AttrIndexDumper.MakeCopyFromDumper
class function Tm3AttrIndexDumper.Make(const anIndexName: AnsiString): Im3AttrIndexDumper;
//#UC START# *66A21BA9035E_667D594C030C_var*
function CheckStorage: Boolean;
var
l_S : Im3IndexedStorage;
l_SS : Im3IndexedStorage;
l_E : Il3StringsEnumerable;
begin
Result := false;
l_S := Tm3ConstantStorageManager.MakeInterface(anIndexName);
try
if (l_S = nil) then
Exit;
if l3IOk(m3COMSafeOpenStorage(l_S,
l3PCharLen(AnsiString(m3HashDataName)),
m3_saRead,
false,
l_SS)) then
try
l_S := nil;
if (l_SS.MaxElementID < 0) then
begin
l_E := l_SS.TOCEnumerable;
if (l_E = nil) then
Exit;
if l_E.Empty then
Exit;
// - а иначе у нас наверное есть неиндексные элементы
// например отрицательные номера
end;//l_SS.MaxElementID < 0
Result := true;
finally
l_SS := nil;
end;//try..finally
finally
l_S := nil;
end;//try..finally
end;//CheckStorage
var
l_D : Tm3AttrIndexDumper;
//#UC END# *66A21BA9035E_667D594C030C_var*
begin
//#UC START# *66A21BA9035E_667D594C030C_impl*
if (anIndexName = '') then
begin
l_D := Create(nil);
try
Result := l_D;
finally
FreeAndNil(l_D);
end;//try..finally
end//anIndexName = ''
else
if Tm3StorageManager.StorageFileExists(anIndexName) then
begin
if Tm3PlainAttrIndexDumper.TryMake(anIndexName, Result) then
// - пробуем открыть индекс "новой системы".
Exit;
if CheckStorage then
Result := MakePrim(anIndexName)
else
begin
l_D := Create(nil);
try
Result := l_D;
finally
FreeAndNil(l_D);
end;//try..finally
end;//CheckStorage
end//Tm3StorageManager.StorageFileExists(anIndexName)
else
Result := nil;
//#UC END# *66A21BA9035E_667D594C030C_impl*
end;//Tm3AttrIndexDumper.Make
constructor Tm3AttrIndexDumper.Create(const anIndex: Im3IndexedStorage);
//#UC START# *68E13E0402B4_667D594C030C_var*
//#UC END# *68E13E0402B4_667D594C030C_var*
begin
//#UC START# *68E13E0402B4_667D594C030C_impl*
f_Operation := m3_gopNone;
f_Count := -1;
inherited Create(anIndex);
//#UC END# *68E13E0402B4_667D594C030C_impl*
end;//Tm3AttrIndexDumper.Create
{$If NOT Defined(l3NoSRT)}
function Tm3AttrIndexDumper.SetRefTo(var thePlace: Tm3AttrIndexDumper): Boolean;
begin
if (thePlace = Self) then
Result := false
else
begin
Result := true;
thePlace.Free;
thePlace := Self.Use;
end;//thePlace = Self
end;//Tm3AttrIndexDumper.SetRefTo
{$IfEnd} // NOT Defined(l3NoSRT)
function Tm3AttrIndexDumper.pm_GetFirst: Il3RangeEnumerable;
//#UC START# *47D8233603DD_667D594C030Cget_var*
//#UC END# *47D8233603DD_667D594C030Cget_var*
begin
//#UC START# *47D8233603DD_667D594C030Cget_impl*
Result := nil;
l3NI;
//#UC END# *47D8233603DD_667D594C030Cget_impl*
end;//Tm3AttrIndexDumper.pm_GetFirst
function Tm3AttrIndexDumper.pm_GetLast: Il3RangeEnumerable;
//#UC START# *47D823570315_667D594C030Cget_var*
//#UC END# *47D823570315_667D594C030Cget_var*
begin
//#UC START# *47D823570315_667D594C030Cget_impl*
Result := nil;
l3NI;
//#UC END# *47D823570315_667D594C030Cget_impl*
end;//Tm3AttrIndexDumper.pm_GetLast
function Tm3AttrIndexDumper.pm_GetCount: Integer;
//#UC START# *4BB08B8902F2_667D594C030Cget_var*
var
l_It : Im3AttrIndexElementEnumerator;
//#UC END# *4BB08B8902F2_667D594C030Cget_var*
begin
//#UC START# *4BB08B8902F2_667D594C030Cget_impl*
if (f_Count < 0) then
begin
f_Count := 0;
l_It := Self.GetEnumerator;
if (l_It <> nil) then
while l_It.MoveNext do
Inc(f_Count);
end;//f_Count < 0
Result := f_Count;
//#UC END# *4BB08B8902F2_667D594C030Cget_impl*
end;//Tm3AttrIndexDumper.pm_GetCount
function Tm3AttrIndexDumper.ValuesByKey(aKey: Integer): Il3RangeEnumerable;
//#UC START# *66B4B9740318_667D594C030C_var*
var
l_InHash : Im3IndexedStorage;
l_Stream : Il3Stream;
l_N : AnsiString;
//#UC END# *66B4B9740318_667D594C030C_var*
begin
//#UC START# *66B4B9740318_667D594C030C_impl*
Result := nil;
if (f_Index <> nil) then
begin
if l3IOk(m3COMSafeOpenStorage(f_Index,
l3PCharLen(AnsiString(m3HashDataName)),
m3_saRead,
false,
l_InHash)) then
try
if (l_InHash <> nil) then
begin
if (aKey < 0) then
begin
l_N := l3CCP(IntToStr(aKey));
m3COMSafeOpenStream(l_InHash, l3PCharLen(l_N), m3_saRead, false, l_Stream);
end//aKey < 0
else
m3COMSafeOpenStream(l_InHash, aKey, m3_saRead, false, l_Stream);
try
Result := Il3RangeEnumerable_CreateFromStream(l_Stream);
finally
l_Stream := nil;
end;//try..finally
end;//l_InHash <> nil
finally
l_InHash := nil;
end;//try..finally
end;//f_Index <> nil
//#UC END# *66B4B9740318_667D594C030C_impl*
end;//Tm3AttrIndexDumper.ValuesByKey
function Tm3AttrIndexDumper.Get_MaxKeyID: Integer;
//#UC START# *671D18210090_667D594C030Cget_var*
var
l_InHash : Im3IndexedStorage;
//#UC END# *671D18210090_667D594C030Cget_var*
begin
//#UC START# *671D18210090_667D594C030Cget_impl*
Result := 0;
if (f_Index <> nil) then
begin
if l3IOk(m3COMSafeOpenStorage(f_Index,
l3PCharLen(AnsiString(m3HashDataName)),
m3_saRead,
false,
l_InHash)) then
try
if (l_InHash <> nil) then
begin
Result := l_InHash.MaxElementID;
end;//l_InHash <> nil
finally
l_InHash := nil;
end;//try..finally
end;//f_Index <> nil
//#UC END# *671D18210090_667D594C030Cget_impl*
end;//Tm3AttrIndexDumper.Get_MaxKeyID
function Tm3AttrIndexDumper.Get_Operation: Tm3GroupOperation;
//#UC START# *68E135160346_667D594C030Cget_var*
var
l_St : Il3Stream;
l_S : IStream;
//#UC END# *68E135160346_667D594C030Cget_var*
begin
//#UC START# *68E135160346_667D594C030Cget_impl*
if (f_Operation = m3_gopNone) then
begin
if (f_Index = nil) then
f_Operation := m3_gopSet
else
begin
l_St := m3COMOpenStream(f_Index,
l3PCharLen('operation'),
m3_saRead,
false,
false);
try
if (l_St = nil) then
f_Operation := m3_gopSet
else
begin
l_S := l_St.As_IStream;
m2COMReadBuffer(l_S, f_Operation, SizeOf(f_Operation));
l_S := nil;
end;//l_St <> nil
finally
l_St := nil;
end;//try..finally
end;//f_Index = nil
end;//f_Operation = m3_gopNone
Result := f_Operation;
//#UC END# *68E135160346_667D594C030Cget_impl*
end;//Tm3AttrIndexDumper.Get_Operation
function Tm3AttrIndexDumper.Get_MinKeyID: Integer;
//#UC START# *69B14AAE0155_667D594C030Cget_var*
//#UC END# *69B14AAE0155_667D594C030Cget_var*
begin
//#UC START# *69B14AAE0155_667D594C030Cget_impl*
Result := 0;
l3NI; // - можно потом вычислить, если понадобится
// (+) L2Mm3StorageIteratorsIterateAllFAction (+) TOCEnumerable
//#UC END# *69B14AAE0155_667D594C030Cget_impl*
end;//Tm3AttrIndexDumper.Get_MinKeyID
procedure Tm3AttrIndexDumper.Set_SearchMode(aValue: Tm3SearchMode);
//#UC START# *69BBB8A101BA_667D594C030Cset_var*
//#UC END# *69BBB8A101BA_667D594C030Cset_var*
begin
//#UC START# *69BBB8A101BA_667D594C030Cset_impl*
f_SearchMode := aValue;
//#UC END# *69BBB8A101BA_667D594C030Cset_impl*
end;//Tm3AttrIndexDumper.Set_SearchMode
function Tm3AttrIndexDumper.Get_Sequential: Boolean;
//#UC START# *69C1D45B01E5_667D594C030Cget_var*
//#UC END# *69C1D45B01E5_667D594C030Cget_var*
begin
//#UC START# *69C1D45B01E5_667D594C030Cget_impl*
Result := false;
// - нет у нас такой информации
//#UC END# *69C1D45B01E5_667D594C030Cget_impl*
end;//Tm3AttrIndexDumper.Get_Sequential
function Tm3AttrIndexDumper.ToTheLeftOf(const anOther: Im3AttrIndexDumper): Boolean;
//#UC START# *69C1DE0300B2_667D594C030C_var*
//#UC END# *69C1DE0300B2_667D594C030C_var*
begin
//#UC START# *69C1DE0300B2_667D594C030C_impl*
Result := (Self.Get_MaxKeyID < anOther.MinKeyID);
//#UC END# *69C1DE0300B2_667D594C030C_impl*
end;//Tm3AttrIndexDumper.ToTheLeftOf
function Tm3AttrIndexDumper.GetEnumerator: Im3AttrIndexElementEnumerator;
{* Получает Enumerator для перебора элементов "контейнера".
Вся эта конструкция совместима с "синтаксическим сахаром" вида:
for Item in Container do Process(Item);
Который поддерживается в "новых" Delphi.
См. http://mdp.garant.ru/pages/viewpage.action?pageId=152961307 }
//#UC START# *5AB8C6B0003A_667D594C030C_var*
var
l_List : TIm3AttrIndexElementList;
l_InHash : Im3IndexedStorage;
function DoHash(const aStoreInfo : Tm3StorageElementInfo): Boolean;
var
l_N : AnsiString;
l_Index : Integer;
l_E : Im3AttrIndexElement;
begin//DoHash
Result := true;
if (aStoreInfo.rIndex >= 0) then
begin
l_E := Tm3AttrIndexElement.Make(aStoreInfo.rIndex, l_InHash, aStoreInfo);
l_List.Add(l_E);
end//aStoreInfo.rIndex >= 0
else
begin
l_N := aStoreInfo.rName.AsString;
if (l_N[1] = '-') then
begin
if TryStrToInt(l_N, l_Index) then
begin
if (l_Index < 0) then
begin
l_E := Tm3AttrIndexElement.Make(l_Index, l_InHash, aStoreInfo);
l_List.Add(l_E);
end;//l_Index < 0
end;//TryStrToInt(l_N, l_Index)
end;//l_N[1] = '-'
end;//aStoreInfo.rIndex >= 0
end;//DoHash
(* function DoHash(const aStoreInfo: Tm3StoreInfo; anIndex: Integer): Boolean;
begin//DoHash
Result := true;
l_List.Add(Tm3AttrIndexElement.Make(anIndex, l_InHash, aStoreInfo));
end;//DoHash*)
//#UC END# *5AB8C6B0003A_667D594C030C_var*
begin
//#UC START# *5AB8C6B0003A_667D594C030C_impl*
Result := nil;
l_List := TIm3AttrIndexElementList.CreateSorted;
try
if (f_Index <> nil) then
begin
if l3IOk(m3COMSafeOpenStorage(f_Index,
l3PCharLen(AnsiString(m3HashDataName)),
m3_saRead,
false,
l_InHash)) then
try
if (l_InHash <> nil) then
begin
l_InHash.IterateAllF(L2Mm3StorageIteratorsIterateAllFAction(@DoHash));
//l_InHash.IterateIndexedF(L2Mm3StorageIteratorsIterateIndexedFAction(@DoHash), 0);
end;//l_InHash <> nil
finally
l_InHash := nil;
end;//try..finally
end;//f_Index <> nil
Result := l_List.GetEnumerator;
finally
FreeAndNil(l_List);
end;//try..finally
//#UC END# *5AB8C6B0003A_667D594C030C_impl*
end;//Tm3AttrIndexDumper.GetEnumerator
initialization
{$If NOT Defined(NoScripts)}
TtfwClassRef_Proxy.TtfwClassRef.Register(TypeInfo(Tm3AttrIndexDumper));
{$IfEnd} // NOT Defined(NoScripts)
//#UC START# *667D594C030CforDiagramm*
(*
*)
//#UC END# *667D594C030CforDiagramm*
end.
Заметки о тестировании, программировании и прочий "поток сознания", который жалко писать "в стол"
воскресенье, 12 апреля 2026 г.
m3AttrIndexDumper
Подписаться на:
Комментарии к сообщению (Atom)
Комментариев нет:
Отправить комментарий