All Projects → goki → Ki

goki / Ki

Licence: bsd-3-clause
Go language (golang) full strength tree structures (ki in Japanese)

Programming Languages

go
31211 projects - #10 most used programming language
golang
3204 projects

Projects that are alternatives of or similar to Ki

Containers
This library provides various containers. Each container has utility functions to manipulate the data it holds. This is an abstraction as to not have to manually manage and reallocate memory.
Stars: ✭ 125 (+104.92%)
Mutual labels:  data-structures, tree, tree-structure
Buckets Js
A complete, fully tested and documented data structure library written in pure JavaScript.
Stars: ✭ 1,128 (+1749.18%)
Mutual labels:  data-structures, tree, tree-structure
Angular2 Tree Diagram
Angular Hierarchical UI module
Stars: ✭ 50 (-18.03%)
Mutual labels:  tree, tree-structure
Data Structure Php Clanguage
对于数据结构和算法类的东西,我工作有些年份了,大学也有所涉猎,积累了一些内容,不高产不母猪,打我自己脸
Stars: ✭ 299 (+390.16%)
Mutual labels:  data-structures, tree-structure
Java Algorithms Implementation
Algorithms and Data Structures implemented in Java
Stars: ✭ 3,927 (+6337.7%)
Mutual labels:  data-structures, tree
Javascript Datastructures Algorithms
📚 collection of JavaScript and TypeScript data structures and algorithms for education purposes. Source code bundle of JavaScript algorithms and data structures book
Stars: ✭ 3,221 (+5180.33%)
Mutual labels:  data-structures, tree
Data Structures Algorithms
My implementation of 85+ popular data structures and algorithms and interview questions in Python 3 and C++
Stars: ✭ 273 (+347.54%)
Mutual labels:  data-structures, tree
Wmderland
🌳 X11 tiling window manager using space partitioning trees
Stars: ✭ 341 (+459.02%)
Mutual labels:  tree, tree-structure
prune
A tree library for Java 8 with functional sensibilities.
Stars: ✭ 22 (-63.93%)
Mutual labels:  tree, tree-structure
Bosket
Collection of tree view components for front-end frameworks. 🌳
Stars: ✭ 457 (+649.18%)
Mutual labels:  tree, tree-structure
C Sharp Algorithms
📚 📈 Plug-and-play class-library project of standard Data Structures and Algorithms in C#
Stars: ✭ 4,684 (+7578.69%)
Mutual labels:  data-structures, tree
Algorithms and data structures
180+ Algorithm & Data Structure Problems using C++
Stars: ✭ 4,667 (+7550.82%)
Mutual labels:  data-structures, tree
Data-structures
Data Structures in Java
Stars: ✭ 13 (-78.69%)
Mutual labels:  data-structures, tree-structure
tree-json-generator
Simple JavaScript Tree Generator library
Stars: ✭ 13 (-78.69%)
Mutual labels:  tree, tree-structure
Rubytree
A General Purpose Tree Data Structure for Ruby
Stars: ✭ 300 (+391.8%)
Mutual labels:  data-structures, tree
react-treefold
A renderless tree component for your hierarchical React views
Stars: ✭ 37 (-39.34%)
Mutual labels:  tree, tree-structure
Data Structures
Go datastructures.
Stars: ✭ 336 (+450.82%)
Mutual labels:  data-structures, tree
Algorithms
Study cases for Algorithms and Data Structures.
Stars: ✭ 32 (-47.54%)
Mutual labels:  data-structures, tree
treetime
TreeTime is a data organisation, management and analysis tool. A tree is a hierarchical structure that arranges information in units and sub-units. TreeTime uses linked trees (one data item can be part of different distinct trees) to store and organise any general purpose data.
Stars: ✭ 26 (-57.38%)
Mutual labels:  tree, tree-structure
stefano-tree
Framework agnostic Nested Set (MPTT) implementation for PHP
Stars: ✭ 24 (-60.66%)
Mutual labels:  tree, tree-structure

alt tag

Go language (golang) tree structure (ki = 木 = tree in Japanese)

Go Report Card GoDoc Travis

Overview

See the Wiki for more docs, and Google Groups goki-gi emailing list.

The Tree is one of the most flexible, widely-used data structures in programming, including the DOM structure at the core of a web browser, scene graphs for 3D and 2D graphics systems, JSON, XML, SVG, filesystems, programs themselves, etc. This is because trees can capture most relevant forms of structure (hierarchical groupings, categories, relationships, etc) and are most powerful when they are fully generative -- arbitrary new types can be inserted flexibly.

GoKi provides a general-purpose tree container type, that can support all of these applications, by embedding and extending the Node struct type that implements the Ki (Ki = Tree in Japanese) interface. Unlike many cases in Go, the need to be able to arbitrarily extend the type space of nodes in the tree within a consistent API, means that the more traditional object-oriented model works best here, with a single common base type, and derived types that handle diverse cases (e.g., different types of widgets in a GUI). GoKi stores a Ki interface of each node, enabling correct virtual function calling on these derived types.

A virtue of using an appropriate data representation is that some important operations can be performed particularly concisely and efficiently when they are naturally supported by the data structure. For example, matrices and vectors as supported by numpy or MATLAB provide a concise high-level language for expressing many algorithms.

For trees, GoKi leverages the tree structure for automatically computing the appropriate extent of a scenegraph that needs to be updated, with an arbitrary sequence of individual operations, by propagating updating flags through the tree, and tracking the "high water mark" (see UpdateStart / End). This makes the GoGi GUI efficient in terms of what needs to be redrawn, while keeping the code local and simple.

In addition, GoKi provides functions that traverse the tree in the usual relevant ways ("natural" me-first depth-first, me-last depth-first, and breadth-first) and take a func function argument, so you can easily apply a common operation across the whole tree in a transparent and self-contained manner, like this:

func (n *MyNode) DoSomethingOnMyTree() {
	n.FuncDownMeFirst(0, nil, func(k Ki, level int, d interface{}) bool {
		mn := KiToMyNode(k)
		mn.DoSomething()
		...
		return ki.Continue // return value determines whether tree traversal continues or not
	})
}

Many operations are naturally expressed in terms of these traversal algorithms.

Three core GoKi features include:

  • A Signal mechanism that allows nodes to communicate changes and other events to arbitrary lists of other nodes (similar to the signals and slots from Qt).

  • UpdateStart() and UpdateEnd() functions that wrap around code that changes the tree structure or contents -- these automatically and efficiently determine the highest level node that was affected by changes, and only that highest node sends an Updated signal. This allows arbitrarily nested modifications to proceed independently, each wrapped in their own Start / End blocks, with the optimal minimal update signaling automatically computed.

  • ConfigChildren uses a list of types and names and performs a minimal, efficient update of the children of a node to configure them to match (including no changes if already configured accordingly). This is used during loading from JSON, and extensively in the GoGi GUI system to efficiently re-use existing tree elements. There is often complex logic to determine what elements need to be present in a Widget, so separating that out from then configuring the elements that actually are present is efficient and simplifies the code.

In addition, Ki nodes support a general-purpose Props property map, and the kit (Ki Types) package provides a TypeRegistry and an EnumRegistry, along with various reflect utilities, to enable fully-automatic saving / loading of Ki trees from JSON or XML, including converting const int (enum) values to / from strings so those numeric values can change in the code without invalidating existing files.

Ki Nodes can be used as fields in a struct -- they function much like pre-defined Children elements, and all the standard FuncDown* iterators traverse the fields automatically. The Ki Init function automatically names these structs with their field names, and sets the parent to the parent struct. This was essential in the GoKi framework to support separate Widget Parts independent of the larger scenegraph.

GoGi Graphical Interface and Gide IDE App

The first and most important application of GoKi is the GoGi graphical interface system, in the gi package, and the Gide IDE built on top of GoGi. The scene graph of Ki elements automatically drives minimal refresh updates, and the signaling framework supports gui event delivery and e.g., the "onclick" event signaling from the Button widget, etc. In short, GoGi provides a complete interactive 2D and 3D GUI environment in native Go, in a compact codebase. Part of this is the natural elegance of Go, but GoKi enhances that by providing the robust natural primitives needed to express all the GUI functionality. Because GoGi is based around standard CSS styles, SVG rendering, and supports all the major HTML elements, it could even provide a lightweight web browser: Glide.

The GoPi interactive parsing framework also leverages GoKi trees to represent the AST (abstract syntax tree) of programs in different langauges. Further, the parser grammar itself is written (in a GUI interactive way) as a tree of parsing elements using Ki nodes.

Code Map

  • kit package: kit.Types TypeRegistry provides name-to-type map for looking up types by name, and types can have default properties. kit.Enums EnumRegistry provides enum (const int) <-> string conversion, including bitflag enums. Also has robust generic kit.ToInt kit.ToFloat etc converters from interface{} to specific type, for processing properties, and several utilities in embeds.go for managing embedded structure types (e.g., TypeEmbeds checks if one type embeds another, and EmbeddedStruct returns the embedded struct from a given struct, providing flexible access to elements of an embedded type hierarchy -- there are also methods for navigating the flattened list of all embedded fields within a struct). Also has a kit.Type struct that supports saving / loading of type information using type names.

  • walki package provides tree-walking methods for more ad-hoc, special-case tree traversal, as compared to the standard Func* methods on Ki itself.

  • bitflag package: simple bit flag setting, checking, and clearing methods that take bit position args as ints (from const int eunum iota's) and do the bit shifting from there

  • ki.go = Ki interface for all major tree node functionality.

  • slice.go = ki.Slice []Ki supports saving / loading of Ki objects in a slice, by recording the size and types of elements in the slice -- requires kit.Types type registry to lookup types by name.

  • props.go = ki.Props map[string]interface{} supports saving / loading of property values using actual struct types and named const int enums, using the kit type registries. Used for CSS styling in GoGi.

  • signal.go = Signal that calls function on a receiver Ki objects that have been previously Connected to the signal -- also supports signal type so the same signal sender can send different types of signals over the same connection -- used for signaling changes in tree structure, and more general tree updating signals.

Status

  • Feb, 2021: version 1.1.0 reflects major simplification pass to reduce API footprint and remove separate Unique names (names should in general be unique -- add a separate non-unique name where needed). Now that GoGi etc is complete, could get rid if quite a few things.

  • April, 2020: version 1.0.0 release -- all stable and well tested.

Trick for fast finding in a slice

GoKi takes an extra starting index arg for all methods that lookup a value in a slice, such as ChildByName. The search for the item starts at that index, and goes up and down from there. Thus, if you have any idea where the item might be in the list, it can save (considerable for large lists) time finding it.

Furthermore, it enables a robust optimized lookup map that remembers these indexes for each item, but then always searches from the index, so it is always correct under list modifications, but if the list is unchanged, then it is very efficient, and does not require saving pointers, which minimizes any impact on the GC, prevents stale pointers, etc.

The IndexInParent() method uses this trick, using the cached Node.index value.

Here's example code for a separate Find method where the indexes are stored in a map:

// FindByName finds item by name, using cached indexes for speed
func (ob *Obj) FindByName(nm string) *Obj {
	if sv.FindIdxs == nil {
		ob.FindIdxs = make(map[string]int) // field on object
	}
	idx, has := ob.FindIdxs[nm]
	if !has {
		idx = len(ob.Kids) / 2 // start in middle first time
	}
	idx, has = ob.Kids.IndexByName(nm, idx)
	if has {
		ob.FindIdxs[nm] = idx
		return ob.Kids[idx].(*Obj)
  	}
	delete(ob.FindIdxs, nm) // must have been deleted
	return nil
}
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].