Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 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.49 MB
Время: 0.043 c
8-1084536203
Senator
2004-05-14 16:03
2004.08.01
кодеки


1-1090083860
diablo_m
2004-07-17 21:04
2004.08.01
Динамическое создание формы


11-1078377224
vinter
2004-03-04 08:13
2004.08.01
Как поместить на форму jpg картинку


1-1089986059
NJoe
2004-07-16 17:54
2004.08.01
TImage


14-1090016450
KilkennyCat
2004-07-17 02:20
2004.08.01
Статистика опроса, проведенного Rouse_ ©