Skip to content

Commit

Permalink
Merge pull request #53 from webability-go/late-night
Browse files Browse the repository at this point in the history
v2.0.0
  • Loading branch information
metalwolf committed Mar 29, 2020
2 parents 7719a91 + 6086008 commit 0fc53ee
Show file tree
Hide file tree
Showing 13 changed files with 1,992 additions and 332 deletions.
31 changes: 23 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,31 +4,46 @@
[![GoDoc](https://godoc.org/github.com/webability-go/xcore?status.png)](https://godoc.org/github.com/webability-go/xcore)
[![GolangCI](https://golangci.com/badges/github.com/webability-go/xcore.svg)](https://golangci.com)

XCore for GO v1
XCore for GO v2
=============================

The XCore package is used to build basic object for programmation. for the WebAbility compatility code
For GO, the actual existing code includes:
- XCache: Application Memory Caches
- XDataset: Basic nested data structures for any purpose (template injection, configuration files, database records, etc)
- XLanguage: language dependent text tables
- XTemplate: template system with meta language
- XCache: Application Memory Caches, thread safe.
- XDataset: Basic nested data structures for any purpose (template injection, configuration files, database records, etc) Support thread safe operations on thread safe structures (XDatasetTS and XDatasetCollectionTS)
- XLanguage: language dependent text tables, thread safe
- XTemplate: template system with meta language, thread safe cloning

Manuals are available on godoc.org [![GoDoc](https://godoc.org/github.com/webability-go/xcore?status.png)](https://godoc.org/github.com/webability-go/xcore)


TO DO:
======
- XDataset.Set should accept path too > > >
- Get*Collection should convert types too
- XTemplate must concatenate strings after compilation
- Implements functions as data entry for template Execute (simple data or loop functions, can get backs anything, creates an interface)
- Some improvements to check, later:
Adds mutex on XLanguage, XDataset, XTemplate ?? (they should be used locally on every thread, or not ??), maybe adds a flag "thread safe" ?
XCache: activate persistant cache too (shared memory) ????? maybe not for go itself, but for instance to talk with other memory data used by other languages and apps, or to not loose the caches if the app is restarted.
Some improvements to check, later:
- Adds mutex on XLanguage, XDataset, XTemplate ?? (they should be used locally on every thread, or not ??), maybe adds a flag "thread safe" ?
- XCache: activate persistant cache too (shared memory) ????? maybe not for go itself, but for instance to talk with other memory data used by other languages and apps, or to not loose the caches if the app is restarted.


Version Changes Control
=======================

v2.0.0 - 2020-03-29
-----------------------
- xdataset.go now as a coverage of 100% with xdataset_test.go
- XCache now uses R/W mutex
- New interfaces.go file to keep all the interfaces in it (XDatasetDef, XDatasetCollectionDef)
- New xdatasetts.go for thread safe dataset
- New xdatasetts_test.go for thread safe dataset tests
- New xdatasetcollection.go for the collection of dataset (separation from xdataset.go)
- New xdatasetcollection_test.go for collection tests
- New xdatasetcollectionts.go for thread safe dataset
- New xdatasetcollectionts_test.go for thread safe datasetcollection tests
- XLanguage is now thread safe with R/W mutexes

v1.1.0 - 2020-03-01
-----------------------
- Modularization of XCore
Expand Down
100 changes: 100 additions & 0 deletions interfaces.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
package xcore

import (
"fmt"
"time"
)

// XDatasetDef is a special interface to implement a set of data that can be scanned recursively (by XTemplate for instance)
// to search data into it, Stringify it, and set/get/del entries of data
// The get* methods must accept a path id>id>id...
type XDatasetDef interface {
// Stringify will dump the content into a human readable string
fmt.Stringer // please implement String()
fmt.GoStringer // Please implement GoString()

// Set will associate the data to the key. If it already exists, it will be replaced
Set(key string, data interface{})

// Get will return the value associated to the key if it exists, or bool = false
Get(key string) (interface{}, bool)
// Same as Get but will return the value associated to the key as a XDatasetDef if it exists, or bool = false
GetDataset(key string) (XDatasetDef, bool)
// Same as Get but will return the value associated to the key as a XDatasetCollectionDef if it exists, or bool = false
GetCollection(key string) (XDatasetCollectionDef, bool)

// Same as Get but will return the value associated to the key as a string if it exists, or bool = false
GetString(key string) (string, bool)
// Same as Get but will return the value associated to the key as a bool if it exists, or bool = false
GetBool(key string) (bool, bool)
// Same as Get but will return the value associated to the key as an int if it exists, or bool = false
GetInt(key string) (int, bool)
// Same as Get but will return the value associated to the key as a float64 if it exists, or bool = false
GetFloat(key string) (float64, bool)
// Same as Get but will return the value associated to the key as a Time if it exists, or bool = false
GetTime(key string) (time.Time, bool)
// Same as Get but will return the value associated to the key as a []String if it exists, or bool = false
GetStringCollection(key string) ([]string, bool)
// Same as Get but will return the value associated to the key as a []bool if it exists, or bool = false
GetBoolCollection(key string) ([]bool, bool)
// Same as Get but will return the value associated to the key as a []int if it exists, or bool = false
GetIntCollection(key string) ([]int, bool)
// Same as Get but will return the value associated to the key as a []float64 if it exists, or bool = false
GetFloatCollection(key string) ([]float64, bool)
// Same as Get but will return the value associated to the key as a []Time if it exists, or bool = false
GetTimeCollection(key string) ([]time.Time, bool)

// Del will delete the data associated to the key and deletes the key entry
Del(key string)
// Clone the object
Clone() XDatasetDef
}

// XDatasetCollectionDef is the definition of a collection of XDatasetDefs
type XDatasetCollectionDef interface {
// Stringify will dump the content into a human readable string
fmt.Stringer // please implement String()
fmt.GoStringer // Please implement GoString()

// Will add a datasetdef to the beginning of the collection
Unshift(data XDatasetDef)
// Will remove the first datasetdef of the collection and return it
Shift() XDatasetDef

// Will add a datasetdef to the end of the collection
Push(data XDatasetDef)
// Will remove the last datasetdef of the collection and return it
Pop() XDatasetDef

// Will count the quantity of entries
Count() int

// Will get the entry by the index and let it in the collection
Get(index int) (XDatasetDef, bool)

// Will search for the data associated to the key by priority (last entry is the most important)
// returns bool = false if nothing has been found
GetData(key string) (interface{}, bool)

// Same as GetData but will convert the result to a string if possible
// returns bool = false if nothing has been found
GetDataString(key string) (string, bool)
// Same as GetData but will convert the result to an int if possible
// returns bool = false if nothing has been found
GetDataInt(key string) (int, bool)
// Same as GetData but will convert the result to a boolean if possible
// returns second bool = false if nothing has been found
GetDataBool(key string) (bool, bool)
// Same as GetData but will convert the result to a float if possible
// returns bool = false if nothing has been found
GetDataFloat(key string) (float64, bool)
// Same as GetData but will convert the result to a Time if possible
// returns bool = false if nothing has been found
GetDataTime(key string) (time.Time, bool)
// Same as GetData but will convert the result to a XDatasetCollectionDef of data if possible
// returns bool = false if nothing has been found
GetCollection(key string) (XDatasetCollectionDef, bool)

// Clone the object
Clone() XDatasetCollectionDef
}
15 changes: 9 additions & 6 deletions xcache.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ type XCache struct {
Expire time.Duration
// Not available from outside for security, access of data is based on a mutex
// "mutex": The cache owns a mutex to lock access to data to read/write/delete/clean the data, to allow concurrency and multithreading of the cache.
mutex sync.Mutex
mutex sync.RWMutex
// "pile": The pile keeps the "ordered by date of reading" object keys, so it's fast to clean the data.
items map[string]*XCacheEntry
// "items": The items are a map to cache entries, acceved by the key of entries.
Expand Down Expand Up @@ -76,6 +76,7 @@ func (c *XCache) Set(key string, indata interface{}) {
}

// removeFromPile will remove an entry key from the ordered pile.
// No lock into this func since it has been set by entry func already
func (c *XCache) removeFromPile(key string) {
// removes the key and append it to the end
for i, x := range c.pile {
Expand All @@ -95,9 +96,9 @@ func (c *XCache) removeFromPile(key string) {
// If the entry exists and is invalidated by time or validator function, then returns nil, true.
// If the entry is good, return <value>, false.
func (c *XCache) Get(key string) (interface{}, bool) {
c.mutex.Lock()
c.mutex.RLock()
if x, ok := c.items[key]; ok {
c.mutex.Unlock()
c.mutex.RUnlock()
if c.Validator != nil {
if b := c.Validator(key, x.ctime); !b {
if LOG {
Expand All @@ -124,11 +125,13 @@ func (c *XCache) Get(key string) (interface{}, bool) {
}
}
x.rtime = time.Now()
c.mutex.Lock()
c.removeFromPile(key)
c.pile = append(c.pile, key)
c.mutex.Unlock()
return x.data, false
}
c.mutex.Unlock()
c.mutex.RUnlock()
return nil, false
}

Expand All @@ -143,9 +146,9 @@ func (c *XCache) Del(key string) {

// Count will return the quantity of entries in the cache.
func (c *XCache) Count() int {
c.mutex.Lock()
c.mutex.RLock()
x := len(c.items)
c.mutex.Unlock()
c.mutex.RUnlock()
return x
}

Expand Down
2 changes: 1 addition & 1 deletion xcore.go
Original file line number Diff line number Diff line change
Expand Up @@ -836,7 +836,7 @@
package xcore

// VERSION is the used version nombre of the XCore library.
const VERSION = "1.1.0"
const VERSION = "2.0.0"

// LOG is the flag to activate logging on the library.
// if LOG is set to TRUE, LOG indicates to the XCore libraries to log a trace of functions called, with most important parameters.
Expand Down

0 comments on commit 0fc53ee

Please sign in to comment.