Текущий архив: 2004.08.01;
Скачать: CL | DM;
ВнизКак сохранить строку в св-ве Objects типа TStringList? Найти похожие ветки
← →
Arm79 (2004-07-18 00:54) [0]Доброй всем ночи.
Есть небольшая задача. Требуется хранить в памяти строки в кол-ве примерно до 20000 штук. Программа в процессе работы все время формирует новые. Если таковой строки нет, то она отсылается на сервер БД, иначе игнорируется. Каждая строка - переведенная в стринг запись БД. По условию, менять формат представления записей БД нельзя, то есть только строковый тип. Соответственно, в строке заданы ключевые поля (их может быть несколько, анализ идентичности строк производится только по ключм!!!). Система реалтаймовская. Я попытался использовать ClientDataSet, но по быстродействию он меня не устроил. Требуемую скорость работы обеспечивает StringList.
Для анализа записей БД пришлось разделить строку на 2 части - ключевую и остальную. Ключи, соответственно, хранятся в StringList[i]. Оставшуюся часть я пытаюсь запихнуть в св-во StringList.Objects[i]. А вот здесь уже возникли проблемы. Проиллюстрирую кодом:
procedure TForm1.Button1Click(Sender: TObject);
var
i : integer;
myS,
mS2: string;
SL : TStringList;
PC : PChar;
begin
SL := TStringList.Create;
SL.Sorted := true;
for i := 0 to 100 do
begin
// формирование строки из 2-х букв алфавита с номером записи
MyS := Chr(Random(32)+224)+Chr(Random(32)+224)+IntToStr(i);
mS2 := IntToStr(Length(myS));
GetMem(PC, Length(myS));
StrCopy(PC, PChar(MyS));
SL.AddObject(mS2, TObject(PC));
end;
for i := 0 to 100 do
begin
Memo1.Lines.Add(PChar(SL.Objects[i]));
//FreeMem(PChar(SL.Objects[i]));
end;
SL.Clear;
SL.Free;
end;
Этот код не работает корректно. У меня где то не ладится с памятью.
Как мне всегда казалось, св-во Objects есть указатель на область памяти. Поэтому неважно, что я туда запихну, важно затем это правильно интерпретировать...
Помогите сохранить оставшуюся часть строки!
Если есть другие предложения по сохранению, отличные от моих, просьба их высказать...
← →
KSergey © (2004-07-18 06:35) [1]Не очень понял все шаманства, разбираться лень. Но все не так ;)
Надо просто сделать наоборот: в SL.Strings добавлять строки, а в Objects - соответсвующие им числа (id).
← →
Sergey Masloff (2004-07-18 09:21) [2]
procedure TForm1.Button1Click(Sender: TObject);
var
i : integer;
myS,
mS2: string;
SL : TStringList;
// PC : PChar; не нужно
begin
SL := TStringList.Create();
try
SL.Sorted := true;
SL.Duplicates := dupAccept; // или сортед убери
for i := 0 to 100 do
begin
// формирование строки из 2-х букв алфавита с номером записи
MyS := Chr(Random(32)+224)+Chr(Random(32)+224)+IntToStr(i);
mS2 := IntToStr(Length(myS));
//GetMem(PC, Length(myS)); - на фиг не нужно
//StrCopy(PC, PChar(MyS)); - на фиг не нужно
//SL.AddObject(mS2, TObject(PC)); тоже не нужно
SL.AddObject(mS2, TObject(PChar(MyS)));
end;
for i := 0 to 100 do
begin
//Memo1.Lines.Add(PChar(SL.Objects[i]));
Memo1.Lines.Add(PChar(SL.Objects[i]));
//FreeMem(PChar(SL.Objects[i]));
end;
SL.Clear;
finally
SL.Free();
end;
end;
Ну вроде бы так внимательней смотреть лень
← →
Arm79 (2004-07-18 10:36) [3]KSergey © (18.07.04 06:35) [1]
Не очень понял все шаманства, разбираться лень. Но все не так ;)
Надо просто сделать наоборот: в SL.Strings добавлять строки, а в Objects - соответсвующие им числа (id).
Чисел нету. Только строки. Например,
"@pcode="qwe", @board="rty", @seccode="tuyi", @price=12.89"
В строке ключевые поля @pcode, @board. Остальные неважно. Если я нахожу запись с такими кючами, то проверяю полное соответствие строки. Если оно есть, то дальше эту строку не обрабатываю. Если ключи есть, то в сохраненной в памяти строке меняю значения неключевых полей на новые и отсылаю изменения в базу. Если записей с такими ключами нет, то я добавляю строку в память и в БД.
2 Sergey Masloff (18.07.04 09:21) [2]
Если убрать сортед, то время поиска в стринглисте увеличится до безобразия. Нельзя.
Выделять память для св-ва Objects надо, потому что через AddObject во втором поле передается указатель.
← →
Palladin © (2004-07-18 10:57) [4]Так а в чем проблема то? В хранении String?
Function NewString(Const p_strData:String):PChar;
Begin
GetMem(Result,Length(p_strData)+1);
Move(p_strData[1],Result^,Length(p_strData));
PByteArray(Result)[Length(p_strData)]:=0;
End;
Procedure FreeString(Var rp_pChar:PChar);
Begin
FreeMem(rp_pChar,StrLen(rp_pChar)+1);
rp_pChar:=Nil;
End;
← →
GrayFace © (2004-07-18 11:28) [5]Sergey Masloff, не верно. Все Objects будут ссылаться на одну и ту же несуществующую строку.
Если Стринглист никто не видит, то лучше всего запихнуть обе строки в одну:вначале ключ, потом остальное; а в Objects записать длины ключей. Если это должно быть видно, то ты все почти правильно делал.
for i:=0 to 100 do
begin
S1:=строка;
S2:=ключ;
GetMem(PC, Length(S2)+4);
pInt(PC)^:=length(S2);
inc(PC,4);
//StrCopy(PC, PChar(S2));
Move(S2,PC,length(S2));
SL.AddObject(S1,PC);//Или Memo1.Lines.AddObject(S1,PC);
end;
Только SL удалять не надо. Потом можно будет работать со string(SL.Objects), а не с PChar, т.е. можно будет быстро брать длину и использовать больше функций. Вообще не очень понятно, что тебе надо. Например, что значит Chr(Random(32)+224)+Chr(Random(32)+224)?
← →
Arm79 (2004-07-18 21:49) [6]2 Palladin © (18.07.04 10:57) [4]
Спасибо, то, что надо
2 GrayFace © (18.07.04 11:28) [5]
>Если Стринглист никто не видит, то лучше всего запихнуть обе >строки в одну:вначале ключ, потом остальное
Я так думал, но получаются слишком большие накладные расходы. Ко всему этому необходимо еще и писать свой поисковик в списке. Стандартный лучше и, что главное, быстрее.
> pInt(PC)^:=length(S2);
pInt = pInteger?
> SL.AddObject(S1,PC);
Эта строка у меня вызывает сомнения, тк чуть раньше было
inc(PC, 4);
Зачем хранить длины ключей? И при добавлении в список не учитывается вычисленная длина, тк запись начинается с 4 позиции.
> Только SL удалять не надо .......
1. Участок приведенного кода из тестовой программы, созданной для отработки работы с данной структурой. Поэтому я не приводил алгоритм формирования новых строк. Он слишком длинный и ненаглядный.
2. Chr(Random(32)+224)+Chr(Random(32)+224) - формирование случайной строки из 2 маленьких букв русского алфавита с номером строки и ничего больше. Никакой смысловой нагрузки не несет, кроме отработки записи-чтения.
Страницы: 1 вся ветка
Текущий архив: 2004.08.01;
Скачать: CL | DM;
Память: 0.47 MB
Время: 0.031 c