Not logged in.  Login/Logout/Register | List snippets | | Create snippet | Upload image | Upload data

141
LINES

< > BotCompany Repo | #1031652 // PersistentManagedObjects_v1

JavaX fragment (include) [tags: use-pretranspiled]

Uses 11335K of libraries. Click here for Pure Java version (6107L/38K).

sclass PersistentManagedObjects_v1<A extends IManagedObject> {
  replace Addr with int.
  replace BoxedAddr with Int.
  
  ManagedIntObjects_v1 mem;
  IF2<ManagedIntObjects_v1, BoxedAddr, A> makeUserObject; // user needs to fill this
  Root root;
  
  final static int
    TYPE_STRING = -1,
    TYPE_INTARRAY = -2,
    TYPE_ROOT = -3;
  
  class Root extends AbstractManagedObject {
    final static int
      ofs_type = 0,
      ofs_version = 1,
      ofs_freeListPtr = 2,
      ofs_userDataPtr = 3;
    final static int objectSize = ofs_userDataPtr+1;
    
    ManagedIntObjects_v1 mem() { ret PersistentManagedObjects_v1.this.mem; }
    
    // initialize as wrapper for existing object
    // or create new when addr == 0
    *(Addr addr) {
      super(PersistentManagedObjects_v1.this.mem);
      if (addr != 0)
        setAddr(addr);  
      else
        create();
    }
    
    // initialize as new object
    *() {
      super(PersistentManagedObjects_v1.this.mem);
      create();
    }
    
    void create { setAddr(mem.alloc(objectSize)); init(); }
    
    void init { type(TYPE_ROOT); version(1); }
    
    // getters + setters
    int type() { ret mem.get(addr+ofs_type); }
    void type(int x) { mem.set(addr+ofs_type, x); }
    int version() { ret mem.get(addr+ofs_version); }
    void version(int x) { mem.set(addr+ofs_version, x); }
    Addr freeListPtr() { ret mem.get(addr+ofs_freeListPtr); }
    void freeListPtr(Addr x) {
      mem.set(addr+ofs_freeListPtr, x);
      print("Free list moved to " + x + " (length=" + (x == 0 ? 0 : mem.get(x)) + ")");
    }
    Addr userDataPtr() { ret mem.get(addr+ofs_userDataPtr); }
    void userDataPtr(Addr x) { mem.set(addr+ofs_userDataPtr, x); }
    A userData() {
      ret makeUserObject.get(mem, userDataPtr());
    }
    void userData(A userData) { userDataPtr(userData == null ? 0 : userData.addr()); }
    
    public void setAddr(Addr newAddr) {
      addr = newAddr; mem.setRootField(addr);
    }

    // GC handling
    public void scanForCollection(IManagedObjectCollector gc) {
      deb()?.printVars("scanForCollection", +this, +addr, +objectSize);
      gc.noteObject(0, 1, null);
      gc.noteRootPointer(0);
      gc.noteObject(addr, objectSize, lambda1 setAddr);
      //print("note freeList");
      //gc.notePointer(addr+ofs_freeListPtr);
      //gc.noteIntArray(freeListPtr()); // we're dropping it anyway (it's a compaction)
      
      print("note userDataPtr");
      gc.notePointer(addr+ofs_userDataPtr);
      var userData = userData();
      deb()?.printVars("note", +userData);
      userData?.scanForCollection(gc);
    }
  }
  
  // makes a new int[] based storage
  *(IF2<ManagedIntObjects_v1, BoxedAddr, A> makeUserObject) {
    this(new ManagedIntObjects_v1, makeUserObject);
  }
  
  *(ManagedIntObjects_v1 *mem, IF2<ManagedIntObjects_v1, BoxedAddr, A> *makeUserObject) {
    Addr rootPtr = mem.getRootField();
    print(+rootPtr);
    root = new Root(rootPtr);
    mem.freeList = FreeList.fromIntArray(mem.readIntArray(root.freeListPtr()));
  }
  
  void flush {
    if (mem.freeList.changed)
      saveFreeList();
  }
  
  void saveFreeList {
    print("Freeing old free list at " + root.freeListPtr());
    mem.freeIntArray(root.freeListPtr());
    int arraySize = (mem.freeList.size()+1)*2; // reserve space for one more entry made in the upcoming freeIntArray() call
    int sizeNeeded = 1+arraySize;
    deb()?.printVars(+arraySize, +sizeNeeded);
    Addr ptr = mem.alloc(sizeNeeded);
    deb()?.printVars(+ptr);
    mem.set(ptr, arraySize); // set length

    // now all the allocs and frees are done and we can persist
    // the FreeList
    int[] data = mem.freeList.toIntArray();
    mem.freeList.changed = false;
    
    for i to arraySize:
      mem.set(ptr+1+i, i < data.length ? data[i] : 0); // pad with zeros
    root.freeListPtr(ptr);
    print("Made new free list at " + root.freeListPtr() + " (l=" + mem.read(root.freeListPtr()) + ")");
  }
  
  A get aka getUserData() {
    ret root.userData();
  }
  
  void set aka setUserData(A userData) {
    root.userData(userData);
  }

  PersistentManagedObjects_v1<A> rotate() {
    flush();
    ret new PersistentManagedObjects_v1(mem.rotate(), makeUserObject);
  }
  
  void collectAndCompact {
    ManagedIntObjects_v1_Collector collector = new(mem);
    collector.startAddress = 0;
    mem.collectAndCompact(root, collector);
    print("Resetting freeListPtr");
    root.freeListPtr(0);
  }
}

download  show line numbers  debug dex  old transpilations   

Travelled to 4 computer(s): bhatertpkbcr, mqqgnosmbjvj, pyentgdyhuwx, vouqrxazstgt

No comments. add comment

Snippet ID: #1031652
Snippet name: PersistentManagedObjects_v1
Eternal ID of this version: #1031652/42
Text MD5: b594dad86c45123220f9d50bed1b7190
Transpilation MD5: e51b550b76b24ca804c6e98e7c165e2c
Author: stefan
Category: javax
Type: JavaX fragment (include)
Public (visible to everyone): Yes
Archived (hidden from active list): No
Created/modified: 2021-06-25 13:14:17
Source code size: 4598 bytes / 141 lines
Pitched / IR pitched: No / No
Views / Downloads: 308 / 621
Version history: 41 change(s)
Referenced in: #1034167 - Standard Classes + Interfaces (LIVE, continuation of #1003674)