Implemented Enhanced Pools

PixelPaladin

Active Member
CX Code Contributor
3rd Party Module Dev
Joined
Aug 27, 2017
Likes
47
Location
Germany
#1
Hello,

I had an idea how pools could be enhanced. Here is my concept:
Code:
Class Pool<T>
   
    Private
   
    Field _pool := New Stack<T>
   
    Global _HasOnPoolAllocate:Int = Pool<T>.UNKNOWN
    Global _HasOnPoolFree:Int     = Pool<T>.UNKNOWN
   
    Const UNKNOWN:Int = 0
    Const YES:Int     = 1
    Const NO:Int      = 2
   
    Public
   
    Method New(initialCapacity:Int = 10)
        For Local i:Int = 0 Until initialCapacity
            _pool.Push New T
        Next
    End
   
    Method Allocate:T()
        Local o:T
        If _pool.IsEmpty() Then
            o = New T
        Else
            o = _pool.Pop()
        End
       
        Select _HasOnPoolAllocate
        Case YES
            IOnPoolAllocate(o).OnPoolAllocate()
        Case UNKNOWN
            _HasOnPoolAllocate = NO
            If IOnPoolAllocate(o) Then
                _HasOnPoolAllocate = YES
                IOnPoolAllocate(o).OnPoolAllocate()
            End
        End
       
        Return o
    End
   
    Method Free:Void(o:T)
        Select _HasOnPoolFree
        Case YES
            IOnPoolFree(o).OnPoolFree()
        Case UNKNOWN
            _HasOnPoolFree = NO
            If IOnPoolFree(o) Then
                _HasOnPoolFree = YES
                IOnPoolFree(o).OnPoolFree()
            End
        End
       
        _pool.Push(o)
    End
End

Interface IOnPoolAllocate
    Method OnPoolAllocate:Void()
End

Interface IOnPoolFree
    Method OnPoolFree:Void()
End
My pool class is still compatible with the current brl pools. The difference is that if a class implements the IOnPoolAllocate interface an initialization method will automatically be called when Pool.Allocate() will be called (same goes for IOnPoolFree when Pool.Free() will be called).
So like constructors/destructors this can be used to initialize and clean up objects automatically.

Here is how it can be used:
Code:
Class Foo Implements IOnPoolAllocate, IOnPoolFree
    Method OnPoolAllocate:Void()
        Print "init stuff"
    End
   
    Method OnPoolFree:Void()
        Print "clean up stuff"
    End
End

Function Main:Int()
    Local FooPool := New Pool<Foo>
    Local bar := FooPool.Allocate() ' => prints "init stuff"
    FooPool.Free(bar)               ' => prints "clean up stuff"
    Return 0
End
 

PixelPaladin

Active Member
CX Code Contributor
3rd Party Module Dev
Joined
Aug 27, 2017
Likes
47
Location
Germany
#4
Does your version have an impact on performance?
Not really. When the first element gets allocated/freed it looks if IonPoolAllocate/IOnPoolFree is implemented and remembers this in two globals for each generic pool class (2 integers for class Pool<Int> Pool<Foo>, 2 for class Pool<String> Pool<Bar>, …). Because this information gets stored, this check (and with it the slow casting operation) only happens once. When allocating/freeing more objects it just looks at these globals. That means the overhead for storing the additional information is minimal as well as the performance impact.
It also should not interfere with any existing code.
 
Last edited:

MikeHart

Administrator
Staff member
Joined
Jun 19, 2017
Likes
427
Location
Germany
#5
Cool. Then get to work. It would be cool to provide an example and extend the docs.
 
Last edited:

PixelPaladin

Active Member
CX Code Contributor
3rd Party Module Dev
Joined
Aug 27, 2017
Likes
47
Location
Germany
#8
Still waiting for your push request :)
The Pool library is nothing more than what I posted. I still need to add the documentation and write examples.
I am not sure if it is right to change the brl libraries since code from the community is not really related to brl. Maybe we should provide a module with all the functionality added by the community. So instead of importing brl.pool people would import whatever.pool. This would also prevent conflicts with existing code (maybe there is something we did not think of at the moment).
 

Holzchopf

Moderator
Staff member
Joined
Jul 31, 2017
Likes
152
Location
Bern, Switzerland
#9
I understand your concerns. But what if brl.pool is used by some other modules, and then, when you import mywhatever.pool, you have the pool features imported twice (OK, for simple stuff, this won't really increase file size). Or you have conflicts because both brl's and mywhatever's pool class is just named Pool. Or they're named differently and therefore you lose a bit of compatibility. Best would probably be if mywhatever's pool extends brl's pool - but following this mentality, you will almost for sure encounter the case where SOMEONE was overly generous with Private and Final and stuff and you have to modify the brl sources anyway to make the base class extensible.

Just some thoughts.

I think I never used pools so far, so I don't really have an opinion about if the extra functionality is worth the tiny bit of impact on performance. My guess is it is.
 

MikeHart

Administrator
Staff member
Joined
Jun 19, 2017
Likes
427
Location
Germany
#10
The Pool library is nothing more than what I posted. I still need to add the documentation and write examples.
I am not sure if it is right to change the brl libraries since code from the community is not really related to brl. Maybe we should provide a module with all the functionality added by the community. So instead of importing brl.pool people would import whatever.pool. This would also prevent conflicts with existing code (maybe there is something we did not think of at the moment).
Ahh ok. As it was posted in the suggestion section to improve Cx I thought you want to add it to the repro. but I understand you concerns, even I don't share them. BRL is just a name.
Then just release it on your own as an external module. I glady will add it to the modules page if you want me to.
 
Last edited:

MikeHart

Administrator
Staff member
Joined
Jun 19, 2017
Likes
427
Location
Germany
#11
Adding to this, shipping Cx with 2 versions of a Pool make no sense imho. I hate it already that we have 2 versions of mojo.
 

PixelPaladin

Active Member
CX Code Contributor
3rd Party Module Dev
Joined
Aug 27, 2017
Likes
47
Location
Germany
#12
Seems like I cannot work with the cerberus git repo. I even tried to clone it again. Whenever I try to pull from the upstream repo it tells me that I should commit my changes first or stash them. When I stash them git keeps telling me the same stuff. The problem has something to do with how git handles the line endings. The problem file is this one:
Code:
targets/winrt_winphone8/template/MainPage.xaml.cs
This is the message I get:
Code:
error: Your local changes to the following files would be overwritten by merge:
   targets/winrt_winphone8/template/MainPage.xaml.cs
Please, commit your changes or stash them before you can merge.
Aborting
EDIT: nevermind - works now ...
 
Last edited:

Gerry Quinn

Active Member
Joined
Jun 24, 2017
Likes
44
#14
I always felt "brl" was a odd choice of name for what were supposed to be standard modules. Obviously it stands for Blitz Research - but it's still just a acronymic library name. If people don't want to change it and everything in it, best just use it as a codename that was chosen that might not be up to date with stuff that happened since.
 
Top Bottom