TSynDictionary

TSynDictionary

mormot.core.json.pas

/// thread-safe dictionary to store some values from associated keys
// - will maintain a dynamic array of values, associated with a hash table
// for the keys, so that setting or retrieving values would be O(1)
// - all process is protected by a TSynLocker, so will be thread-safe
// - TDynArray is a wrapper which do not store anything, whereas this class
// is able to store both keys and values, and provide convenient methods to
// access the stored data, including JSON serialization and binary storage
TSynDictionary = class(TSynLocked)

///线程安全的字典,用于存储关联键的一些值

// -将维护一个与散列表关联的动态值数组

//用于键,因此设置或检索值将是O(1)

// -所有进程都由TSynLocker保护,因此是线程安全的

// - TDynArray是一个包装器,它不存储任何东西,而这个类

//能够存储键和值,并提供方便的方法

//访问存储的数据,包括JSON序列化和二进制存储

procedure TTestCoreBase._TSynDictionary;
type
  tvalue = variant;

  tvalues = TVariantDynArray;
const
  MAX = 10000;
var
  dict: TSynDictionary;

  procedure Test;
  var
    k: RawUTF8;
    v: tvalue;
    i: integer;
  begin
    check(dict.Count = MAX);
    for i := 1 to MAX do
    begin
      UInt32ToUTF8(i, k);
      v := 0;
      check(dict.Exists(k));
      check(dict.FindAndCopy(k, v));
      check(v = i);
    end;
  end;

var
  v: tvalue;
  s, k: RawUTF8;
  i: integer;
  exists: boolean;
begin
  dict := TSynDictionary.Create(TypeInfo(TRawUTF8DynArray), TypeInfo(tvalues));
  try
    for i := 1 to MAX do
    begin
      UInt32ToUTF8(i, k);
      v := i;
      check(dict.Add(k, v) = i - 1);
    end;
    Test;
    s := dict.SaveToJSON;
    check(dict.Exists(k));
    dict.DeleteAll;
    check(dict.Count = 0);
    check(not dict.Exists(k));
    check(dict.LoadFromJSON(s));
    Test;
    s := dict.SaveToBinary;
  finally
    dict.Free;
  end;
  dict := TSynDictionary.Create(TypeInfo(TRawUTF8DynArray), TypeInfo(tvalues));
  try
    check(dict.LoadFromBinary(s));
    Test;
    for i := MAX downto 1 do
      if i and 127 = 0 then
      begin
        UInt32ToUTF8(i, k);
        check(dict.Delete(k) = i - 1);
        check(dict.Exists(k) = false);
      end;
    for i := 1 to MAX do
    begin
      exists := (i and 127) <> 0;
      UInt32ToUTF8(i, k);
      check(dict.Exists(k) = exists);
      if exists then
      begin
        v := 0;
        check(dict.FindAndCopy(k, v));
        check(v = i);
        if i < 10000 then
        begin // FindKeyFromValue() brute force is slow
          k := '';
          check(dict.FindKeyFromValue(v, k));
          check(GetInteger(pointer(k)) = i);
        end;
      end;
    end;
  finally
    dict.Free;
  end;
end;

  

 

posted @ 2020-12-02 11:42  delphi中间件  阅读(498)  评论(0编辑  收藏  举报