Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2004.08.01;
Скачать: [xml.tar.bz2];

Вниз

Как сохранить строку в св-ве 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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.47 MB
Время: 0.037 c
14-1089970421
ghg
2004-07-16 13:33
2004.08.01
где инфа про компонент TShellTreeView


3-1089016115
CyberMOHCTP
2004-07-05 12:28
2004.08.01
Cannot modify a read-only dataset - Как бороться?


14-1089663163
KilkennyCat
2004-07-13 00:12
2004.08.01
Блин, пока ехал на работу, мучался вопросом...


4-1087374976
DFF
2004-06-16 12:36
2004.08.01
API : Длинна текста и смена шрифта


8-1083744484
rand0m
2004-05-05 12:08
2004.08.01
Морфинг





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский