четверг, 25 сентября 2014 г.

Про "рефакторинг"

По мотивам - Депрессия. Или превратности hResult и прочих ErrorCode

И ещё сегодня я нашёл два "бутылочных горлышка" - AllocNewFATAlement и AllocNewCluster.

Они в свою очередь ведут к LockFile.

Потому, что лочим заголовок.

Где записана информация о структуре хранилища.

Потому, что доступ к заголовку - должен быть синхронизирован.

Иначе - получится "каша", а не "хранилище".

И все пользователи при записи "бъются от эти залочки".

Я сегодня эту картину наблюдал на "синтетических" нагрузочных тестах.

Реально под отладчиком.

Когда другие машины - "молотили", а я одну из них - "отлаживал".

И УВИДЕЛ. Реально увидел. В коде. И на break-point'ах.

Как - "один другого ждёт".

И знаю уже как это разрулить.

Надо упреждающе аллоцировать не один FATElement и Cluster, а сразу несколько (пять, десять, двадцать, тридцать).

Одним куском.

Учитывая, что кластеров в файле обычно не один и не два и даже не десять, то это - эффективно.

И держать список свободных локально у клиента. А потом когда клиент закрывается - возвращать их в список свободных. Т.е. "не пригодившихся". Чтобы из потом могли использовать другие клиенты.

Есть конечно вероятность - потерять элементы, если клиент завершится аварийно.

Но зато - мы реже попадаем в "бутылочное горлышко".

Потому, что мы можем написать.

if AllocatedFatElements.Empty then
begin
 // - тут есть межПРОЦЕССНОЕ "бутылочное горлышко"
 Lock;
 try
  Result := AllocNewFatElement;
  for l_Index := 0 to 10 do
   AllocatedFatElements.Add(AllocNewFatElement);
 finally
  Unlock;
 end//try..finally
end
else
 // - тут ТОЛЬКО межПОТОЧНОЕ "бутылочное горлышко" (потому что AllocatedFatElements - естественно - многопоточно-защищён)
 Result := AllocatedFatElements.GetLastAndDeleteIt;

Вместо:

Lock;
// - а тут - ВСЕГДА - многоПРОЦЕССОРНОЕ "бутылочное горлышко"
try
 Result := AllocNewFatElement;
finally
 Unlock;
end;//try..finally

Ну и аналогично для кластеров.

А даже если и элементы "провиснут", то сильно хуже не будет, хранилище - не разрушится. Просто в нём будут "дырки".

Но учитывая тот факт, что у нас ночью происходит "ночной Update", если он возможен конечно, то хранилище - всё равно - перепаковывается. Т.е. "дырки" к "утру" - всё равно исчезнут.

И будет перепакованная постоянная часть без дырок. И "пустая" переменная часть.

Куда клиенты в течении дня пишут свои версии документов.

А следующей ночью - процесс опять повторяется.

Если конечно к базе не подключены работающие пользователи.

Комментариев нет:

Отправить комментарий