Hoje enquanto modelava e implementava Notificação e Estado dos objetos no Jazz, tive a preocupação com a memória utilizada e com o desempenho. Na versão anterior eu utilizava Sets, mas a notificação e o status necessitavam melhorias.
Então me ocorreu a idéia de utilizar bit para identificar o Estado, desta forma, um byte seria suficiente para identificar todos os possíveis Estados de um objeto, foi então que postei no stackoverflow uma pergunta sobre como manipular bit “How use bit/bit-operator to control object state?”.
A pergunta foi respondida pelo Scott W que ainda deu a dica da pagina sobre Delphi Operators. Outros colegas também responderam sugerindo a utilização de Sets, e entre eles o Engenheiro do Compilador do Delphi Barry Kelly, que ainda explicou como o compilador do Delphi gera assembly para Sets.
Informações sobre Sets segundo Barry Kelly:
Utilizar Sets é a melhor técnica que utilizar operadores de bit. Eles não são mais leves, visto que Sets são compilados com o mesmo código de CPU que operações binárias.
A vantagem é que eles são mais seguros por que são verificados pelo compilador, enquanto operadores de bit são todos inteiros.
Neste caso como terei no máximo 8 itens, eles serão de tamanho máximo de 1 byte
A versão final utilizando Sets ficou assim,
Declaração dos possíveis estados:
TStateType = ( stLoaded = 0, // loaded from persistance stNative = 1, // value loaded and converted to native type stSaved = 2, // saved stChanged = 3, // object or member changed stDelete = 4, // marked to delete stNull = 5 // value is null ); TState = Set of TStateType;Você sabia que é possível definir o valor numérico de um item em Sets?
Armazenamento das informações:
PDataPackage = ^TDataPackage; TDataPackage = record Data: TBytes; TypeInfo: TMetaInfo; State: Byte; Instance: TBuffer; end;Estas são as informações enviadas entre cliente e servidor de aplicações para persistência e recuperação dos dados,
- Data contém os dados em Bytes;
- TypeInfo será convertido a apenas o nome da classe de implementação dos Metadados;
- State é apenas 1 Byte, contendo os possíveis valores de TState;
- Instance será ignorada, pois apenas representa a instância única no cliente ou no servidor, e será utilizada para notificação.
E para acessar as informações:
TValueType = class(TJazzObject, IValueType, IDataPackage) private FDataPackage: PDataPackage; ... end; function TValueType.IsNull: Boolean; begin Result:= stNull in TState(FDataPackage^.State); end;Como persistir TState
var State: TState; begin State:= [stChanged]; FDataPackage^.State:= Byte(State); end;Como TState tem menos de 8 ítens, pode ser persistido utilizando apenas 1 byte.