Динамические Массивы
(Arrays)

Version 2.0

Copyright © 1998-2001 by Andrey Romanchenko
All rights reserved.

e-mail:   lasersquad@tut.by
web site:   http://DynamicArrays.narod.ru/

Содержание


Общее описание

Динамические массивы это мощное средство для хранения, быстрого поиска и манипулирования данными различных типов используемых в среде Delphi.

Память под хранимые данные выделяется динамически по мере роста количества элементов в массиве.

Память выделяется на немного большее количество элементов по специальному алгоритму что бы минимизировать количество запросов на выделение памяти к системе что повышает производительность.

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

Все массивы zero based т.е. первый элемент массива имеет индекс 0, второй 1 и т.д.


Инсталяция

Динамические массивы не требуют никакой инсталяции. Достаточно включить модуль DynamicArrays.pas в секцию uses нужного модуля вашего проекта и все. Только не забудьте указать Delphi путь где вы разместили файл DynamicArrays.pas. Это можно сделать либо в либо в

Глобальные определения

В DynamicArrays.pas определены некоторые глобальные типы которые вы можете использовать в своих программах.
Два типа данных:
 pboolean = ^boolean;
 ppointer = ^pointer;

А так же три callback функции:

THArray

Обобщеный динамический массив элементов.
Хранит элементы любой природы и любой сложности, все что он знает это размер одного элемента в байтах (ItemSize).
Не содержит абстрактных методов и поэтому позволяет создавать экземпляры класса THArray, а не только его наследников для хранения любых элементов.
Является предком всех классов динамических массивов.
От THArray наследуются : Все методы класса THArray работают с указателями на данные в памяти (указатели типа pointer) т.к. тип хранимых данных для THArray не определен. Например функция Add(pValue:pointer) добавляет в конец массива ItemSize байтов взятых из памяти по адресу pValue. Аналогично работают все другие методы класса THArray.
Класс THArrayString является просто надстройкой над THArray для работы со string.
Класс THArrayStringFix работает со строками строго фиксированой длины (например строковые поля в базе).

Свойства
Capacity:integer; На сколько элементов (ItemSize байт каждый) захвачено памяти
Count:integer; Количество элементов в массиве
ItemSize:integer; Размер каждого элемента. При изменении ItemSize значения выполняется ClearMem и все данные теряются.
Memory:pointer; Указатель на начало массива элементов.
Методы
function Add(pValue:pointer):integer;virtual; Добавляет в конец массива значение находящееся по адресу pValue. Размер берется из ItemSize. Возвращает номер позиции, куда было добавлено значение.
procedure AddMany(pValue:pointer;Count:integer); Добавляет несколько значений в конец массива. Можно использовать для копирования одного массива в другой.
procedure AddFillValues(ACount:integer); Добавляет ACount элементов в конец массива. Память занимаемая добавляемыми элементами обнуляется.
procedure Clear;virtual; Чистит массив, но память не освобождает (остатется для хранения новых данных). Если часто чистится перезаписывается массив, но размер примерно одинаков, память чистить не обязательно - следующий раз не будет захватываться память. См. также метод ClearMem.
procedure ClearMem;virtual; Чистит массив, при этом освобождая всю память.
procedure Delete(num:integer);virtual; Удаляет элемент в позиции num. Все следующие значения сдвигаются к началу. Память при этом не освобождается. См. метод Hold для освобождения незанятой памяти.
function Insert(num:integer;pValue:pointer):integer;virtual; Добавляет значение, но не в конец, а в позицию num. Все следующие элементы сдвигаются. Возвращает номер позиции, куда было добавлено значение.
procedure InsertMany(num:integer;pValue:pointer;Count:integer); То же самое, но несколько значений.
function IndexOf(Value:pointer):integer; Возвращает индекс первого встреченого значения на которое указывает Value. Если ничего не нашла то возвращает -1.
Если в массиве хранится массив записей то Value может быть указателем на запись которую нужно найти. Для поиска следующего значения можно использовать метод IndexOfFrom. Каждый класс наследник имеет свой метод IndexOf оптимизированный для поиска элементов определенного типа (тип элементов зависит от класса - например THArrayInteger хранит элементы integer), поэтому если используется класс наследник THArray то всегда лучше использовать его метод IndexOf для поиска.
function IndexOfFrom(Value:pointer;Start:integer):integer; Возвращает индекс значения на которое указывает Value, поиск начинает с элемента с индексом Start. Если ничего не нашла то возвращает -1. Используется для инкрементального поиска.
Каждый класс наследник имеет свой метод IndexOfFrom оптимизированны для поиска элементов определенного типа (тип элементов зависит от класса, например THArrayDouble хранит элементы Double) поэтому если используется класс наследник THArray то всегда лучше использовать его метод IndexOfFrom для поиска.
procedure Hold; Отдать лишнюю память системе. Остается память только для тех значений, которые есть в массиве. Но в дальнейшем добавлять значения можно без проблем, просто это вызовет захват новой памяти при добавлении первого же значения.
procedure Grow; Увеличивает захваченую память (Capacity) для хранения новых элементов по специальному алгоритму. Для больших массивов (больше 64 элементов) память увеличивается на 25%.
procedure GrowTo(Count:integer); Увеличивает захваченую память (Capacity) для хранения новых элементов. Новый размер захваченой памяти вычисляется по следующей формуле Capacity:=max(Capacity вычисленая по специальному алгоритму, Count).
procedure Get(num:integer;pValue:pointer);virtual; Получить значение элемента с номером num. Нужно передать сюда адрес куска памяти pValue, а функция скопирует туда значение. Для внутреннего пользования.
function GetAddr(num:integer):pointer; Получить адрес элемента num. Адрес вычисляется как Memory+num*ItemSize.
procedure LoadFromStream(s:TStream);virtual; Читает массив из потока. Первым должно идти число integer - количество элементов в массиве, а затем сами элементы в виде непрерывного куска памяти. Для корректной работы записывайте и читайте поток экземплярами класса одного типа. Например если поток записан с помощью THArrayInteger то и читать его нужно с помощью THArrayInteger. THArraySmallInt ошибки не выдаст, но вычитает ерунду из этого потока. Если же записывать поток с помощью THArraySmallInt а пытаться читать с помощью THArrayInteger то возникнет ошибка доступа к памяти т.к. массив THArraySmallInt занимает меньше места в памяти чем THArrayInteger.
Медод является виртуальным и может быть переопределен.
См. так же SaveToStream
procedure SaveToStream(s:TStream);virtual; Записывает массив в поток. Первым записывается идти число integer - количество элементов в массиве, а затем элементы в виде непрерывного куска памяти.
Медод является виртуальным и может быть переопределен.
См. так же LoadFromStream
procedure MoveData(FromPos,Count,Offset:integer);virtual; Переместить записи в массиве, начиная с FromPos количеством Count на смещение Offset.
function QuickFind(FindProc:TFindProc;FindData:pointer):integer; Быстрый поиск в ОТСОРТИРОВАННОМ массиве с помощью пользовательской ф-ции FindProc. FindData указатель на значение которое нужно найти (передается в FindProc). Метод используется в редких случаях когда сравнение 2-х элементов не тривиальная задача, например если THArray хранит структуры либо какие то более сложно организованные данные.
procedure QuickSort(CompareProc:TCompareProc;SwapProc:TSwapProc=nil); Сортировка элементов массива методом быстрой сортировки. Для сравнения 2-х элементов используется пользовательская функция CompareProc, а для обмена их местами необязательная пользовательская ф-ция SwapProc. Если SwapProc не указана то для обмена элементов местами используется метод Swap.
procedure SetCapacity(Value:integer); Захватить память под Value значений. Если значений в массиве было больше, лишние удаляются.
procedure Sort(CompareProc : TCompareProc); Сортировка элементов массива методом пузырька. Для сравнения 2-х элементов используется пользовательская функция CompareProc.
procedure Swap(Index1,Index2:integer);virtual; Меняет местами значения с индексами Index1 и Index2. Не использует функцию TSwapProc.
procedure Update(num:integer;pValue:pointer);virtual; Устанавливает элемент массива с индексом num в значение находящееся по адресу pValue.
procedure UpdateMany(num:integer;pValue:pointer;Count:integer); То же но для нескольких значений.
procedure Zero; Обнуляет память где хранятся данные. Используйте этот метод осторожно т.к. он затирает все хранимые данные и их восстановить будет уже невозможно.


THArrayInteger

Массив для хранения целых чисел.
При попытке обращения к несуществующему индексу выдает исключение ERangeError.
Может использоваться в качестве стека. Для этого содержит методы Push и Pop. Первый добавляет значение в конец массива, а второй читает и удаляет последнее значение. Методы Push и Pop есть только у THArrayInteger. Если такие методы будут нужны для других классов пишите добавлю.
THArrayInteger имеет два уникальных метода для импорта и экспорта списка значений в строку - AddFromString, GetAsString .

Свойства
property Value[Index:integer]:integer; default; Извлекает либо устанавливает значение по индексу. Если индекс не существует то выдает исключение ERangeError.
Методы
procedure AddFromString(InputString,Delimiters:string); Добавляет группу значений из строки InputString разделенных разделителями Delimiters. Несколько подряд идущих разделителей воспринимаются как один.
function AddValue(Value:integer):integer; Добавляет значение Value в конец массива. Возвращает индекс добавленого элемента.
function CalcMax:integer; Возвращает максимальное значение в массиве. Если массив пустой то возвращает -1.
function IndexOf(Value:integer):integer; Возвращает индекс первого встреченого значения Value. Если ничего не нашла то возвращает -1. Для поиска следующего значения можно использовать функцию IndexOfFrom
function IndexOfFrom(Value:integer;Start:integer):integer; Возвращает индекс значения Value, поиск начинает с элемента с индексом Start. Если ничего не нашла то возвращает -1. Используется для инкрементального поиска.
function GetAsString:string; Выгоняет все значения массива в строку. Значения в строке разделены пробелом.
function Pop:integer; Восстанавливает значение из стека. А на самом деле достает и удаляет последнее значение в массиве. Если массив пустой то возбуждается исключение ERangeError.
procedure Push(Value:integer); Вталкивает значение в стек. А на самом деле добавляет значение в конец массива.


THArrayByte

Массив для хранения чисел byte, то есть массива байтов.
Byte представляет собой 8 битовое беззнаковое целое число - минимальная единица хранения информации.

Свойства
property Value[Index:integer]:byte; default; Извлекает либо устанавливает значение по индексу. Если индекс не существует то выдает исключение ERangeError.
Методы
function AddValue(Value:byte):integer; Добавляет значение Value в конец массива. Возвращает индекс добавленого элемента.
function IndexOf(Value:byte):integer; Возвращает индекс первого встреченого значения Value. Если ничего не нашла то возвращает -1. Для поиска следующего значения можно использовать функцию IndexOfFrom
function IndexOfFrom(Value:byte;Start:integer):integer; Возвращает индекс значения Value, поиск начинает с элемента с индексом Start. Если ничего не нашла то возвращает -1. Используется для инкрементального поиска.


THArraySmallInt

Массив для хранения чисел SmallInt.
Формат SmallInt представляет собой 16 битовое знаковое целое число.

Свойства
property Value[Index:integer]:SmallInt; default; Извлекает либо устанавливает значение по индексу. Если индекс не существует то выдает исключение ERangeError.
Методы
function AddValue(Value:SmallInt):integer; Добавляет значение Value в конец массива. Возвращает индекс добавленого элемента.
function IndexOf(Value:SmallInt):integer; Возвращает индекс первого встреченого значения Value. Если ничего не нашла то возвращает -1. Для поиска следующего значения можно использовать функцию IndexOfFrom
function IndexOfFrom(Value:SmallInt;Start:integer):integer; Возвращает индекс значения Value, поиск начинает с элемента с индексом Start. Если ничего не нашла то возвращает -1. Используется для инкрементального поиска.


THArrayWord

Массив для хранения чисел в формате Word.
Формат Word представляет собой 16 битовое беззнаковое целое число.

Свойства
property Value[Index:integer]:Word; default; Извлекает либо устанавливает значение по индексу. Если индекс не существует то выдает исключение ERangeError.
Методы
function AddValue(Value:Word):integer; Добавляет значение Value в конец массива. Возвращает индекс добавленого элемента.
function IndexOf(Value:Word):integer; Возвращает индекс первого встреченого значения Value. Если ничего не нашла то возвращает -1. Для поиска следующего значения можно использовать функцию IndexOfFrom
function IndexOfFrom(Value:Word;Start:integer):integer; Возвращает индекс значения Value, поиск начинает с элемента с индексом Start. Если ничего не нашла то возвращает -1. Используется для инкрементального поиска.


THArrayLongWord

Массив для хранения чисел в формате LongWord.
Формат LongWord представляет собой 32 битовое беззнаковое целое число.

Свойства
property Value[Index:integer]:LongWord; default; Извлекает либо устанавливает значение по индексу. Если индекс не существует то выдает исключение ERangeError.
Методы
function AddValue(Value:LongWord):integer; Добавляет значение Value в конец массива. Возвращает индекс добавленого элемента.
function IndexOf(Value:LongWord):integer; Возвращает индекс первого встреченого значения Value. Если ничего не нашла то возвращает -1. Для поиска следующего значения можно использовать функцию IndexOfFrom
function IndexOfFrom(Value:LongWord;Start:integer):integer; Возвращает индекс значения Value, поиск начинает с элемента с индексом Start. Если ничего не нашла то возвращает -1. Используется для инкрементального поиска.


THArrayInt64

Массив для хранения чисел в формате Int64.
Формат Int64 представляет собой 64 битовое знаковое целое число.

Свойства
property Value[Index:integer]:Int64; default; Извлекает либо устанавливает значение по индексу. Если индекс не существует то выдает исключение ERangeError.
Методы
function AddValue(Value:Int64):integer; Добавляет значение Value в конец массива. Возвращает индекс добавленого элемента.
function IndexOf(Value:int64):integer; Возвращает индекс первого встреченого значения Value. Если ничего не нашла то возвращает -1. Для поиска следующего значения можно использовать функцию IndexOfFrom
function IndexOfFrom(Value:int64;Start:integer):integer; Возвращает индекс значения Value, поиск начинает с элемента с индексом Start. Если ничего не нашла то возвращает -1. Используется для инкрементального поиска.


THArrayBoolean

Массив для хранения чисел в формате Boolean.
Каждый boolean хранится как один байт (Delphi представление).

Свойства
property Value[Index:integer]:boolean; default; Извлекает либо устанавливает значение по индексу. Если индекс не существует то выдает исключение ERangeError.
Методы
function AddValue(Value:boolean):integer; Добавляет значение Value в конец массива. Возвращает индекс добавленого элемента.
function IndexOf(Value:boolean):integer; Возвращает индекс первого встреченого значения Value. Если ничего не нашла то возвращает -1. Для поиска следующего значения можно использовать функцию IndexOfFrom
function IndexOfFrom(Value:boolean;Start:integer):integer; Возвращает индекс значения Value, поиск начинает с элемента с индексом Start. Если ничего не нашла то возвращает -1. Используется для инкрементального поиска.


THArrayPointer

Массив для хранения указателей.
Указатели могут указывать куда угодно. Никаких специальных операций над хранимыми данными THArrayPointer не производит.

Свойства
property Value[Index:integer]:pointer; default; Извлекает либо устанавливает значение по индексу. Если индекс не существует то выдает исключение ERangeError.
Методы
function AddValue(Value:pointer):integer; Добавляет значение Value в конец массива. Возвращает индекс добавленого элемента.
function IndexOf(Value:pointer):integer; Возвращает индекс первого встреченого значения Value. Если ничего не нашла то возвращает -1. Для поиска следующего значения можно использовать функцию IndexOfFrom
function IndexOfFrom(Value:pointer;Start:integer):integer; Возвращает индекс значения Value, поиск начинает с элемента с индексом Start. Если ничего не нашла то возвращает -1. Используется для инкрементального поиска.


THArrayObjects

Массив для хранения указателей на классы Delphi.
Содержит несколько дополнительных методов для работы в элементами как с указателями на TObject. ВНИМАНИЕ! При разрушении автоматически разрушает все сохраненые обьекты, вызывая для каждого обьекта метод Free. Для разрушения массива без разрушения сохраненных обьектов используйте класс THArrayPointer.

Свойства
property Value[Index:integer]:TObject; default; Извлекает либо устанавливает значение по индексу. Если индекс не существует то выдает исключение ERangeError.
Методы
function AddValue(Value:TObject):integer; Добавляет значение Value в конец массива. Возвращает индекс добавленого элемента.
procedure ClearMem; Чистит массив, при этом освобождая всю память и разрушая все сохраненые обьекты! Что бы удалить только ссылки на обьекты вызывай SafeClearMem.
procedure Delete(num:integer); Удаляет элемент в позиции num, разрушая при этом сам обьект! Для удаления только ссылки на обьект см. SafeDelete.
Все следующие значения сдвигаются к началу. Память при этом не освобождается. См. метод Hold для освобождения незанятой памяти.
function IndexOf(Value:TObject):integer; Возвращает индекс первого встреченого значения Value. Если ничего не нашла то возвращает -1. Для поиска следующего значения можно использовать функцию IndexOfFrom
function IndexOfFrom(Value:TObject;Start:integer):integer; Возвращает индекс значения Value, поиск начинает с элемента с индексом Start. Если ничего не нашла то возвращает -1. Используется для инкрементального поиска.
procedure SafeClearMem; Чистит массив, при этом освобождая всю память. Удаляет только ссылки на обьекты, сами обьекты не разрушаются.
procedure SafeDelete(num:integer); Удаляет элемент в позиции num. При этом сам обьект не разрушается а удаляется только ссылка на него.
Все следующие значения сдвигаются к началу. Память при этом не освобождается. См. метод Hold для освобождения незанятой памяти.

THArrayCurrency

Массив для хранения плавающих чисел в формате Currency.
Currency это специальный плавающий тип данных в Delphi для представления денежной информации.

Свойства
property Value[Index:integer]:Currency; default; Извлекает либо устанавливает значение по индексу. Если индекс не существует то выдает исключение ERangeError.
Методы
function AddValue(Value:Currency):integer; Добавляет значение Value в конец массива. Возвращает индекс добавленого элемента.
function IndexOf(Value:Currency):integer; Возвращает индекс первого встреченого значения Value. Если ничего не нашла то возвращает -1. Для поиска следующего значения можно использовать функцию IndexOfFrom
function IndexOfFrom(Value:Currency;Start:integer):integer; Возвращает индекс значения Value, поиск начинает с элемента с индексом Start. Если ничего не нашла то возвращает -1. Используется для инкрементального поиска.

THArrayDouble

Массив для хранения плавающих чисел в формате Double.


Свойства
property Value[Index:integer]:Double; default; Извлекает либо устанавливает значение по индексу. Если индекс не существует то выдает исключение ERangeError.
Методы
function AddValue(Value:Double):integer; Добавляет значение Value в конец массива. Возвращает индекс добавленого элемента.
function IndexOf(Value:Double):integer; Возвращает индекс первого встреченого значения Value. Если ничего не нашла то возвращает -1. Для поиска следующего значения можно использовать функцию IndexOfFrom
function IndexOfFrom(Value:Double;Start:integer):integer; Возвращает индекс значения Value, поиск начинает с элемента с индексом Start. Если ничего не нашла то возвращает -1. Используется для инкрементального поиска.

THArrayExtended

Массив для хранения плавающих чисел в формате Extended.
Формат Extended представляет собой 10 байтовойе число с плавающей точкой. Применяется для вычислений с повышеной точностью.

Свойства
property Value[Index:integer]:Extended; default; Извлекает либо устанавливает значение по индексу. Если индекс не существует то выдает исключение ERangeError.
Методы
function AddValue(Value:Extended):integer; Добавляет значение Value в конец массива. Возвращает индекс добавленого элемента.
function IndexOf(Value:Extended):integer; Возвращает индекс первого встреченого значения Value. Если ничего не нашла то возвращает -1. Для поиска следующего значения можно использовать функцию IndexOfFrom
function IndexOfFrom(Value:Extended;Start:integer):integer; Возвращает индекс значения Value, поиск начинает с элемента с индексом Start. Если ничего не нашла то возвращает -1. Используется для инкрементального поиска.

THArrayString

Массив для хранения строк любой длины.
На самом деле представляет собой массив указателей на строки.

Свойства
property Value[Index:integer]:String; default; Извлекает либо устанавливает значение по индексу. Если индекс не существует то выдает исключение ERangeError.
Методы
function AddValue(Value:String):integer; Добавляет значение Value в конец массива. Возвращает индекс добавленого элемента.
function IndexOf(Value:string):integer; Возвращает индекс первого встреченого значения Value. Если ничего не нашла то возвращает -1. Для поиска следующего значения можно использовать функцию IndexOfFrom
function IndexOfFrom(Value:string;Start:integer):integer; Возвращает индекс значения Value, поиск начинает с элемента с индексом Start. Если ничего не нашла то возвращает -1. Используется для инкрементального поиска.

THArrayStringFix

Массив для хранения строк фиксированой длины. Полезен для хранения полей таблиц баз данных.
Для создания экземпляра этого класса используйте специальный конструктор CreateSize(Size:integer).

Свойства
property Value[Index:integer]:String; default; Извлекает либо устанавливает значение по индексу. Если индекс не существует то выдает исключение ERangeError.
Методы
constructor CreateSize(Size:integer); Для создания экземпляра этого класса вместо обычного конструктора без параметров используйте конструктор CreateSize в который передается размер строки в байтах
Size. Вызов обычного конструктора (Create без параметров) вызовет генерацию исключения.
function AddValue(Value:string):integer; Добавляет значение Value в конец массива. Возвращает индекс добавленого элемента.
function IndexOf(Value:string):integer; Возвращает индекс первого встреченого значения Value. Если ничего не нашла то возвращает -1. Для поиска следующего значения можно использовать функцию IndexOfFrom
function IndexOfFrom(Value:string;Start:integer):integer; Возвращает индекс значения Value, поиск начинает с элемента с индексом Start. Если ничего не нашла то возвращает -1. Используется для инкрементального поиска.

THArrayWideStrings

Массив для хранения строк в формате Unicode (WideString в Delphi).


Свойства
property Value[Index:integer]:WideString; default; Извлекает либо устанавливает значение по индексу. Если индекс не существует то выдает исключение ERangeError.
Методы
function AddValue(Value:WideString):integer; Добавляет значение Value в конец массива. Возвращает индекс добавленого элемента.
function IndexOf(Value:WideString):integer; Возвращает индекс первого встреченого значения Value. Если ничего не нашла то возвращает -1. Для поиска следующего значения можно использовать функцию IndexOfFrom
function IndexOfFrom(Value:WideString;Start:integer):integer; Возвращает индекс значения Value, поиск начинает с элемента с индексом Start. Если ничего не нашла то возвращает -1. Используется для инкрементального поиска.