problems updating root file

From: Eddy Offermann (eddy@rentec.com)
Date: Fri Oct 02 1998 - 03:18:59 MEST


Dear Rooters,

I have a problem when adding data to a tree and NOT performing a purge. After
the 10'th time I can not read the tree anymore and get the message:

Fatal in <operator new>: storage exhausted
aborting

I have tried to make a compact example. It consists out of:

1) sharable library libMylib.so which is made through
   makefile, myClass.h and myClass.C

------------------------
makefile: 
------------------------

ROOTLIBS      = -L$(ROOTSYS)/lib -lNew -lBase -lCint -lClib -lCont -lFunc \
                -lGraf -lGraf3d -lHist -lHtml -lMatrix -lMeta -lMinuit -lNet \
                -lPostscript -lProof -lTree -lUnix -lZip
ROOTGLIBS     = -lGpad -lGui -lGX11 -lX3d
 
# Solaris
CXX           = CC
CXXFLAGS      = -g -KPIC -I./ -I$(ROOTSYS)/include
LD            = CC
LDFLAGS       = -g
SOFLAGS       = -G
LIBS          = $(ROOTLIBS) -lm -lsocket -lgen -L/opt/SUNWspro/lib -lsunmath
 
.C.o:
		$(CXX) $(CXXFLAGS) -c $<
all:            libMylib.so
clean:
	rm -f $(OBJS) *~ myClassDict.? myClassFile.? core

libMylib.so: myClass.o myClassDict.o
	$(LD) $(SOFLAGS) $(LDFLAGS) myClass.o myClassDict.o -o libMylib.so

myClass.o: myClass.h
myClassDict.C: myClass.h
	@rootcint -f myClassDict.C -c myClass.h


------------------------
myClass.h:
------------------------

#ifndef ROOT_MYCLASS
#define ROOT_MYCLASS

#include "TTree.h"
#include "TObject.h"
#include <unistd.h>
#include <assert.h>
#include <iostream.h>
  

class myClass : public TObject {
public:
  Float_t a;
  Float_t b;
  Int_t   seqNumber;
  
  myClass();
  ~myClass();
  void dump();
    
  ClassDef(myClass,1)
};

#endif

------------------------
myClass.C:
------------------------

#include <myClass.h>

ClassImp(myClass)

myClass::myClass()
{
}

myClass::~myClass()
{
}

void myClass::dump()
{
  printf("%i %.2f %.2f\n",seqNumber,a,b);
}


2) the macro code.C

------------------------
code.C:
------------------------

make(Char_t filename[], Int_t new=0, Int_t nrEntries=100000)
{
  TFile *hfile;
  TTree *tree;
  myClass *var = new myClass;

  printf("----\nmake\n----\n");
  if (new)
  {
    printf("creating file %s\n",filename);
    hfile = new TFile(filename,"CREATE");
    tree = new TTree("tree","tree");
    Int_t split = 1;
    Int_t bsize = 64000;
    TBranch *branch = tree->Branch("ticks","myClass",&var,bsize,split);
  }
  else
  {
    printf("opening file %s\n",filename);
    hfile = new TFile(filename,"UPDATE");
    tree = (TTree*) hfile->Get("tree");
    tree->SetBranchAddress("ticks",&var);
  }
  
  for (Int_t i = 0; i < nrEntries; i++)
  {
    var->seqNumber = i;
    tree->Fill();
  }
  printf("added %d entries to %s\n",nrEntries,filename);

//  hfile->Purge(1);
  hfile->Write();
  hfile->ls();
  hfile->Close();
}

read(Char_t filename[])
{
  printf("----\nread\n----\n");
  TFile *hfile = new TFile(filename,"READ");
  if (hfile == NULL)
  {
    printf("Can not open the root file\n");
    exit(1);
  }
  
  myClass *var = new myClass;
  TTree *tree = (TTree*) hfile->Get("tree");
  if (tree == NULL)
  {
    printf("Can not find tree\n");
    exit(1);
  }
  tree->SetBranchAddress("ticks", &var);
  
  Int_t nrEntries = tree->GetEntries();
  Int_t step = nrEntries/10;
  printf("nrEntries : %d\n", nrEntries);
  for (Int_t i = 0; i < nrEntries; i++)
  {
    tree->GetEvent(i);
    if (i%step == 0)
    {
      printf("%d : ",i);
      var->dump();
    }
  }

  hfile->Close();
  delete hfile;
}

3) the macro doit.C

------------------------
doit.C:
------------------------

{
  system("rm -f test.root");
  for (Int_t i = 0; i < 11; i++)
  {
    Int_t new = (i == 0) ? 1 : 0;
    make("test.root",new,10000);
    read("test.root");
  }
}


After making the 'libMylib.so' , I give the following commands in
root (2.00/11):

root [0] gSystem->Load("libMylib.so")
(int)0
root [1] .L code.C
root [2] .x doit.C

the ouput on the screen is:

----
make
----
creating file test.root                      <---- first time in loop
added 10000 entries to test.root
TFile Writing Name=test.root
----
read
----
nrEntries : 10000
0 : 0 0.00 0.00
1000 : 1000 0.00 0.00
2000 : 2000 0.00 0.00
3000 : 3000 0.00 0.00
4000 : 4000 0.00 0.00
5000 : 5000 0.00 0.00
6000 : 6000 0.00 0.00
7000 : 7000 0.00 0.00
8000 : 8000 0.00 0.00
9000 : 9000 0.00 0.00
----
make
----
opening file test.root                      <---- 2nd time in loop
added 10000 entries to test.root
TFile Writing Name=test.root
TFile**         test.root
 TFile*         test.root
  OBJ: TTree    tree    tree : 0
  KEY: TTree    tree;1  tree
TFile Writing Name=test.root
----
read
  .
  .
  .
  .
  .
  .
  .
  .
  .
----
make
----
opening file test.root                    <----- 10th time in loop
added 10000 entries to test.root
TFile Writing Name=test.root
TFile**         test.root
 TFile*         test.root
  OBJ: TTree    tree    tree : 0
  KEY: TTree    tree;10 tree
  KEY: TTree    tree;9  tree
  KEY: TTree    tree;8  tree
  KEY: TTree    tree;7  tree
  KEY: TTree    tree;6  tree
  KEY: TTree    tree;5  tree
  KEY: TTree    tree;4  tree
  KEY: TTree    tree;3  tree
  KEY: TTree    tree;2  tree
  KEY: TTree    tree;1  tree
TFile Writing Name=test.root
----
read
----
nrEntries : 100000
0 : 0 0.00 0.00
10000 : 0 0.00 0.00
20000 : 0 0.00 0.00
30000 : 0 0.00 0.00
40000 : 0 0.00 0.00
Fatal in <operator new>: storage exhausted
aborting

When changing the number of entries per cycle from 10000 to 100000, the
problem remains but decreasing it to 1000 removes the problem. For 10000,
I have played with the buffersize and changed it from 64000 to 32000 and the
problem happend in cycle 17.

Keeping 10 cycles might sound unreasoable but my fear is that depending on
data/buff size it could happen after 1 or 2 cycles, that way losing the
data.

Any clue what I did wrong ??

Best regards,
Eddy Offermann



This archive was generated by hypermail 2b29 : Tue Jan 04 2000 - 00:34:38 MET