1.9「Motoko——Actor classes」

1.9「Motoko——Actor classes」

Actor classes:

Actor classes allow you to programmatically create canister smart contracts. Currently, actor classes have to be defined in a single .mo source file. In order to illustrate how to define and import (import) actor classes, the following example demonstrates a distributed map with Nat type as key mapped to Text type. It provides simple insert put(k, v)and query functions get(k)for manipulating these keys and values.

To distribute the data for this example, a list of key values ​​is divided into n buckets. Now, we just set n = 8. The container i corresponding to the key value k is determined by the remainder of dividing n by k, ie i = k % n. The i-th container ( i in [0…n) ) accepts an assigned actor to store the text value corresponding to the key.

The actor responsible for the ith container is Bucket(i)obtained as an instance of the actor class, as defined in the sample Buckets.mo file:

import Nat "mo:base/Nat";
import Map "mo:base/RBTree";

actor class Bucket(n : Nat, i : Nat) {
    
    

  type Key = Nat;
  type Value = Text;

  let map = Map.RBTree<Key, Value>(Nat.compare);

  public func get(k : Key) : async ?Value {
    
    
    assert((k % n) == i);
    map.get(k);
  };

  public func put(k : Key, v : Value) : async () {
    
    
    assert((k % n) == i);
    map.put(k,v);
  };

};

A bucket stores the current mapping of keys to values in a mutable map variable containing an imperative RedBlack tree, map, that is initially empty.

On get(k), the bucket actor simply returns any value stored at k, returning map.get(k).

On put(k, v), the bucket actor updates the current map to map k to ?v by calling map.put(k, v).

Both functions use the class parameters n and i to verify that the key is appropriate for the bucket by asserting ((k % n) == i).

Users of the map can then interact with it through the Map actor, as follows:

import Array "mo:base/Array";
import Buckets "Buckets";

actor Map {
    
    

  let n = 8; // number of buckets

  type Key = Nat;
  type Value = Text;

  type Bucket = Buckets.Bucket;

  let buckets : [var ?Bucket] = Array.init(n, null);

  public func get(k : Key) : async ?Value {
    
    
    switch (buckets[k % n]) {
    
    
      case null null;
      case (?bucket) await bucket.get(k);
    };
  };

  public func put(k : Key, v : Value) : async () {
    
    
    let i = k % n;
    let bucket = switch (buckets[i]) {
    
    
      case null {
    
    
        let b = await Buckets.Bucket(n, i); // dynamically install a new Bucket
        buckets[i] := ?b;
        b;
      };
      case (?bucket) bucket;
    };
    await bucket.put(k, v);
  };

};

As this example illustrates, the Map code imports the Bucket actor class as module Buckets.

The actor maintains an array of n allocated buckets, with all entries initially null. Entries are populated with Bucket actors on demand.

On get(k, v), the Map actor:

  • uses the remainder of key k divided by n to determine the index i of the bucket responsible for that key
  • returns null if the ith bucket does not exist, or
  • delegates to that bucket by calling bucket.get(k, v) if it does.

On put(k, v), the Map actor:

  • uses the remainder of key k divided by n to determine the index i of the bucket responsible for that key
  • installs bucket i if the bucket does not exist by using an asynchronous call to the constructor, Buckets.Bucket(i), and, after awaiting the result, records it in the array buckets
  • delegates the insertion to that bucket by calling bucket.put(k, v).

While this example sets the number of buckets to 8, you can easily generalize the example by making the Map actor an actor class, adding a parameter (n : Nat) and omitting the declaration let n = 8;. For example:

actor class Map(n : Nat) {
    
    

  type Key = Nat
  ...
}

Users of the Map actor class can now freely determine the (maximum) number of containers in the network by passing a parameter when constructing the actor.

Vehicle NFT_2
- Motoko-

Guess you like

Origin blog.csdn.net/qq_29810031/article/details/123226838