Commit af206304 authored by Jody Goldberg's avatar Jody Goldberg Committed by Jody Goldberg

Revamp the recalc queue

2001-05-22  Jody Goldberg <jgoldberg@home.com>

	* gnumeric.spec.in : bump version of libole2
	* README : ditto.
	* configure.in : ditto.

2001-05-19  Jody Goldberg <jgoldberg@home.com>

	* src/workbook.c (workbook_is_pristine) : no need to check the recalc
	  queue.  If there are no dependents there is nothing to put on the
	  eval queue.

	* src/func.c (cb_iterate_cellrange) : rename from
	  iterate_cellrange_callback remove 'generation' mechanism.

	* src/cell.c (cell_cleanout) : Clear both recalc flags,
	  in_queue and needs
	(cell_copy) : ditto.
	(cell_eval_content) : No need to render the value.  assign_value
	  already does it.
	(cell_content_changed) : deleted.

	* src/Makefile.am : merge dependent.[ch] into eval.[ch]

2001-05-18  Jody Goldberg <jgoldberg@home.com>

	* src/eval.c : reorg and merged with dependent.[ch]

	* src/sheet.c (sheet_cell_set_text) :
	  s/cell_content_changed/cell_queue_recalc/
	(sheet_cell_set_expr) : ditto.
	(sheet_cell_set_value) : ditto.
	(colrow_move) : ditto.
	(sheet_destroy_contents) :
	  s/dependent_unqueue_recalc_sheet/dependent_unqueue_sheet/

	* src/cmd-edit.c (cmd_select_cur_row) : Make behavior match XL.
	(cmd_select_cur_col) : Make behavior match XL.

	* src/format.c (render_number) : avoid temporaries.
	(do_render_number) : ditto.

2001-05-17  Jody Goldberg <jgoldberg@home.com>

	* src/expr.c (eval_range) : delete.
	(eval_expr_real) : Use workbook_foreach_cell_in_range rather than
	  range_eval.  Remove 'generation' mechanism.
	(cb_range_eval) : a simple pass through

	* src/eval.c (sheet_region_recalc_deps) : rename from
	  sheet_recalc_dependencies and merge in sheet_region_get_deps.
	  Use the new foreach style interfaces.
	(cb_single_recalc_all_depends) : rename from cb_single_get_all_depends
	  and simplify.
	(cb_range_recalc_all_depends) : rename from cb_sheet_get_all_depends and simplify.
	(cb_dependent_queue_recalc) : new wrapper.
	(cb_region_contained_depend) : renamed from search_range_deps and simplify.
	(cell_foreach_dep) : rename from cell_get_dependencies and switch to
	  an in place api rather than creating a list.
	(cell_foreach_single_dep) : switch to in place api
	(cell_foreach_range_dep) : ditto.
	(search_cell_deps) : ditto.
	(cell_recalc_deps) : ditto.
	(cell_eval) : ditto.
	(cb_generation_queue) : new utility.

	* src/dependent.c (dependent_list_filter) : delete.

	* src/cmd-edit.c (cb_collect_deps) : new function split from.
	(cmd_select_cur_depends) : here. So that we can use the new depend
	  api.

	* src/sheet.c (sheet_move_range) : use sheet_region_recalc_deps.
	(sheet_{insert,delete}_{cols,rows}) : ditto.
	(sheet_cell_remove_simple) : Use in place depend interface.

	* src/cell.c (cell_content_changed) : Use in place depend interface.
	* src/clipboard.c (clipboard_paste_region) : ditto.
	* src/commands.c (cmd_area_set_text_redo) : ditto.
	(cmd_autofill_redo) : ditto.

2001-05-21  Jody Goldberg <jgoldberg@home.com>

	* Makefile.am : remove gnorba and modernize a bit.
parent 645a9477
2001-05-22 Jody Goldberg <jgoldberg@home.com>
* gnumeric.spec.in : bump version of libole2
* README : ditto.
* configure.in : ditto.
2001-05-19 Jody Goldberg <jgoldberg@home.com>
* src/workbook.c (workbook_is_pristine) : no need to check the recalc
queue. If there are no dependents there is nothing to put on the
eval queue.
* src/func.c (cb_iterate_cellrange) : rename from
iterate_cellrange_callback remove 'generation' mechanism.
* src/cell.c (cell_cleanout) : Clear both recalc flags,
in_queue and needs
(cell_copy) : ditto.
(cell_eval_content) : No need to render the value. assign_value
already does it.
(cell_content_changed) : deleted.
* src/Makefile.am : merge dependent.[ch] into eval.[ch]
2001-05-18 Jody Goldberg <jgoldberg@home.com>
* src/eval.c : reorg and merged with dependent.[ch]
* src/sheet.c (sheet_cell_set_text) :
s/cell_content_changed/cell_queue_recalc/
(sheet_cell_set_expr) : ditto.
(sheet_cell_set_value) : ditto.
(colrow_move) : ditto.
(sheet_destroy_contents) :
s/dependent_unqueue_recalc_sheet/dependent_unqueue_sheet/
* src/cmd-edit.c (cmd_select_cur_row) : Make behavior match XL.
(cmd_select_cur_col) : Make behavior match XL.
* src/format.c (render_number) : avoid temporaries.
(do_render_number) : ditto.
2001-05-17 Jody Goldberg <jgoldberg@home.com>
* src/expr.c (eval_range) : delete.
(eval_expr_real) : Use workbook_foreach_cell_in_range rather than
range_eval. Remove 'generation' mechanism.
(cb_range_eval) : a simple pass through
* src/eval.c (sheet_region_recalc_deps) : rename from
sheet_recalc_dependencies and merge in sheet_region_get_deps.
Use the new foreach style interfaces.
(cb_single_recalc_all_depends) : rename from cb_single_get_all_depends
and simplify.
(cb_range_recalc_all_depends) : rename from cb_sheet_get_all_depends and simplify.
(cb_dependent_queue_recalc) : new wrapper.
(cb_region_contained_depend) : renamed from search_range_deps and simplify.
(cell_foreach_dep) : rename from cell_get_dependencies and switch to
an in place api rather than creating a list.
(cell_foreach_single_dep) : switch to in place api
(cell_foreach_range_dep) : ditto.
(search_cell_deps) : ditto.
(cell_recalc_deps) : ditto.
(cell_eval) : ditto.
(cb_generation_queue) : new utility.
* src/dependent.c (dependent_list_filter) : delete.
* src/cmd-edit.c (cb_collect_deps) : new function split from.
(cmd_select_cur_depends) : here. So that we can use the new depend
api.
* src/sheet.c (sheet_move_range) : use sheet_region_recalc_deps.
(sheet_{insert,delete}_{cols,rows}) : ditto.
(sheet_cell_remove_simple) : Use in place depend interface.
* src/cell.c (cell_content_changed) : Use in place depend interface.
* src/clipboard.c (clipboard_paste_region) : ditto.
* src/commands.c (cmd_area_set_text_redo) : ditto.
(cmd_autofill_redo) : ditto.
2001-05-21 Jody Goldberg <jgoldberg@home.com>
* Makefile.am : remove gnorba and modernize a bit.
2001-05-23 Zbigniew Chyla <cyba@gnome.pl>
* src/plugin-service.c
......
......@@ -5,6 +5,10 @@ Almer:
Jody:
* Fix ctrl-enter filling.
* Reorganize the recalc queue
Zbigniew:
* More work on plugin system.
--------------------------------------------------------------------------
Gnumeric 0.65
......
2001-05-22 Jody Goldberg <jgoldberg@home.com>
* gnumeric.spec.in : bump version of libole2
* README : ditto.
* configure.in : ditto.
2001-05-19 Jody Goldberg <jgoldberg@home.com>
* src/workbook.c (workbook_is_pristine) : no need to check the recalc
queue. If there are no dependents there is nothing to put on the
eval queue.
* src/func.c (cb_iterate_cellrange) : rename from
iterate_cellrange_callback remove 'generation' mechanism.
* src/cell.c (cell_cleanout) : Clear both recalc flags,
in_queue and needs
(cell_copy) : ditto.
(cell_eval_content) : No need to render the value. assign_value
already does it.
(cell_content_changed) : deleted.
* src/Makefile.am : merge dependent.[ch] into eval.[ch]
2001-05-18 Jody Goldberg <jgoldberg@home.com>
* src/eval.c : reorg and merged with dependent.[ch]
* src/sheet.c (sheet_cell_set_text) :
s/cell_content_changed/cell_queue_recalc/
(sheet_cell_set_expr) : ditto.
(sheet_cell_set_value) : ditto.
(colrow_move) : ditto.
(sheet_destroy_contents) :
s/dependent_unqueue_recalc_sheet/dependent_unqueue_sheet/
* src/cmd-edit.c (cmd_select_cur_row) : Make behavior match XL.
(cmd_select_cur_col) : Make behavior match XL.
* src/format.c (render_number) : avoid temporaries.
(do_render_number) : ditto.
2001-05-17 Jody Goldberg <jgoldberg@home.com>
* src/expr.c (eval_range) : delete.
(eval_expr_real) : Use workbook_foreach_cell_in_range rather than
range_eval. Remove 'generation' mechanism.
(cb_range_eval) : a simple pass through
* src/eval.c (sheet_region_recalc_deps) : rename from
sheet_recalc_dependencies and merge in sheet_region_get_deps.
Use the new foreach style interfaces.
(cb_single_recalc_all_depends) : rename from cb_single_get_all_depends
and simplify.
(cb_range_recalc_all_depends) : rename from cb_sheet_get_all_depends and simplify.
(cb_dependent_queue_recalc) : new wrapper.
(cb_region_contained_depend) : renamed from search_range_deps and simplify.
(cell_foreach_dep) : rename from cell_get_dependencies and switch to
an in place api rather than creating a list.
(cell_foreach_single_dep) : switch to in place api
(cell_foreach_range_dep) : ditto.
(search_cell_deps) : ditto.
(cell_recalc_deps) : ditto.
(cell_eval) : ditto.
(cb_generation_queue) : new utility.
* src/dependent.c (dependent_list_filter) : delete.
* src/cmd-edit.c (cb_collect_deps) : new function split from.
(cmd_select_cur_depends) : here. So that we can use the new depend
api.
* src/sheet.c (sheet_move_range) : use sheet_region_recalc_deps.
(sheet_{insert,delete}_{cols,rows}) : ditto.
(sheet_cell_remove_simple) : Use in place depend interface.
* src/cell.c (cell_content_changed) : Use in place depend interface.
* src/clipboard.c (clipboard_paste_region) : ditto.
* src/commands.c (cmd_area_set_text_redo) : ditto.
(cmd_autofill_redo) : ditto.
2001-05-21 Jody Goldberg <jgoldberg@home.com>
* Makefile.am : remove gnorba and modernize a bit.
2001-05-23 Zbigniew Chyla <cyba@gnome.pl>
* src/plugin-service.c
......
2001-05-22 Jody Goldberg <jgoldberg@home.com>
* gnumeric.spec.in : bump version of libole2
* README : ditto.
* configure.in : ditto.
2001-05-19 Jody Goldberg <jgoldberg@home.com>
* src/workbook.c (workbook_is_pristine) : no need to check the recalc
queue. If there are no dependents there is nothing to put on the
eval queue.
* src/func.c (cb_iterate_cellrange) : rename from
iterate_cellrange_callback remove 'generation' mechanism.
* src/cell.c (cell_cleanout) : Clear both recalc flags,
in_queue and needs
(cell_copy) : ditto.
(cell_eval_content) : No need to render the value. assign_value
already does it.
(cell_content_changed) : deleted.
* src/Makefile.am : merge dependent.[ch] into eval.[ch]
2001-05-18 Jody Goldberg <jgoldberg@home.com>
* src/eval.c : reorg and merged with dependent.[ch]
* src/sheet.c (sheet_cell_set_text) :
s/cell_content_changed/cell_queue_recalc/
(sheet_cell_set_expr) : ditto.
(sheet_cell_set_value) : ditto.
(colrow_move) : ditto.
(sheet_destroy_contents) :
s/dependent_unqueue_recalc_sheet/dependent_unqueue_sheet/
* src/cmd-edit.c (cmd_select_cur_row) : Make behavior match XL.
(cmd_select_cur_col) : Make behavior match XL.
* src/format.c (render_number) : avoid temporaries.
(do_render_number) : ditto.
2001-05-17 Jody Goldberg <jgoldberg@home.com>
* src/expr.c (eval_range) : delete.
(eval_expr_real) : Use workbook_foreach_cell_in_range rather than
range_eval. Remove 'generation' mechanism.
(cb_range_eval) : a simple pass through
* src/eval.c (sheet_region_recalc_deps) : rename from
sheet_recalc_dependencies and merge in sheet_region_get_deps.
Use the new foreach style interfaces.
(cb_single_recalc_all_depends) : rename from cb_single_get_all_depends
and simplify.
(cb_range_recalc_all_depends) : rename from cb_sheet_get_all_depends and simplify.
(cb_dependent_queue_recalc) : new wrapper.
(cb_region_contained_depend) : renamed from search_range_deps and simplify.
(cell_foreach_dep) : rename from cell_get_dependencies and switch to
an in place api rather than creating a list.
(cell_foreach_single_dep) : switch to in place api
(cell_foreach_range_dep) : ditto.
(search_cell_deps) : ditto.
(cell_recalc_deps) : ditto.
(cell_eval) : ditto.
(cb_generation_queue) : new utility.
* src/dependent.c (dependent_list_filter) : delete.
* src/cmd-edit.c (cb_collect_deps) : new function split from.
(cmd_select_cur_depends) : here. So that we can use the new depend
api.
* src/sheet.c (sheet_move_range) : use sheet_region_recalc_deps.
(sheet_{insert,delete}_{cols,rows}) : ditto.
(sheet_cell_remove_simple) : Use in place depend interface.
* src/cell.c (cell_content_changed) : Use in place depend interface.
* src/clipboard.c (clipboard_paste_region) : ditto.
* src/commands.c (cmd_area_set_text_redo) : ditto.
(cmd_autofill_redo) : ditto.
2001-05-21 Jody Goldberg <jgoldberg@home.com>
* Makefile.am : remove gnorba and modernize a bit.
2001-05-23 Zbigniew Chyla <cyba@gnome.pl>
* src/plugin-service.c
......
2001-05-22 Jody Goldberg <jgoldberg@home.com>
* gnumeric.spec.in : bump version of libole2
* README : ditto.
* configure.in : ditto.
2001-05-19 Jody Goldberg <jgoldberg@home.com>
* src/workbook.c (workbook_is_pristine) : no need to check the recalc
queue. If there are no dependents there is nothing to put on the
eval queue.
* src/func.c (cb_iterate_cellrange) : rename from
iterate_cellrange_callback remove 'generation' mechanism.
* src/cell.c (cell_cleanout) : Clear both recalc flags,
in_queue and needs
(cell_copy) : ditto.
(cell_eval_content) : No need to render the value. assign_value
already does it.
(cell_content_changed) : deleted.
* src/Makefile.am : merge dependent.[ch] into eval.[ch]
2001-05-18 Jody Goldberg <jgoldberg@home.com>
* src/eval.c : reorg and merged with dependent.[ch]
* src/sheet.c (sheet_cell_set_text) :
s/cell_content_changed/cell_queue_recalc/
(sheet_cell_set_expr) : ditto.
(sheet_cell_set_value) : ditto.
(colrow_move) : ditto.
(sheet_destroy_contents) :
s/dependent_unqueue_recalc_sheet/dependent_unqueue_sheet/
* src/cmd-edit.c (cmd_select_cur_row) : Make behavior match XL.
(cmd_select_cur_col) : Make behavior match XL.
* src/format.c (render_number) : avoid temporaries.
(do_render_number) : ditto.
2001-05-17 Jody Goldberg <jgoldberg@home.com>
* src/expr.c (eval_range) : delete.
(eval_expr_real) : Use workbook_foreach_cell_in_range rather than
range_eval. Remove 'generation' mechanism.
(cb_range_eval) : a simple pass through
* src/eval.c (sheet_region_recalc_deps) : rename from
sheet_recalc_dependencies and merge in sheet_region_get_deps.
Use the new foreach style interfaces.
(cb_single_recalc_all_depends) : rename from cb_single_get_all_depends
and simplify.
(cb_range_recalc_all_depends) : rename from cb_sheet_get_all_depends and simplify.
(cb_dependent_queue_recalc) : new wrapper.
(cb_region_contained_depend) : renamed from search_range_deps and simplify.
(cell_foreach_dep) : rename from cell_get_dependencies and switch to
an in place api rather than creating a list.
(cell_foreach_single_dep) : switch to in place api
(cell_foreach_range_dep) : ditto.
(search_cell_deps) : ditto.
(cell_recalc_deps) : ditto.
(cell_eval) : ditto.
(cb_generation_queue) : new utility.
* src/dependent.c (dependent_list_filter) : delete.
* src/cmd-edit.c (cb_collect_deps) : new function split from.
(cmd_select_cur_depends) : here. So that we can use the new depend
api.
* src/sheet.c (sheet_move_range) : use sheet_region_recalc_deps.
(sheet_{insert,delete}_{cols,rows}) : ditto.
(sheet_cell_remove_simple) : Use in place depend interface.
* src/cell.c (cell_content_changed) : Use in place depend interface.
* src/clipboard.c (clipboard_paste_region) : ditto.
* src/commands.c (cmd_area_set_text_redo) : ditto.
(cmd_autofill_redo) : ditto.
2001-05-21 Jody Goldberg <jgoldberg@home.com>
* Makefile.am : remove gnorba and modernize a bit.
2001-05-23 Zbigniew Chyla <cyba@gnome.pl>
* src/plugin-service.c
......
2001-05-22 Jody Goldberg <jgoldberg@home.com>
* gnumeric.spec.in : bump version of libole2
* README : ditto.
* configure.in : ditto.
2001-05-19 Jody Goldberg <jgoldberg@home.com>
* src/workbook.c (workbook_is_pristine) : no need to check the recalc
queue. If there are no dependents there is nothing to put on the
eval queue.
* src/func.c (cb_iterate_cellrange) : rename from
iterate_cellrange_callback remove 'generation' mechanism.
* src/cell.c (cell_cleanout) : Clear both recalc flags,
in_queue and needs
(cell_copy) : ditto.
(cell_eval_content) : No need to render the value. assign_value
already does it.
(cell_content_changed) : deleted.
* src/Makefile.am : merge dependent.[ch] into eval.[ch]
2001-05-18 Jody Goldberg <jgoldberg@home.com>
* src/eval.c : reorg and merged with dependent.[ch]
* src/sheet.c (sheet_cell_set_text) :
s/cell_content_changed/cell_queue_recalc/
(sheet_cell_set_expr) : ditto.
(sheet_cell_set_value) : ditto.
(colrow_move) : ditto.
(sheet_destroy_contents) :
s/dependent_unqueue_recalc_sheet/dependent_unqueue_sheet/
* src/cmd-edit.c (cmd_select_cur_row) : Make behavior match XL.
(cmd_select_cur_col) : Make behavior match XL.
* src/format.c (render_number) : avoid temporaries.
(do_render_number) : ditto.
2001-05-17 Jody Goldberg <jgoldberg@home.com>
* src/expr.c (eval_range) : delete.
(eval_expr_real) : Use workbook_foreach_cell_in_range rather than
range_eval. Remove 'generation' mechanism.
(cb_range_eval) : a simple pass through
* src/eval.c (sheet_region_recalc_deps) : rename from
sheet_recalc_dependencies and merge in sheet_region_get_deps.
Use the new foreach style interfaces.
(cb_single_recalc_all_depends) : rename from cb_single_get_all_depends
and simplify.
(cb_range_recalc_all_depends) : rename from cb_sheet_get_all_depends and simplify.
(cb_dependent_queue_recalc) : new wrapper.
(cb_region_contained_depend) : renamed from search_range_deps and simplify.
(cell_foreach_dep) : rename from cell_get_dependencies and switch to
an in place api rather than creating a list.
(cell_foreach_single_dep) : switch to in place api
(cell_foreach_range_dep) : ditto.
(search_cell_deps) : ditto.
(cell_recalc_deps) : ditto.
(cell_eval) : ditto.
(cb_generation_queue) : new utility.
* src/dependent.c (dependent_list_filter) : delete.
* src/cmd-edit.c (cb_collect_deps) : new function split from.
(cmd_select_cur_depends) : here. So that we can use the new depend
api.
* src/sheet.c (sheet_move_range) : use sheet_region_recalc_deps.
(sheet_{insert,delete}_{cols,rows}) : ditto.
(sheet_cell_remove_simple) : Use in place depend interface.
* src/cell.c (cell_content_changed) : Use in place depend interface.
* src/clipboard.c (clipboard_paste_region) : ditto.
* src/commands.c (cmd_area_set_text_redo) : ditto.
(cmd_autofill_redo) : ditto.
2001-05-21 Jody Goldberg <jgoldberg@home.com>
* Makefile.am : remove gnorba and modernize a bit.
2001-05-23 Zbigniew Chyla <cyba@gnome.pl>
* src/plugin-service.c
......
A discussion of the new dependency code, version 0.1
A discussion of the new dependency code, version 0.2
by Michael Meeks <mmeeks@gnu.org>
The dependency code is a comparatively conceptualy simple part of the gnumeric
code. The code is designed to determine which cells depend on the cell of
interest. The main use of this is in triggering recomputation of cells which
depend on a cell that has just changed.
code. The code is designed to determine which objects depend on which cells.
The main use of this is triggering recomputation for things that depend on
something that has changed.
1. Overview of the Dependencies
......@@ -25,12 +24,10 @@ range references. The two hash tables store DependencyRange structures in the
'range_hash' member, and DependencySingle structures in the 'single_hash'
member.
The DependencyRange structure defines a range reference. This essential
lists the Cells ( not neccessarily in this sheet ), that depend on the range
specified. Hence to find the cells that depend on a cell you have just altered
you must search all the range structures in the range_hash for that sheet. This
is very important; to re-phrase dependancies are stored in an Area -> list of
depending cells fashion.
The DependencyRange structure defines a range reference. This lists the
Dependencies ( not neccessarily in this sheet ), that depend on the range
specified. Hence to find the cells that depend on a cell you have just altered
you must search all the range structures in the range_hash for that sheet.
The DependencySingle structure mapping stores the degenerate case of
a DependencyRange. Essentialy it stores the cells that depend on a unit range.
......@@ -39,21 +36,12 @@ the Range hash, all of which has to be traversed per dependency calculation.
NB. the DependencySingle has to use CellPos' since there is no garentee that
a cell will exist at a given position in the sheet that is depended on.
1.2 The generation gap
In order to ensure that there are no circular dependencies that will
create a recursive loop locking gnumeric there is a generation counter on
each cell. There is a generation count per workbook which is incremented on
recalculate. When a cell is re-calculated its generation is set to be the
workbook's generation count. A cell will only be re-evaluated if its generation
is not the current generation.
2. Dependent Evaluation
The routine dependent_eval will evaluate a dependent and if its value
changes it will queue cells that depend on it, these are obtained via
cell_get_dependencies, which looks up in the single_hash and tranverses the
cell_forech_dep, which looks up in the single_hash and tranverses the
range_hash to obtain its result. Often cell recalculation happens through
workbook_recalc which works through the workbook's eval_queue re-evaluating
the cells there.
......@@ -64,18 +52,9 @@ the cells there.
simply traversing the ExprTree (expr.h) will result in many cells being
evaluated. Essentialy each dereference in the ExprTree ( eg. =A1 ) will cause
the re-calculation of A1's ExprTree before we can continue ( recursively ).
After the root ExprTree has been evaluated the value is set on the Cell and
the dependencies of this cell are queued on the workbook's eval_queue.
2.2 Short circuiting dependencies
Clearly, if after evaluating a cell's ExprTree we generate an identical
Value (value.h) we can prune a huge chunk off the dependency tree by not
bothering notifying dependencies of a change ( since there hasn't been one ).
Hence cell_eval_content returns a gboolean indicating whether the cell's
value has changed. (Ok, so this feature was dropped before the code went
live, since a few other changes were needed to support it, but there is room
for performance improvement here ).
This is actually fairly expensive when the expression contains a reference like
=sum(a1:a65535)
Each dependent can be in two states
3. Dependencies the bottleneck
......@@ -99,7 +78,7 @@ time in search_cell_deps.
To overcome this problem we partition dependencies into single cell
dependencies and range dependencies. This way for the common =A1 case, we don't
add an entry in the range_hash, we simply add an entry in the simple_hash.
Hence for the cell_get_dependencies we have one less entry in the range hash to
Hence for the cell_forech_dep we have one less entry in the range hash to
iterate over, which saves N iterations of search_cell_deps.
Another common case is having a lot of formulae sharing the same range
......@@ -180,7 +159,7 @@ references a different cell, hence the dependency has to be treated rather
differently. This is yet to be implemented.
5. Future Expansion
5.1 Future Expansion
There are several avenues open for future expansion. Clearly further
accelerating the range search will give big speedups on large sheets. This
......@@ -189,15 +168,6 @@ ranges homing in on the cell of interest, and storing the results for future
reference. Clearly many of the MStyle range related optimizations would be
useful here as well.
5.1 Pruning the tree
It should be trivial to chop huge chunks of the dependency tree out
if we find that the value we have generated is identical to that which we
already had. This is currently implemented, but commented out, since
dependencies need to be recalculated on move / cut / paste etc. and in this
case the value does not change. Simply NULL'ing cell->value in cell_relocate
might fix this.
5.2 Multi-threading,
With the current structure, it might well be possible to add multi-
......
A discussion of the new dependency code, version 0.1
A discussion of the new dependency code, version 0.2
by Michael Meeks <mmeeks@gnu.org>
The dependency code is a comparatively conceptualy simple part of the gnumeric
code. The code is designed to determine which cells depend on the cell of
interest. The main use of this is in triggering recomputation of cells which
depend on a cell that has just changed.
code. The code is designed to determine which objects depend on which cells.
The main use of this is triggering recomputation for things that depend on
something that has changed.
1. Overview of the Dependencies
......@@ -25,12 +24,10 @@ range references. The two hash tables store DependencyRange structures in the
'range_hash' member, and DependencySingle structures in the 'single_hash'
member.
The DependencyRange structure defines a range reference. This essential
lists the Cells ( not neccessarily in this sheet ), that depend on the range
specified. Hence to find the cells that depend on a cell you have just altered
you must search all the range structures in the range_hash for that sheet. This
is very important; to re-phrase dependancies are stored in an Area -> list of
depending cells fashion.
The DependencyRange structure defines a range reference. This lists the
Dependencies ( not neccessarily in this sheet ), that depend on the range
specified. Hence to find the cells that depend on a cell you have just altered
you must search all the range structures in the range_hash for that sheet.
The DependencySingle structure mapping stores the degenerate case of
a DependencyRange. Essentialy it stores the cells that depend on a unit range.
......@@ -39,21 +36,12 @@ the Range hash, all of which has to be traversed per dependency calculation.
NB. the DependencySingle has to use CellPos' since there is no garentee that
a cell will exist at a given position in the sheet that is depended on.
1.2 The generation gap
In order to ensure that there are no circular dependencies that will
create a recursive loop locking gnumeric there is a generation counter on
each cell. There is a generation count per workbook which is incremented on
recalculate. When a cell is re-calculated its generation is set to be the
workbook's generation count. A cell will only be re-evaluated if its generation
is not the current generation.
2. Dependent Evaluation
The routine dependent_eval will evaluate a dependent and if its value
changes it will queue cells that depend on it, these are obtained via
cell_get_dependencies, which looks up in the single_hash and tranverses the
cell_forech_dep, which looks up in the single_hash and tranverses the
range_hash to obtain its result. Often cell recalculation happens through
workbook_recalc which works through the workbook's eval_queue re-evaluating
the cells there.
......@@ -64,18 +52,9 @@ the cells there.
simply traversing the ExprTree (expr.h) will result in many cells being
evaluated. Essentialy each dereference in the ExprTree ( eg. =A1 ) will cause
the re-calculation of A1's ExprTree before we can continue ( recursively ).
After the root ExprTree has been evaluated the value is set on the Cell and
the dependencies of this cell are queued on the workbook's eval_queue.
2.2 Short circuiting dependencies
Clearly, if after evaluating a cell's ExprTree we generate an identical
Value (value.h) we can prune a huge chunk off the dependency tree by not
bothering notifying dependencies of a change ( since there hasn't been one ).
Hence cell_eval_content returns a gboolean indicating whether the cell's
value has changed. (Ok, so this feature was dropped before the code went
live, since a few other changes were needed to support it, but there is room
for performance improvement here ).
This is actually fairly expensive when the expression contains a reference like
=sum(a1:a65535)
Each dependent can be in two states
3. Dependencies the bottleneck
......@@ -99,7 +78,7 @@ time in search_cell_deps.
To overcome this problem we partition dependencies into single cell
dependencies and range dependencies. This way for the common =A1 case, we don't
add an entry in the range_hash, we simply add an entry in the simple_hash.
Hence for the cell_get_dependencies we have one less entry in the range hash to
Hence for the cell_forech_dep we have one less entry in the range hash to
iterate over, which saves N iterations of search_cell_deps.
Another common case is having a lot of formulae sharing the same range
......@@ -180,7 +159,7 @@ references a different cell, hence the dependency has to be treated rather
differently. This is yet to be implemented.
5. Future Expansion
5.1 Future Expansion
There are several avenues open for future expansion. Clearly further
accelerating the range search will give big speedups on large sheets. This
......@@ -189,15 +168,6 @@ ranges homing in on the cell of interest, and storing the results for future
reference. Clearly many of the MStyle range related optimizations would be
useful here as well.
5.1 Pruning the tree
It should be trivial to chop huge chunks of the dependency tree out
if we find that the value we have generated is identical to that which we
already had. This is currently implemented, but commented out, since
dependencies need to be recalculated on move / cut / paste etc. and in this
case the value does not change. Simply NULL'ing cell->value in cell_relocate
might fix this.
5.2 Multi-threading,
With the current structure, it might well be possible to add multi-
......
2001-05-18 Jody Goldberg <jgoldberg@home.com>
* ms-excel-read.c (ms_excel_read_formula) : Use cell_queue_recalc
to get appropriate recursion.
2001-05-17 Jody Goldberg <jgoldberg@home.com>
* ms-excel-read.c (ms_excel_formula_shared) : Use a g_warning not a
printf.
2001-05-21 Zbigniew Chyla <cyba@gnome.pl>
* boot.c (excel_file_probe, excel_file_open, excel97_file_save,
......
......@@ -1376,7 +1376,7 @@ ms_excel_get_style_from_xf (ExcelSheet *sheet, guint16 xfidx)
static void
ms_excel_set_xf (ExcelSheet *sheet, int col, int row, guint16 xfidx)
{
MStyle *const mstyle = ms_excel_get_style_from_xf (sheet, xfidx);
MStyle *const mstyle = ms_excel_get_style_from_xf (sheet, xfidx);
if (mstyle == NULL)
return;
......@@ -1861,8 +1861,8 @@ ms_excel_formula_shared (BiffQuery *q, ExcelSheet *sheet, Cell *cell)
return expr;
}
printf ("EXCEL : unexpected record after a formula 0x%x in '%s'\n",
q->opcode, cell_name (cell));
g_warning ("EXCEL : unexpected record after a formula 0x%x in '%s'\n",
q->opcode, cell_name (cell));
return NULL;
}
......@@ -2061,7 +2061,7 @@ ms_excel_read_formula (BiffQuery *q, ExcelSheet *sheet)
* 0x2 = CalcOnLoad
*/
if (options & 0x3)
dependent_queue_recalc (CELL_TO_DEP (cell));
cell_queue_recalc (cell);
}
BiffSharedFormula *
......
......@@ -82,8 +82,6 @@ GNUMERIC_BASE_SOURCES = \
dates.h \
datetime.c \
datetime.h \
dependent.c \
dependent.h \
error-info.c \
error-info.h \
eval.h \
......
......@@ -79,7 +79,7 @@ cell_cleanout (Cell *cell)
cell->format = NULL;
}
cell->base.flags &= ~(CELL_HAS_EXPRESSION|DEPENDENT_QUEUED_FOR_RECALC);
cell->base.flags &= ~(CELL_HAS_EXPRESSION|DEPENDENT_IN_RECALC_QUEUE|DEPENDENT_NEEDS_RECALC);
}
/**
......@@ -104,7 +104,7 @@ cell_copy (Cell const *cell)
/* The new cell is not linked into any of the major management structures */
new_cell->base.sheet = NULL;
new_cell->base.flags &= ~(DEPENDENT_QUEUED_FOR_RECALC|CELL_IN_SHEET_LIST|DEPENDENT_IN_EXPR_LIST);
new_cell->base.flags &= ~(DEPENDENT_IN_RECALC_QUEUE|DEPENDENT_NEEDS_RECALC|CELL_IN_SHEET_LIST|DEPENDENT_IN_EXPR_LIST);
/* now copy properly the rest */
if (cell_has_expr (new_cell))
......@@ -183,29 +183,9 @@ cell_eval_content (Cell *cell)
v = value_new_error (&pos, "Internal error");
cell_assign_value (cell, v, NULL);
/* TODO : Can we Use spancalc without too much performance overhead
* Seems like a better approach may be to do this at display time */
cell_render_value (cell, TRUE);
sheet_redraw_cell (cell);
}
/**
* cell_content_changed: Queues recalc of all of the cells depends.
*/
void
cell_content_changed (Cell *cell)
{
GList *deps;
g_return_if_fail (cell != NULL);
/* Queue all of the dependencies for this cell */
deps = cell_get_dependencies (cell);
if (deps)