|
@@ -21,32 +21,29 @@
|
|
unit HTMLIndexer;
|
|
unit HTMLIndexer;
|
|
{$MODE OBJFPC}{$H+}
|
|
{$MODE OBJFPC}{$H+}
|
|
interface
|
|
interface
|
|
-uses Classes, SysUtils, FastHTMLParser;
|
|
|
|
|
|
+uses Classes, SysUtils, FastHTMLParser,avl_tree;
|
|
|
|
|
|
Type
|
|
Type
|
|
-
|
|
|
|
- { TIndexedWord }
|
|
|
|
-
|
|
|
|
{ TIndexDocument }
|
|
{ TIndexDocument }
|
|
-
|
|
|
|
TIndexDocument = class(TObject)
|
|
TIndexDocument = class(TObject)
|
|
private
|
|
private
|
|
FDocumentIndex: Integer;
|
|
FDocumentIndex: Integer;
|
|
- public
|
|
|
|
|
|
+ FLastEntry : Integer;
|
|
WordIndex: array of Integer;
|
|
WordIndex: array of Integer;
|
|
|
|
+ function getindexentries:integer;
|
|
|
|
+ public
|
|
|
|
+ function GetWordIndex(i:integer):integer; inline;
|
|
procedure AddWordIndex(AIndex: Integer);
|
|
procedure AddWordIndex(AIndex: Integer);
|
|
constructor Create(ADocumentIndex: Integer);
|
|
constructor Create(ADocumentIndex: Integer);
|
|
property DocumentIndex: Integer read FDocumentIndex;
|
|
property DocumentIndex: Integer read FDocumentIndex;
|
|
|
|
+ property IndexEntry[i:integer] : Integer read GetWordIndex;
|
|
|
|
+ property NumberofIndexEntries : integer read getindexentries;
|
|
end;
|
|
end;
|
|
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-
|
|
|
|
|
|
+ { TIndexedWord }
|
|
TIndexedWord = class(TObject)
|
|
TIndexedWord = class(TObject)
|
|
private
|
|
private
|
|
FIsTitle: Boolean;
|
|
FIsTitle: Boolean;
|
|
- FNextWord: TIndexedWord;
|
|
|
|
- FPrevWord: TIndexedWord;
|
|
|
|
FTheWord: string;
|
|
FTheWord: string;
|
|
FCachedTopic: TIndexDocument;
|
|
FCachedTopic: TIndexDocument;
|
|
FDocuments: Array of TIndexDocument;
|
|
FDocuments: Array of TIndexDocument;
|
|
@@ -56,16 +53,16 @@ Type
|
|
constructor Create(AWord: String; AIsTitle: Boolean);
|
|
constructor Create(AWord: String; AIsTitle: Boolean);
|
|
destructor Destroy; override;
|
|
destructor Destroy; override;
|
|
function GetLogicalDocument(AIndex: Integer): TIndexDocument;
|
|
function GetLogicalDocument(AIndex: Integer): TIndexDocument;
|
|
- property TheWord: string read FTheWord; // Always lowercase
|
|
|
|
- property PrevWord: TIndexedWord read FPrevWord write FPrevWord;
|
|
|
|
- property NextWord: TIndexedWord read FNextWord write FNextWord;
|
|
|
|
|
|
+ property TheWord: string read FTheWord write ftheword; // Always lowercase
|
|
property DocumentTopic[TopicIndexNum: Integer]: TIndexDocument read GetDocument;
|
|
property DocumentTopic[TopicIndexNum: Integer]: TIndexDocument read GetDocument;
|
|
property DocumentCount: Integer read GetDocumentCount;
|
|
property DocumentCount: Integer read GetDocumentCount;
|
|
- property IsTitle: Boolean read FIsTitle;
|
|
|
|
|
|
+ property IsTitle: Boolean read FIsTitle write fistitle;
|
|
end;
|
|
end;
|
|
|
|
|
|
{ TIndexedWordList }
|
|
{ TIndexedWordList }
|
|
|
|
|
|
|
|
+ TForEachMethod = procedure (AWord:TIndexedWord) of object;
|
|
|
|
+ TForEachProcedure = Procedure (AWord:TIndexedWord;state:pointer);
|
|
TIndexedWordList = class(TObject)
|
|
TIndexedWordList = class(TObject)
|
|
private
|
|
private
|
|
FIndexTitlesOnly: Boolean;
|
|
FIndexTitlesOnly: Boolean;
|
|
@@ -82,13 +79,10 @@ Type
|
|
FTotalWordCount: DWord;
|
|
FTotalWordCount: DWord;
|
|
FTotalWordLength: DWord;
|
|
FTotalWordLength: DWord;
|
|
FLongestWord: DWord;
|
|
FLongestWord: DWord;
|
|
- FFirstWord: TIndexedWord;
|
|
|
|
- FCachedWord: TIndexedWord;
|
|
|
|
FParser: THTMLParser;
|
|
FParser: THTMLParser;
|
|
|
|
+ FAVLTree : TAVLTree;
|
|
|
|
+ Spare :TIndexedWord;
|
|
function AddGetWord(AWord: String; IsTitle: Boolean): TIndexedWord;
|
|
function AddGetWord(AWord: String; IsTitle: Boolean): TIndexedWord;
|
|
- function GetWordForward(AWord: String; StartWord: TIndexedWord; out WrongWord: TIndexedWord; AIsTitle: Boolean): TIndexedWord;
|
|
|
|
- function GetWordBackward(AWord: String; StartWord: TIndexedWord; out WrongWord: TIndexedWord; AIsTitle: Boolean): TIndexedWord;
|
|
|
|
- function CompareWord(AWord: String; AIndexWord: TIndexedWord; AIsTitle: Boolean): Integer;
|
|
|
|
// callbacks
|
|
// callbacks
|
|
procedure CBFoundTag(NoCaseTag, ActualTag: string);
|
|
procedure CBFoundTag(NoCaseTag, ActualTag: string);
|
|
procedure CBFountText(Text: string);
|
|
procedure CBFountText(Text: string);
|
|
@@ -99,8 +93,9 @@ Type
|
|
destructor Destroy; override;
|
|
destructor Destroy; override;
|
|
function IndexFile(AStream: TStream; ATOPICIndex: Integer; AIndexOnlyTitles: Boolean): String; // returns the documents <Title>
|
|
function IndexFile(AStream: TStream; ATOPICIndex: Integer; AIndexOnlyTitles: Boolean): String; // returns the documents <Title>
|
|
procedure Clear;
|
|
procedure Clear;
|
|
- procedure AddWord(const AWord: TIndexedWord; StartingWord: TIndexedWord; AIsTitle: Boolean);
|
|
|
|
- property FirstWord: TIndexedWord read FFirstWord;
|
|
|
|
|
|
+ procedure AddWord(const AWord: TIndexedWord);
|
|
|
|
+ procedure ForEach(Proc:TForEachMethod);
|
|
|
|
+ procedure ForEach(Proc:TForEachProcedure;state:pointer);
|
|
property IndexedFileCount: DWord read FIndexedFileCount;
|
|
property IndexedFileCount: DWord read FIndexedFileCount;
|
|
property LongestWord: DWord read FLongestWord;
|
|
property LongestWord: DWord read FLongestWord;
|
|
property TotalWordCount: DWord read FTotalWordCount;
|
|
property TotalWordCount: DWord read FTotalWordCount;
|
|
@@ -112,6 +107,8 @@ Type
|
|
|
|
|
|
implementation
|
|
implementation
|
|
|
|
|
|
|
|
+Const GrowSpeed = 10;
|
|
|
|
+
|
|
function Max(ANumber, BNumber: DWord): DWord;
|
|
function Max(ANumber, BNumber: DWord): DWord;
|
|
begin
|
|
begin
|
|
if ANumber > BNumber then
|
|
if ANumber > BNumber then
|
|
@@ -120,107 +117,53 @@ begin
|
|
Result := BNumber;
|
|
Result := BNumber;
|
|
end;
|
|
end;
|
|
|
|
|
|
-{ TIndexedWordList }
|
|
|
|
|
|
+Function CompareProcObj(Node1, Node2: Pointer): integer;
|
|
|
|
+var n1,n2 : TIndexedWord;
|
|
|
|
+begin
|
|
|
|
+ n1:=TIndexedWord(Node1); n2:=TIndexedWord(Node2);
|
|
|
|
+ Result := CompareText(n1.theword, n2.theword);
|
|
|
|
+ if Result = 0 then
|
|
|
|
+ begin
|
|
|
|
+ Result := ord(n2.IsTitle)-ord(n1.IsTitle);
|
|
|
|
+ end;
|
|
|
|
+ if Result < 0 then Result := -1
|
|
|
|
+ else if Result > 0 then Result := 1;
|
|
|
|
+end;
|
|
|
|
|
|
|
|
+{ TIndexedWordList }
|
|
function TIndexedWordList.AddGetWord(AWord: String; IsTitle: Boolean): TIndexedWord;
|
|
function TIndexedWordList.AddGetWord(AWord: String; IsTitle: Boolean): TIndexedWord;
|
|
-var
|
|
|
|
- //StartWord,
|
|
|
|
- WrongWord: TIndexedWord;
|
|
|
|
|
|
+var
|
|
|
|
+ n : TAVLTreeNode;
|
|
begin
|
|
begin
|
|
Result := nil;
|
|
Result := nil;
|
|
AWord := LowerCase(AWord);
|
|
AWord := LowerCase(AWord);
|
|
-
|
|
|
|
- {if FCachedWord <> nil then
|
|
|
|
- StartWord := FCachedWord
|
|
|
|
|
|
+ if not assigned(spare) then
|
|
|
|
+ spare:=TIndexedWord.Create(AWord,IsTitle)
|
|
else
|
|
else
|
|
- StartWord := FFirstWord;
|
|
|
|
-
|
|
|
|
- if StartWord <> nil then
|
|
|
|
- begin
|
|
|
|
- case CompareWord(AWord, StartWord, IsTitle) of
|
|
|
|
- 0: Exit(WrongWord);
|
|
|
|
- 1: Result := GetWordBackward(AWord, StartWord, WrongWord, IsTitle);
|
|
|
|
- -1: Result := GetWordForward(AWord, StartWord, WrongWord, IsTitle);
|
|
|
|
|
|
+ begin
|
|
|
|
+ spare.TheWord:=aword;
|
|
|
|
+ spare.IsTitle:=IsTitle;
|
|
end;
|
|
end;
|
|
- end
|
|
|
|
- else}
|
|
|
|
- Result := GetWordForward(AWord, FFirstWord, WrongWord, IsTitle);
|
|
|
|
|
|
+
|
|
|
|
+ n:=favltree.FindKey(Spare,@CompareProcObj);
|
|
|
|
+ if assigned(n) then
|
|
|
|
+ result:=TIndexedWord(n.Data);
|
|
|
|
|
|
if Result = nil then
|
|
if Result = nil then
|
|
begin
|
|
begin
|
|
Inc(FTotalDifferentWordLength, Length(AWord));
|
|
Inc(FTotalDifferentWordLength, Length(AWord));
|
|
Inc(FTotalDIfferentWords);
|
|
Inc(FTotalDIfferentWords);
|
|
- Result := TIndexedWord.Create(AWord,IsTitle);
|
|
|
|
- AddWord(Result, WrongWord,IsTitle);
|
|
|
|
- if IsTitle then
|
|
|
|
- ;//WriteLn('Creating word: ', AWord);
|
|
|
|
|
|
+ Result := spare; // TIndexedWord.Create(AWord,IsTitle);
|
|
|
|
+ spare:=nil;
|
|
|
|
+ AddWord(Result);
|
|
|
|
+ // if IsTitle then
|
|
|
|
+ //WriteLn('Creating word: ', AWord);
|
|
FLongestWord := Max(FLongestWord, Length(AWord));
|
|
FLongestWord := Max(FLongestWord, Length(AWord));
|
|
end;
|
|
end;
|
|
Inc(FTotalWordLength, Length(AWord));
|
|
Inc(FTotalWordLength, Length(AWord));
|
|
Inc(FTotalWordCount);
|
|
Inc(FTotalWordCount);
|
|
end;
|
|
end;
|
|
|
|
|
|
-function TIndexedWordList.GetWordForward(AWord: String; StartWord: TIndexedWord; out WrongWord: TIndexedWord; AIsTitle: Boolean): TIndexedWord;
|
|
|
|
-var
|
|
|
|
- FCurrentWord: TIndexedWord;
|
|
|
|
-begin
|
|
|
|
- Result := nil;
|
|
|
|
- WrongWord := nil;
|
|
|
|
- FCurrentWord := StartWord;
|
|
|
|
- while (FCurrentWord <> nil) and (CompareWord(AWord, FCurrentWord, AIsTitle) <> 0) do
|
|
|
|
- begin
|
|
|
|
- WrongWord := FCurrentWord;
|
|
|
|
- case CompareWord(AWord, FCurrentWord, AIsTitle) of
|
|
|
|
- -1: FCurrentWord := nil;
|
|
|
|
- 0: Exit(FCurrentWord);
|
|
|
|
- 1: FCurrentWord := FCurrentWord.NextWord;
|
|
|
|
- end;
|
|
|
|
- end;
|
|
|
|
-
|
|
|
|
- if FCurrentWord <> nil then
|
|
|
|
- Result := FCurrentWord;
|
|
|
|
-end;
|
|
|
|
-
|
|
|
|
-function TIndexedWordList.GetWordBackward(AWord: String; StartWord: TIndexedWord; out WrongWord: TIndexedWord; AIsTitle: Boolean): TIndexedWord;
|
|
|
|
-var
|
|
|
|
- FCurrentWord: TIndexedWord;
|
|
|
|
-begin
|
|
|
|
- Result := nil;
|
|
|
|
- WrongWord := nil;
|
|
|
|
- FCurrentWord := StartWord;
|
|
|
|
- while (FCurrentWord <> nil) and (CompareWord(AWord, FCurrentWord, AIsTitle) <> 0) do
|
|
|
|
- begin
|
|
|
|
- WrongWord := FCurrentWord;
|
|
|
|
- case CompareWord(AWord, FCurrentWord, AIsTitle) of
|
|
|
|
- -1:
|
|
|
|
- begin
|
|
|
|
- WrongWord := FCurrentWord;
|
|
|
|
- FCurrentWord := nil
|
|
|
|
- end;
|
|
|
|
- 0: Exit(FCurrentWord);
|
|
|
|
- 1: FCurrentWord := FCurrentWord.PrevWord;
|
|
|
|
- end;
|
|
|
|
- end;
|
|
|
|
- if FCurrentWord <> nil then
|
|
|
|
- Result := FCurrentWord;
|
|
|
|
-end;
|
|
|
|
-
|
|
|
|
-function TIndexedWordList.CompareWord ( AWord: String;
|
|
|
|
- AIndexWord: TIndexedWord; AIsTitle: Boolean ) : Integer;
|
|
|
|
-begin
|
|
|
|
- Result := CompareText(AWord, AIndexWord.TheWord);
|
|
|
|
- if Result = 0 then
|
|
|
|
- begin
|
|
|
|
- Result := Result + ord(AIndexWord.IsTitle);
|
|
|
|
- Result := Result - ord(AIsTitle);
|
|
|
|
- end;
|
|
|
|
- if Result < 0 then Result := -1
|
|
|
|
- else if Result > 0 then Result := 1;
|
|
|
|
- //if AIsTitle then
|
|
|
|
- //WriteLn('Looking for title word :', AWord);
|
|
|
|
- //WriteLn(Result);
|
|
|
|
-end;
|
|
|
|
-
|
|
|
|
procedure TIndexedWordList.CBFoundTag(NoCaseTag, ActualTag: string);
|
|
procedure TIndexedWordList.CBFoundTag(NoCaseTag, ActualTag: string);
|
|
begin
|
|
begin
|
|
if FInBody then begin
|
|
if FInBody then begin
|
|
@@ -280,12 +223,10 @@ begin
|
|
Delete(WordName, FPos, 1);
|
|
Delete(WordName, FPos, 1);
|
|
FPos := Pos('''', WordName);
|
|
FPos := Pos('''', WordName);
|
|
end;
|
|
end;
|
|
- WordIndex := Self.Words[WordName, IsTitle];
|
|
|
|
|
|
+ WordIndex := addgetword(wordname,istitle);
|
|
InWord := False;
|
|
InWord := False;
|
|
- //if IsNumberWord then WriteLn('Following is NUMBER WORD: "', (WordStart[0]),'"'); ;
|
|
|
|
IsNumberWord := False;
|
|
IsNumberWord := False;
|
|
WordIndex.DocumentTopic[FTopicIndex].AddWordIndex(FWordCount);
|
|
WordIndex.DocumentTopic[FTopicIndex].AddWordIndex(FWordCount);
|
|
- //WriteLn(FWordCount, ' "', WordName,'"');
|
|
|
|
//if not IsTitle then
|
|
//if not IsTitle then
|
|
Inc(FWordCount);
|
|
Inc(FWordCount);
|
|
|
|
|
|
@@ -295,7 +236,6 @@ begin
|
|
InWord := True;
|
|
InWord := True;
|
|
WordStart := WordPtr;
|
|
WordStart := WordPtr;
|
|
IsNumberWord := WordPtr^ in ['0'..'9'];
|
|
IsNumberWord := WordPtr^ in ['0'..'9'];
|
|
- //if IsNumberWord then WriteLn('Following is NUMBER WORD: "', WordPtr[0],'"'); ;
|
|
|
|
end;
|
|
end;
|
|
Inc(WordPtr);
|
|
Inc(WordPtr);
|
|
until WordPtr^ = #0;
|
|
until WordPtr^ = #0;
|
|
@@ -303,7 +243,9 @@ begin
|
|
if InWord then
|
|
if InWord then
|
|
begin
|
|
begin
|
|
WordName := Copy(WordStart, 0, (WordPtr-WordStart));
|
|
WordName := Copy(WordStart, 0, (WordPtr-WordStart));
|
|
- WordIndex := Self.Words[WordName, IsTitle];
|
|
|
|
|
|
+ try
|
|
|
|
+ WordIndex := addgetword(wordname,istitle); // Self.Words[WordName, IsTitle];
|
|
|
|
+ except on e:exception do writeln(wordname); end;
|
|
WordIndex.DocumentTopic[FTopicIndex].AddWordIndex(FWordCount);
|
|
WordIndex.DocumentTopic[FTopicIndex].AddWordIndex(FWordCount);
|
|
InWord := False;
|
|
InWord := False;
|
|
//if IsNumberWord then WriteLn('Following is NUMBER WORD: "', (WordStart[0]),'"'); ;
|
|
//if IsNumberWord then WriteLn('Following is NUMBER WORD: "', (WordStart[0]),'"'); ;
|
|
@@ -311,19 +253,21 @@ begin
|
|
//WriteLn(FWordCount, ' "', WordName,'"');
|
|
//WriteLn(FWordCount, ' "', WordName,'"');
|
|
if not IsTitle then
|
|
if not IsTitle then
|
|
Inc(FWordCount);
|
|
Inc(FWordCount);
|
|
-
|
|
|
|
end;
|
|
end;
|
|
-
|
|
|
|
end;
|
|
end;
|
|
|
|
|
|
constructor TIndexedWordList.Create;
|
|
constructor TIndexedWordList.Create;
|
|
begin
|
|
begin
|
|
inherited;
|
|
inherited;
|
|
|
|
+ favltree:=TAVLTree.Create(@CompareProcObj);
|
|
|
|
+ spare:=nil;
|
|
end;
|
|
end;
|
|
|
|
|
|
destructor TIndexedWordList.Destroy;
|
|
destructor TIndexedWordList.Destroy;
|
|
begin
|
|
begin
|
|
- Clear;
|
|
|
|
|
|
+ clear;
|
|
|
|
+ if assigned(spare) then spare.free;
|
|
|
|
+ favltree.free;
|
|
inherited Destroy;
|
|
inherited Destroy;
|
|
end;
|
|
end;
|
|
|
|
|
|
@@ -360,60 +304,40 @@ begin
|
|
end;
|
|
end;
|
|
|
|
|
|
procedure TIndexedWordList.Clear;
|
|
procedure TIndexedWordList.Clear;
|
|
-var
|
|
|
|
- FCurrentWord: TIndexedWord;
|
|
|
|
begin
|
|
begin
|
|
- FCurrentWord := FFirstWord;
|
|
|
|
- while FCurrentWord <> nil do
|
|
|
|
- begin
|
|
|
|
- FFirstWord := FCurrentWord.NextWord;
|
|
|
|
- FCurrentWord.Free;
|
|
|
|
- FCurrentWord := FFirstWord;
|
|
|
|
- end;
|
|
|
|
|
|
+ fAvlTree.FreeAndClear;
|
|
end;
|
|
end;
|
|
|
|
|
|
-procedure TIndexedWordList.AddWord(const AWord: TIndexedWord; StartingWord: TIndexedWord; AIsTitle: Boolean);
|
|
|
|
-var
|
|
|
|
- WrongWord: TIndexedWord;
|
|
|
|
|
|
+procedure TIndexedWordList.AddWord(const AWord: TIndexedWord);
|
|
begin
|
|
begin
|
|
- if FFirstWord = nil then
|
|
|
|
- FFirstWord := AWord
|
|
|
|
- else begin
|
|
|
|
- if StartingWord <> nil then
|
|
|
|
- WrongWord := StartingWord;
|
|
|
|
- case CompareWord(AWord.TheWord, StartingWord, AIsTitle) of
|
|
|
|
- 1: GetWordForward(AWord.TheWord, StartingWord, WrongWord, AIsTitle);
|
|
|
|
- 0: ; // uh oh
|
|
|
|
- -1: GetWordBackward(AWord.TheWord, StartingWord, WrongWord, AIsTitle);
|
|
|
|
- end;
|
|
|
|
- if WrongWord = nil then
|
|
|
|
- WrongWord := FirstWord;
|
|
|
|
- case CompareWord(AWord.TheWord, WrongWord, AIsTitle) of
|
|
|
|
- -1:
|
|
|
|
- begin
|
|
|
|
- AWord.PrevWord := WrongWord.PrevWord;
|
|
|
|
- if AWord.PrevWord <> nil then
|
|
|
|
- AWord.PrevWord.NextWord := AWord;
|
|
|
|
- WrongWord.PrevWord := AWord;
|
|
|
|
- AWord.NextWord := WrongWord;
|
|
|
|
- end;
|
|
|
|
- 0: ;//WriteLn('Found word which shouldn''t happen'); // uh oh
|
|
|
|
- 1:
|
|
|
|
- begin
|
|
|
|
- AWord.PrevWord := WrongWord;
|
|
|
|
- AWord.NextWord := WrongWord.NextWord;
|
|
|
|
- WrongWord.NextWord := AWord;
|
|
|
|
- end;
|
|
|
|
- end;
|
|
|
|
- end;
|
|
|
|
- if AWord.PrevWord = nil then
|
|
|
|
- FFirstWord := AWord;
|
|
|
|
- FCachedWord := AWord;
|
|
|
|
|
|
+ favltree.add(AWord);
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
+procedure TIndexedWordList.ForEach(Proc:TForEachMethod);
|
|
|
|
+var
|
|
|
|
+ AVLNode : TAVLTreeNode;
|
|
|
|
+begin
|
|
|
|
+ AVLNode:=fAVLTree.FindLowest;
|
|
|
|
+ while (AVLNode<>nil) do
|
|
|
|
+ begin
|
|
|
|
+ Proc(TIndexedWord(AVLNode.Data));
|
|
|
|
+ AVLNode:=FAVLTree.FindSuccessor(AVLNode)
|
|
|
|
+ end;
|
|
|
|
+end;
|
|
|
|
|
|
-{ TIndexedWord }
|
|
|
|
|
|
+procedure TIndexedWordList.ForEach(Proc:TForEachProcedure;state:pointer);
|
|
|
|
+var
|
|
|
|
+ AVLNode : TAVLTreeNode;
|
|
|
|
+begin
|
|
|
|
+ AVLNode:=fAVLTree.FindLowest;
|
|
|
|
+ while (AVLNode<>nil) do
|
|
|
|
+ begin
|
|
|
|
+ Proc(TIndexedWord(AVLNode.Data),State);
|
|
|
|
+ AVLNode:=FAVLTree.FindSuccessor(AVLNode)
|
|
|
|
+ end;
|
|
|
|
+end;
|
|
|
|
|
|
|
|
+{ TIndexedWord }
|
|
function TIndexedWord.GetDocument ( TopicIndexNum: Integer ) : TIndexDocument;
|
|
function TIndexedWord.GetDocument ( TopicIndexNum: Integer ) : TIndexDocument;
|
|
var
|
|
var
|
|
i: Integer;
|
|
i: Integer;
|
|
@@ -449,10 +373,8 @@ destructor TIndexedWord.Destroy;
|
|
var
|
|
var
|
|
i: Integer;
|
|
i: Integer;
|
|
begin
|
|
begin
|
|
- if FPrevWord <> nil then
|
|
|
|
- FPrevWord.NextWord := FNextWord;
|
|
|
|
- if FNextWord <> nil then
|
|
|
|
- FNextWord.PrevWord := FPrevWord;
|
|
|
|
|
|
+ // here the word removed itself from the linked list. But it can't
|
|
|
|
+ // touch the AVL tree here.
|
|
for i := 0 to High(FDocuments) do
|
|
for i := 0 to High(FDocuments) do
|
|
FreeAndNil(FDocuments[i]);
|
|
FreeAndNil(FDocuments[i]);
|
|
inherited Destroy;
|
|
inherited Destroy;
|
|
@@ -464,16 +386,28 @@ begin
|
|
end;
|
|
end;
|
|
|
|
|
|
{ TIndexDocument }
|
|
{ TIndexDocument }
|
|
-
|
|
|
|
procedure TIndexDocument.AddWordIndex ( AIndex: Integer ) ;
|
|
procedure TIndexDocument.AddWordIndex ( AIndex: Integer ) ;
|
|
begin
|
|
begin
|
|
- SetLength(WordIndex, Length(WordIndex)+1);
|
|
|
|
- WordIndex[High(WordIndex)] := AIndex;
|
|
|
|
|
|
+ if FLastEntry>=Length(WordIndex) Then
|
|
|
|
+ SetLength(WordIndex, Length(WordIndex)+GrowSpeed);
|
|
|
|
+ WordIndex[FLastEntry] := AIndex;
|
|
|
|
+ Inc(FLastEntry);
|
|
end;
|
|
end;
|
|
|
|
|
|
constructor TIndexDocument.Create ( ADocumentIndex: Integer ) ;
|
|
constructor TIndexDocument.Create ( ADocumentIndex: Integer ) ;
|
|
begin
|
|
begin
|
|
FDocumentIndex := ADocumentIndex;
|
|
FDocumentIndex := ADocumentIndex;
|
|
|
|
+ flastentry:=0;
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+function TIndexDocument.GetWordIndex(i:integer):integer;
|
|
|
|
+begin
|
|
|
|
+ result:=WordIndex[i];
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+function TIndexDocument.getindexentries:integer;
|
|
|
|
+begin
|
|
|
|
+ result:=flastentry-1;
|
|
end;
|
|
end;
|
|
|
|
|
|
end.
|
|
end.
|